SSH代理转发与Ansible

Bob*_*lay 64 git ssh ssh-agent ansible

我正在使用Ansible 1.5.3和Git与ssh代理转发(https://help.github.com/articles/using-ssh-agent-forwarding).我可以登录到我使用Ansible管理的服务器并测试我与git的连接是否正确配置:

ubuntu@test:~$ ssh -T git@github.com
Hi gituser! You've successfully authenticated, but GitHub does not provide shell access.
Run Code Online (Sandbox Code Playgroud)

我也可以使用这个帐户克隆和更新我的一个repos,这样我的git配置看起来不错,当我直接通过ssh登录我的服务器时使用ssh转发.

问题:当我使用Ansible命令模块尝试上面显示的相同测试时.它以"Permission denied"失败.Ansible输出的一部分(详细日志记录)如下所示:

failed: [xxx.xxxxx.com] => {"changed": true, "cmd": ["ssh", "-T", "git@github.com"], "delta": "0:00:00.585481", "end": "2014-06-09 14:11:37.410907", "rc": 255, "start": "2014-06-09 14:11:36.825426"}
stderr: Permission denied (publickey).
Run Code Online (Sandbox Code Playgroud)

这是运行此命令的简单playbook:

- hosts: webservers
  sudo: yes
  remote_user: ubuntu

  tasks:

  - name: Test that git ssh connection is working.
    command: ssh -T git@github.com
Run Code Online (Sandbox Code Playgroud)

问题:当我通过ssh手动登录并运行命令时,为什么一切正常,但是当同一个命令通过Ansible运行同一个命令时失败?

如果没有其他人打败我,我会很快发布答案.虽然我使用git来演示问题,但是任何依赖于ssh代理转发的模块都可能发生这种情况.它不是Ansible特有的,但我怀疑很多人会在这种情况下首先遇到问题.

Bob*_*lay 49

通过从剧本中删除此行来解决此问题:

sudo: yes
Run Code Online (Sandbox Code Playgroud)

在远程主机上运行sudo时,登录期间由ssh设置的环境变量不再可用.特别是,SSH_AUTH_SOCK,"标识用于与代理通信的UNIX域套接字的路径"不再可见,因此ssh代理转发不起作用.

在不需要sudo时避免使用sudo是解决问题的一种方法.另一种方法是通过创建sudoers文件来确保在sudo会话期间SSH_AUTH_SOCK保持不变:

/etc/sudoers:

     Defaults    env_keep += "SSH_AUTH_SOCK"
Run Code Online (Sandbox Code Playgroud)

  • 可能需要明确设置`sudo:no`. (4认同)
  • @SystematicFrank:您链接中的安全风险针对 chmod 777,而不是 SSH_AUTH_SOCK (3认同)
  • 如果您使用SSH_AUTH_SOCK,至少要注意安全风险http://serverfault.com/a/371788/67801 (2认同)

Tre*_*son 32

这里有一些非常有用的部分答案,但在多次遇到这个问题之后,我认为概述会有所帮助.

首先,从运行Ansible的客户端连接到目标计算机时,需要确保启用SSH代理转发.即使使用transport=smart,也可能无法自动启用SSH代理转发,具体取决于客户端的SSH配置.为了确保它,您可以更新您的内容~/.ansible.cfg以包括此部分:

[ssh_connection]
ssh_args=-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r -o ForwardAgent=yes
Run Code Online (Sandbox Code Playgroud)

接下来,您可能必须处理become: yes(和become_user: root)通常会禁用代理转发的事实,因为SSH_AUTH_SOCK环境变量已重置.(我觉得令人震惊的是,Ansible似乎认为人们将以root身份SSH,因为这使得任何有用的审计都不可能.)有几种方法可以解决这个问题.从Ansible 2.2开始,最简单的方法是在使用时sudo通过指定-E标志来保留(整个)环境:

become_flags: "-E"
Run Code Online (Sandbox Code Playgroud)

但是,这可能会通过保留变量等方式产生不必要的副作用PATH.最干净的方法是仅将SSH_AUTH_SOCK其包含env_keep在您的/etc/sudoers文件中:

Defaults    env_keep += "SSH_AUTH_SOCK"
Run Code Online (Sandbox Code Playgroud)

要使用Ansible执行此操作:

- name: enable SSH forwarding for sudo
  lineinfile:
    dest: /etc/sudoers
    insertafter: '^#?\s*Defaults\s+env_keep\b'
    line: 'Defaults    env_keep += "SSH_AUTH_SOCK"'
Run Code Online (Sandbox Code Playgroud)

此playbook任务比其他一些建议更保守,因为它在任何其他默认env_keep设置之后(或在文件末尾,如果没有找到)添加此任务,而不更改任何现有env_keep设置或假设SSH_AUTH_SOCK已存在.

  • Sudo 还允许通过标志仅保留某些环境变量。因此,`become_flags` ansible 设置中的`-E`可以替换为更具体的`--preserve-env=SSH_AUTH_SOCK`。这有助于减少保持整个环境的副作用。 (7认同)
  • @AlouaniYounes当我升级到Ansible 2.4时,它继续为我工作。 (2认同)

小智 26

您的问题的另一个答案(除了我使用Ansible 1.9)可能如下:

您可能需要检查/etc/ansible/ansible.cfg(或其他三个可以覆盖配置设置的可能位置),transport=smartansible docs中所建议的那样.transport=paramiko在上一次安装尝试期间,我的某些时候默认默认,导致我的控制机器无法使用OpenSSH,从而阻止了代理转发.这可能是一个巨大的边缘案例,但谁知道呢?可能是你!

虽然我没有发现我的配置是必要的,但我应该注意到其他人已经提到你应该-o ForwardAgent=yes在同一个文件中添加你的ssh_args设置,如下所示:

[ssh_connection]
ssh_args=-o ForwardAgent=yes
Run Code Online (Sandbox Code Playgroud)

为了完整起见,我在这里只提到它.

  • 如果指定`ssh_args`将阻止ansible提供自己的,包括设置持久连接的args.这可能导致**巨大的**减速.将添加的相关参数是`-o ControlMaster = auto -o ControlPersist = 60s -o ControlPath =/tmp/ansible-ssh-%h-%p-%r`. (6认同)
  • 我不得不将`ssh_args`添加到我的`ansible.cfg`以使SSH代理转发工作.感谢你成为唯一一个推荐它的人!我在OSX 10.10上运行Ansible 1.9.1 (3认同)
  • 有时“sudo_flags”也会出现问题,默认设置为“sudo_flags = -H -S -n”,并且可能会失败并显示“sudo:需要密码”。在这种情况下,您需要设置 `sudo_flags = -H -S` 删除 -n 选项。 (2认同)
  • 我不明白使用 `ssh_extra_args=-o ForwardAgent=yes` 可以防止速度变慢(由 qqx 提到)。 (2认同)

AJc*_*dez 17

为了扩展@j.freckle的答案,改变sudoers文件的安全方式是:

- name: Add ssh agent line to sudoers
  lineinfile: 
    dest: /etc/sudoers
    state: present
    regexp: SSH_AUTH_SOCK
    line: Defaults env_keep += "SSH_AUTH_SOCK"
Run Code Online (Sandbox Code Playgroud)

  • 但是我们不需要运行ansible两次吗?一个用于设置 ssh fwding,另一个用于实际获取与此环境变量集的连接? (2认同)