git 使用 Ansible 进行 SSH 代理转发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24124140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SSH Agent Forwarding with Ansible
提问by Bob Barcklay
I'm using Ansible 1.5.3 and Git with ssh agent forwarding (https://help.github.com/articles/using-ssh-agent-forwarding). I can log into the server that I am managing with Ansible and test that my connection to git is correctly configured:
我将 Ansible 1.5.3 和 Git 与 ssh 代理转发一起使用(https://help.github.com/articles/using-ssh-agent-forwarding)。我可以登录到我使用 Ansible 管理的服务器并测试我与 git 的连接是否正确配置:
ubuntu@test:~$ ssh -T [email protected]
Hi gituser! You've successfully authenticated, but GitHub does not provide shell access.
I can also clone and update one of my repos using this account so my git configuration looks good and uses ssh forwarding when I log into my server directly via ssh.
我还可以使用此帐户克隆和更新我的一个存储库,因此当我通过 ssh 直接登录到我的服务器时,我的 git 配置看起来不错并使用 ssh 转发。
The problem: When I attempt the same test shown above using the Ansible command module. It fails with “Permission denied”. Part of the Ansible output (with verbose logging) looks like this:
问题:当我使用 Ansible 命令模块尝试上面显示的相同测试时。它因“权限被拒绝”而失败。Ansible 输出的一部分(带有详细日志记录)如下所示:
failed: [xxx.xxxxx.com] => {"changed": true, "cmd": ["ssh", "-T", "[email protected]"], "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).
Here is the simple playbook that runs this command:
这是运行此命令的简单剧本:
- hosts: webservers
sudo: yes
remote_user: ubuntu
tasks:
- name: Test that git ssh connection is working.
command: ssh -T [email protected]
The question: why does everything work correctly when I manually log in via ssh and run the command but fail when the same command is run as the same user via Ansible?
问题:为什么当我通过 ssh 手动登录并运行命令时一切正常,但在通过 Ansible 以同一用户身份运行相同命令时失败?
I will post the answer shortly if no one else beats me to it. Although I am using git to demonstrate the problem, it could occur with any module that depends on ssh agent forwarding. It is not specific to Ansible but I suspect many will first encounter the problem in this scenario.
如果没有其他人打败我,我会很快发布答案。尽管我使用 git 来演示该问题,但任何依赖于 ssh 代理转发的模块都可能发生该问题。它不是 Ansible 特有的,但我怀疑很多人会在这种情况下首先遇到这个问题。
回答by Bob Barcklay
The problem is resolved by removing this line from the playbook:
通过从剧本中删除这一行来解决问题:
sudo: yes
When sudo is run on the remote host, the environment variables set by ssh during login are no longer available. In particular, SSH_AUTH_SOCK, which "identifies the path of a UNIX-domain socket used to communicate with the agent" is no longer visible so ssh agent forwarding does not work.
在远程主机上运行 sudo 时,登录时 ssh 设置的环境变量不再可用。特别是 SSH_AUTH_SOCK,它“标识用于与代理通信的 UNIX 域套接字的路径”不再可见,因此 ssh 代理转发不起作用。
Avoiding sudo when you don't need it is one way to work around the problem. Another way is to ensure that SSH_AUTH_SOCK sticks around during your sudo session by creating a sudoers file:
在不需要时避免使用 sudo 是解决问题的一种方法。另一种方法是通过创建 sudoers 文件来确保 SSH_AUTH_SOCK 在您的 sudo 会话期间保持不变:
/etc/sudoers:
Defaults env_keep += "SSH_AUTH_SOCK"
回答by Trevor Robinson
There are some very helpful partial answers here, but after running into this issue a number of times, I think an overview would be helpful.
这里有一些非常有用的部分答案,但是在多次遇到这个问题之后,我认为概述会有所帮助。
First, you need to make sure that SSH agent forwarding is enabled when connecting from your client running Ansible to the target machine. Even with transport=smart
, SSH agent forwarding may not be automatically enabled, depending on your client's SSH configuration. To ensure that it is, you can update your ~/.ansible.cfg
to include this section:
首先,您需要确保在从运行 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
Next, you'll likely have to deal with the fact that become: yes
(and become_user: root
) will generally disable agent forwarding because the SSH_AUTH_SOCK
environment variable is reset. (I find it shocking that Ansible seems to assumethat people will SSH as root, since that makes any useful auditing impossible.) There are a few ways to deal with this. As of Ansible 2.2, the easiest approach is to preserve the (whole) environment when using sudo
by specifying the -E
flag:
接下来,您可能需要处理这样一个事实,即become: yes
(和become_user: root
) 通常会禁用代理转发,因为SSH_AUTH_SOCK
环境变量已重置。(我感到震惊的是,Ansible 似乎假设人们将以 root 身份使用 SSH,因为这使得任何有用的审计都变得不可能。)有几种方法可以解决这个问题。从 Ansible 2.2 开始,最简单的方法是在使用时sudo
通过指定-E
标志来保留(整个)环境:
become_flags: "-E"
However, this can have unwanted side-effects by preserving variables like PATH
. The cleanest approach is to only preserve SSH_AUTH_SOCK
by including it in env_keep
in your /etc/sudoers
file:
但是,通过保留诸如PATH
. 最干净的方法是仅SSH_AUTH_SOCK
通过将其包含env_keep
在/etc/sudoers
文件中来保留:
Defaults env_keep += "SSH_AUTH_SOCK"
To do this with Ansible:
使用 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"'
This playbook task is a little more conservative than some of the others suggested, since it adds this after any other default env_keep
settings (or at the end of the file, if none are found), without changing any existing env_keep
settings or assuming SSH_AUTH_SOCK
is already present.
这个剧本任务比其他一些建议的要保守一些,因为它在任何其他默认env_keep
设置之后(或在文件末尾,如果没有找到)添加它,而不更改任何现有env_keep
设置或假设SSH_AUTH_SOCK
已经存在。
回答by swendr
Another answer to your question (with the exception that I am using Ansible 1.9) could be the following:
您问题的另一个答案(除了我使用的是 Ansible 1.9)可能如下:
You may want to check your /etc/ansible/ansible.cfg (or the other three potential locations where config settings can be overridden) for transport=smart
as recommended in the ansible docs. Mine had defaulted to transport=paramiko
at some point during a previous install attempt, preventing my control machine from utilizing OpenSSH, and thus agent forwarding. This is probably a massive edge case, but who knows? It could be you!
您可能需要按照 ansible文档中的transport=smart
建议检查您的 /etc/ansible/ansible.cfg(或其他三个可以覆盖配置设置的潜在位置)。我的在之前的安装尝试中的某个时间点默认为,阻止我的控制机器使用 OpenSSH,从而阻止代理转发。这可能是一个巨大的边缘情况,但谁知道呢?可能是你!transport=paramiko
Though I didn't find it necessary for my configuration, I should note that others have mentioned that you should add -o ForwardAgent=yes
to your ssh_args setting in the same file like so:
虽然我认为我的配置没有必要,但我应该注意到其他人已经提到你应该-o ForwardAgent=yes
在同一个文件中添加你的 ssh_args 设置,如下所示:
[ssh_connection]
ssh_args=-o ForwardAgent=yes
I only mention it here for the sake of completeness.
我只是为了完整起见在这里提到它。
回答by AJcodez
To expand on @j.freckle's answer, the ansible way to change sudoers file is:
要扩展@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"