Ansible SSH转发似乎无法与Vagrant一起使用

25

好的,问题有点奇怪。我已经在 Vagrant 中启用了 SSH 转发功能。但是我尝试在使用 Ansible 作为 Vagrant provisioner 时使其工作。

我找出了 Ansible 正在执行的内容,并尝试从命令行自己执行,确实,在那里它也失败了。

[/common/picsolve-ansible/u12.04%]ssh -o HostName=127.0.0.1 \
 -o User=vagrant -o  Port=2222 -o UserKnownHostsFile=/dev/null \
 -o StrictHostKeyChecking=no -o PasswordAuthentication=no \
 -o IdentityFile=/Users/bryanhunt/.vagrant.d/insecure_private_key \
 -o IdentitiesOnly=yes -o LogLevel=FATAL \
 -o ForwardAgent=yes "/bin/sh  \
 -c 'git clone git@bitbucket.org:bryan_picsolve/poc_docker.git /home/vagrant/poc_docker' "
Permission denied (publickey,password).

但是当我只运行vagrant ssh时,代理转发正常工作,并且我可以检出并读写我的github项目。

[/common/picsolve-ansible/u12.04%]vagrant ssh
vagrant@vagrant-ubuntu-precise-64:~$ /bin/sh  -c 'git clone git@bitbucket.org:bryan_picsolve/poc_docker.git /home/vagrant/poc_docker'
Cloning into '/home/vagrant/poc_docker'...
remote: Counting objects: 18, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 18 (delta 4), reused 0 (delta 0)
Receiving objects: 100% (18/18), done.
Resolving deltas: 100% (4/4), done.
vagrant@vagrant-ubuntu-precise-64:~$

有人知道这是怎么运作的吗?

更新:

通过 ps awux 命令,我确定了 Vagrant 正在执行的确切命令。

我复制了它,然后 git checkout 就能工作了。

 ssh vagrant@127.0.0.1 -p 2222 \
  -o Compression=yes \
  -o StrictHostKeyChecking=no \
  -o LogLevel=FATAL \ 
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  -o IdentitiesOnly=yes \
  -i /Users/bryanhunt/.vagrant.d/insecure_private_key \
  -o ForwardAgent=yes \
  -o LogLevel=DEBUG \
   "/bin/sh  -c 'git clone git@bitbucket.org:bryan_picsolve/poc_docker.git /home/vagrant/poc_docker' "

你是否查看了相关问题 https://dev59.com/Gmct5IYBdhLWcg3wnuvg?rq=1 和 http://stackoverflow.com/questions/12923675/how-to-setup-vagrant-ssh-agent-forwarding?lq=1? - Vilsepi
我看了一下,但他们没有直接解决我的问题。我已经找出了问题所在。现在我会发布解决方案。 - binarytemple_picsolve
6个回答

21

从ansible 1.5(devel aa2d6e47f0),更新于2014/03/24 14:23:18(GMT +100)以及Vagrant 1.5.1版本开始,现在可以正常工作。

我的Vagrant配置包含以下内容:

config.vm.provision "ansible" do |ansible|
   ansible.playbook = "../playbooks/basho_bench.yml"
   ansible.sudo = true
   ansible.host_key_checking = false
   ansible.verbose =  'vvvv'
   ansible.extra_vars = { ansible_ssh_user: 'vagrant', 
                 ansible_connection: 'ssh',
                 ansible_ssh_args: '-o ForwardAgent=yes'}

明确禁用sudo是一个好主意。例如,当使用Ansible git模块时,我会这样做:

- name: checkout basho_bench repository 
  sudo: no
  action: git repo=git@github.com:basho/basho_bench.git dest=basho_bench

根据我的经验,我相信你必须手动指定库存才能使其工作。如果我只让vagrant制作库存,它对我没有用。 - btobolaski
如果您销毁并重新创建您的Vagrant box,ssh-agent forwarding将会被静默禁用,除非您传递一个空的已知主机文件,这是根据Ben Darnell的回答:https://dev59.com/hmEi5IYBdhLWcg3wx-xs#23704069 - eager

16

关键的区别似乎在于UserKnownHostFile设置。即使StrictHostKeyChecking关闭,当已知主机文件中存在冲突条目时(这些冲突对于vagrant很常见,因为多个虚拟机可能在不同的时间具有相同的地址),ssh会悄悄地禁用某些功能,包括代理转发。 如果我将UserKnownHostFile指向/dev/null,则它对我有效:

config.vm.provision "ansible" do |ansible|
  ansible.playbook = "playbook.yml"

  ansible.raw_ssh_args = ['-o UserKnownHostsFile=/dev/null']
end

4
哇,这东西有多少种坏掉的方式啊,我之前让它起来了,但又坏了,按照你的建议做了一遍,现在好了。这东西非常必要但也非常脆弱,而且ssh命令本身也很脆弱,这个工具确实已经显得老态龙钟了。 - bryan_basho

8

以下是解决方法:

在和你的 Vagrantfile 相同的目录中创建一个名为 ansible.cfg 的文件,其中包含以下内容:

[ssh_connection]
ssh_args = -o ForwardAgent=yes

4
在不使用Vagrant时(我使用相同的配置),这在使用Ansible时有效,但是在使用Vagrant时不行(如果我没记错的话)。在我看来,在让这些东西工作方面所涉及的麻烦是这个绝妙工具中的一个弱点。 - bryan_basho
1
Ansible在配置过程中使用SSH,并将您的Vagrant虚拟机添加到~/.ssh/known_hosts。代理转发依赖于经过验证的主机密钥,因此在运行Ansible进行配置之前最好使用以下命令删除任何过时的密钥:ssh-keygen -R [127.0.0.1]:2222 - bbaassssiiee

3
您可以在Vagrantfile中添加以下代码来启用ssh转发功能:

您只需将此行添加到您的Vagrantfile中即可启用ssh转发:

config.ssh.forward_agent = true

注意:不要忘记使用become:false执行任务。

希望这能帮到你。


这是唯一对我有用的东西,即使我在ansible.cfg中设置了 ssh_args = -A(不要忘记使用 become: false 执行任务)。 - DevAntoine

2

我曾经为一个类似的问题苦苦挣扎了几个小时。

Vagrant 1.7.2

ansible 1.9.4

我的症状:

failed: [vagrant1] => {"cmd": "/usr/bin/git ls-remote '' -h refs/heads/HEAD", "failed": true, "rc": 128}
stderr: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

msg: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

FATAL: all hosts have already failed -- aborting

我通过SSH连接到虚拟机后发现,我的ssh-agent已经按照预期进行了转发:

vagrant@vagrant-ubuntu-trusty-64:~$ ssh -T git@github.com
Hi baxline! You've successfully authenticated, but GitHub does not provide shell access.

然而,从主机上,我无法打开连接:

$ ansible web -a "ssh-add -L"
vagrant1 | FAILED | rc=2 >>
Could not open a connection to your authentication agent.

确认我的ansible.cfg文件已经设置好,如@Lorin所指出的,以及我的Vagrantfile设置config.ssh.forward_agent = true后,我仍然无法成功。

解决方案是删除主机的~/.ssh/known_hosts文件中与我的guest相关的所有行。对于我来说,它们是以以下内容开头的行:

[127.0.0.1]:2201 ssh-rsa
[127.0.0.1]:2222 ssh-rsa
[127.0.01]:2222 ssh-rsa
[127.0.0.1]:2200 ssh-rsa

请注意第三行IP地址看起来有些不对劲。我不确定,但我认为那一行可能是罪魁祸首。这些行是在我销毁和创建Vagrant虚拟机时创建的。


有关主机机器(而非虚拟机)上 known_hosts 文件的顶级提示。这也是我的问题。 - stephendwolff

2

我发现在Ubuntu 12.04上,我需要分别进行两个操作才能让它正常工作:

  • the -o ForwardAgent thing that @Lorin mentions
  • adding /etc/sudoers.d/01-make_SSH_AUTH_SOCK_AVAILABLE with these contents:

    Defaults env_keep += "SSH_AUTH_SOCK"
    

我相当确定我已经尝试了两种方法。下周末,我会再次尝试最新的Ansible和你的建议。谢谢,Bryan。 - binarytemple_picsolve
1
@binarytemple_picsolve 小心ControlMaster!据我所知,它会保持你的SSH连接活动60秒,即使Vagrant已经停止。因此,如果你进行了影响ssh工作方式的更改,它不会生效,如果原始连接仍在运行。我建议你在调试时从ansible.cfg中删除ControlMaster和ControlPersist选项。 - offby1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接