首页 文章

SSH代理转发与Ansible

提问于
浏览
60

我正在使用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.

我也可以使用这个帐户克隆和更新我的一个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).

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

- hosts: webservers
  sudo: yes
  remote_user: ubuntu

  tasks:

  - name: Test that git ssh connection is working.
    command: ssh -T git@github.com

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

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

4 回答

  • 27

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

    sudo: yes
    

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

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

    /etc/sudoers:
    
         Defaults    env_keep += "SSH_AUTH_SOCK"
    
  • 26

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

    首先,从运行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
    

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

    become_flags: "-E"
    

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

    Defaults    env_keep += "SSH_AUTH_SOCK"
    

    要使用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"'
    

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

  • 48

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

    对于 transport=smart ,您可能需要检查/etc/ansible/ansible.cfg(或可以覆盖配置设置的其他三个可能位置)in the ansible docs . 在上一次安装尝试期间,我的某个时刻默认为 transport=paramiko ,这阻止了我的控制机器使用OpenSSH,从而阻止了代理转发 . 这可能是一个巨大的边缘案例,但谁知道呢?可能是你!

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

    [ssh_connection]
    ssh_args=-o ForwardAgent=yes
    

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

  • 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"
    

相关问题