使用Jenkins从Ansbile中的Bitbucket获取公钥时被拒绝(Public key denied when fetching from Bitbucket in Ansbile with Jenkins)

我想做什么:

我有一个Ansible脚本,它从Bitbucket执行git克隆,我正在通过Ansible插件从jenkins运行该脚本。

路线:

Jenkins server ---(ansible)---> App server ----(git)---> bitbucket.org

我正在尝试使用Jenkins服务器上的ssh私钥从App服务器连接到Bitbucket上的repo,这应该可以在ssh-agent的帮助下实现。

出了什么问题:

Ansible脚本无法连接到Bitbucket, Public key denied 。

我检查了什么:

Jenkins上的公钥已添加到部署密钥列表中,并且在没有权限问题的情况下可以正常工作。 ssh-agent在jenkins节点上运行,并且添加了jenkins上的私钥。 在服务器AllowFowardAgent设置为yes 。 jenkins的ansible插件将私钥复制到/tmp并在运行playbooks时使用它。 这与我使用ssh-add -ed的文件路径不同,但我不认为这会导致问题。

詹金斯代码

在运行Ansible任务之前,我先运行下面的shell脚本:

eval `ssh-agent -s` ssh-add ~/.ssh/id_rsa cat >~/.ssh/config <<EOL Host * ForwardAgent yes EOL cat ~/.ssh/config git clone git@bitbucket.org:myuser/myrepo.git

Ansible代码

我的剧本:

- name: check SSH_AUTH_SOCK shell: echo "$SSH_AUTH_SOCK" - name: check ssh-agent forwarding shell: ssh -T git@bitbucket.org

我的ansible.cfg :

[ssh_connection] ssh_args = -o ForwardAgent=yes -o StrictHostKeyChecking=no -C -o ControlMaster=auto -o ControlPersist=60s

输出

在我的Ansible脚本中,我可以看到设置了SSH_AUTH_SOCK :

11:29:04 changed: [testserver] => {"changed": true, "cmd": "echo \"$SSH_AUTH_SOCK\"", "delta": "0:00:00.007881", "end": "2016-09-06 11:29:04.576963", "invocation": {"module_args": {"_raw_params": "echo \"$SSH_AUTH_SOCK\"", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 0, "start": "2016-09-06 11:29:04.569082", "stderr": "", "stdout": "/tmp/ssh-WnmHgtzMBS/agent.13630", "stdout_lines": ["/tmp/ssh-WnmHgtzMBS/agent.13630"], "warnings": []}

但是ssh -T git@bitbucket.org失败了:

11:29:09 fatal: [testserver]: FAILED! => {"changed": true, "cmd": "ssh -T git@bitbucket.org", "delta": "0:00:05.009720", "end": "2016-09-06 11:29:09.879430", "failed": true, "invocation": {"module_args": {"_raw_params": "ssh -T git@bitbucket.org", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 255, "start": "2016-09-06 11:29:04.869710", "stderr": "Error reading response length from authentication socket.\r\nPermission denied (publickey).", "stdout": "", "stdout_lines": [], "warnings": []}

What I am trying to do:

I have an Ansible script which does a git clone from Bitbucket, and I'm running that script from jenkins via the Ansible plugin.

The route:

Jenkins server ---(ansible)---> App server ----(git)---> bitbucket.org

I'm trying to connect to the repo on Bitbucket from the App server, using the ssh private key on the Jenkins server, which should be achievable with the help of ssh-agent.

What's going wrong:

The Ansible script fails connecting to Bitbucket with Public key denied.

What I have checked:

The public key on Jenkins has been added to deploy keys list and it do works without permission problems. ssh-agent is running on the jenkins node and the private key on jenkins has been added. AllowFowardAgent has been set to yes on the server. The ansible plugin for jenkins copies the private key to /tmp and use it when running playbooks. It's not the same file path to what I have ssh-add-ed, but I don't think that's causing the problem.

The Jenkins code

Before running the Ansible task I have the below shell script run first:

eval `ssh-agent -s` ssh-add ~/.ssh/id_rsa cat >~/.ssh/config <<EOL Host * ForwardAgent yes EOL cat ~/.ssh/config git clone git@bitbucket.org:myuser/myrepo.git

The Ansible code

My playbook:

- name: check SSH_AUTH_SOCK shell: echo "$SSH_AUTH_SOCK" - name: check ssh-agent forwarding shell: ssh -T git@bitbucket.org

My ansible.cfg:

[ssh_connection] ssh_args = -o ForwardAgent=yes -o StrictHostKeyChecking=no -C -o ControlMaster=auto -o ControlPersist=60s

The output

In my Ansible script I can see that SSH_AUTH_SOCK is set:

11:29:04 changed: [testserver] => {"changed": true, "cmd": "echo \"$SSH_AUTH_SOCK\"", "delta": "0:00:00.007881", "end": "2016-09-06 11:29:04.576963", "invocation": {"module_args": {"_raw_params": "echo \"$SSH_AUTH_SOCK\"", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 0, "start": "2016-09-06 11:29:04.569082", "stderr": "", "stdout": "/tmp/ssh-WnmHgtzMBS/agent.13630", "stdout_lines": ["/tmp/ssh-WnmHgtzMBS/agent.13630"], "warnings": []}

But ssh -T git@bitbucket.org fails:

11:29:09 fatal: [testserver]: FAILED! => {"changed": true, "cmd": "ssh -T git@bitbucket.org", "delta": "0:00:05.009720", "end": "2016-09-06 11:29:09.879430", "failed": true, "invocation": {"module_args": {"_raw_params": "ssh -T git@bitbucket.org", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 255, "start": "2016-09-06 11:29:04.869710", "stderr": "Error reading response length from authentication socket.\r\nPermission denied (publickey).", "stdout": "", "stdout_lines": [], "warnings": []}

最满意答案

当您执行ssh-agent -s它会输出SSH的代理转发功能所需的一系列环境变量,例如:

SSH_AUTH_SOCK=/var/folders/nw/2vnhg_gj77v_cyfv0p1vdfj80000gn/T//ssh-alCh0yLKdoci/agent.53532; export SSH_AUTH_SOCK; SSH_AGENT_PID=53533; export SSH_AGENT_PID; echo Agent pid 53533;

当你通过eval运行它们时,这些命令在当前shell会话中执行,你可以看到最后一个( echo )的输出:

Agent pid 53533

但是,为当前进程和子进程设置了环境变量。 如果您从不同的流程调用Ansible playbook,则不会看到它们。

正如您已经想到的那样,Jenkins的SSH代理插件需要注意,以便其他进程(如Ansible插件)将继承这些环境变量。

When you execute ssh-agent -s it outputs a series of environment variables which are required for agent forwarding feature of SSH, for example:

SSH_AUTH_SOCK=/var/folders/nw/2vnhg_gj77v_cyfv0p1vdfj80000gn/T//ssh-alCh0yLKdoci/agent.53532; export SSH_AUTH_SOCK; SSH_AGENT_PID=53533; export SSH_AGENT_PID; echo Agent pid 53533;

When you run it through eval these commands get executed in the current shell session and you can see the output of the last one (echo):

Agent pid 53533

The environment variables however are set for the current process and subprocesses. If you call Ansible playbook from a different process, they won't be seen.

As you already figured out, the SSH Agent Plugin for Jenkins takes care so that other processes (like Ansible plugin) will inherit these environment variables.

使用Jenkins从Ansbile中的Bitbucket获取公钥时被拒绝(Public key denied when fetching from Bitbucket in Ansbile with Jenkins)

我想做什么:

我有一个Ansible脚本,它从Bitbucket执行git克隆,我正在通过Ansible插件从jenkins运行该脚本。

路线:

Jenkins server ---(ansible)---> App server ----(git)---> bitbucket.org

我正在尝试使用Jenkins服务器上的ssh私钥从App服务器连接到Bitbucket上的repo,这应该可以在ssh-agent的帮助下实现。

出了什么问题:

Ansible脚本无法连接到Bitbucket, Public key denied 。

我检查了什么:

Jenkins上的公钥已添加到部署密钥列表中,并且在没有权限问题的情况下可以正常工作。 ssh-agent在jenkins节点上运行,并且添加了jenkins上的私钥。 在服务器AllowFowardAgent设置为yes 。 jenkins的ansible插件将私钥复制到/tmp并在运行playbooks时使用它。 这与我使用ssh-add -ed的文件路径不同,但我不认为这会导致问题。

詹金斯代码

在运行Ansible任务之前,我先运行下面的shell脚本:

eval `ssh-agent -s` ssh-add ~/.ssh/id_rsa cat >~/.ssh/config <<EOL Host * ForwardAgent yes EOL cat ~/.ssh/config git clone git@bitbucket.org:myuser/myrepo.git

Ansible代码

我的剧本:

- name: check SSH_AUTH_SOCK shell: echo "$SSH_AUTH_SOCK" - name: check ssh-agent forwarding shell: ssh -T git@bitbucket.org

我的ansible.cfg :

[ssh_connection] ssh_args = -o ForwardAgent=yes -o StrictHostKeyChecking=no -C -o ControlMaster=auto -o ControlPersist=60s

输出

在我的Ansible脚本中,我可以看到设置了SSH_AUTH_SOCK :

11:29:04 changed: [testserver] => {"changed": true, "cmd": "echo \"$SSH_AUTH_SOCK\"", "delta": "0:00:00.007881", "end": "2016-09-06 11:29:04.576963", "invocation": {"module_args": {"_raw_params": "echo \"$SSH_AUTH_SOCK\"", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 0, "start": "2016-09-06 11:29:04.569082", "stderr": "", "stdout": "/tmp/ssh-WnmHgtzMBS/agent.13630", "stdout_lines": ["/tmp/ssh-WnmHgtzMBS/agent.13630"], "warnings": []}

但是ssh -T git@bitbucket.org失败了:

11:29:09 fatal: [testserver]: FAILED! => {"changed": true, "cmd": "ssh -T git@bitbucket.org", "delta": "0:00:05.009720", "end": "2016-09-06 11:29:09.879430", "failed": true, "invocation": {"module_args": {"_raw_params": "ssh -T git@bitbucket.org", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 255, "start": "2016-09-06 11:29:04.869710", "stderr": "Error reading response length from authentication socket.\r\nPermission denied (publickey).", "stdout": "", "stdout_lines": [], "warnings": []}

What I am trying to do:

I have an Ansible script which does a git clone from Bitbucket, and I'm running that script from jenkins via the Ansible plugin.

The route:

Jenkins server ---(ansible)---> App server ----(git)---> bitbucket.org

I'm trying to connect to the repo on Bitbucket from the App server, using the ssh private key on the Jenkins server, which should be achievable with the help of ssh-agent.

What's going wrong:

The Ansible script fails connecting to Bitbucket with Public key denied.

What I have checked:

The public key on Jenkins has been added to deploy keys list and it do works without permission problems. ssh-agent is running on the jenkins node and the private key on jenkins has been added. AllowFowardAgent has been set to yes on the server. The ansible plugin for jenkins copies the private key to /tmp and use it when running playbooks. It's not the same file path to what I have ssh-add-ed, but I don't think that's causing the problem.

The Jenkins code

Before running the Ansible task I have the below shell script run first:

eval `ssh-agent -s` ssh-add ~/.ssh/id_rsa cat >~/.ssh/config <<EOL Host * ForwardAgent yes EOL cat ~/.ssh/config git clone git@bitbucket.org:myuser/myrepo.git

The Ansible code

My playbook:

- name: check SSH_AUTH_SOCK shell: echo "$SSH_AUTH_SOCK" - name: check ssh-agent forwarding shell: ssh -T git@bitbucket.org

My ansible.cfg:

[ssh_connection] ssh_args = -o ForwardAgent=yes -o StrictHostKeyChecking=no -C -o ControlMaster=auto -o ControlPersist=60s

The output

In my Ansible script I can see that SSH_AUTH_SOCK is set:

11:29:04 changed: [testserver] => {"changed": true, "cmd": "echo \"$SSH_AUTH_SOCK\"", "delta": "0:00:00.007881", "end": "2016-09-06 11:29:04.576963", "invocation": {"module_args": {"_raw_params": "echo \"$SSH_AUTH_SOCK\"", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 0, "start": "2016-09-06 11:29:04.569082", "stderr": "", "stdout": "/tmp/ssh-WnmHgtzMBS/agent.13630", "stdout_lines": ["/tmp/ssh-WnmHgtzMBS/agent.13630"], "warnings": []}

But ssh -T git@bitbucket.org fails:

11:29:09 fatal: [testserver]: FAILED! => {"changed": true, "cmd": "ssh -T git@bitbucket.org", "delta": "0:00:05.009720", "end": "2016-09-06 11:29:09.879430", "failed": true, "invocation": {"module_args": {"_raw_params": "ssh -T git@bitbucket.org", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 255, "start": "2016-09-06 11:29:04.869710", "stderr": "Error reading response length from authentication socket.\r\nPermission denied (publickey).", "stdout": "", "stdout_lines": [], "warnings": []}

最满意答案

当您执行ssh-agent -s它会输出SSH的代理转发功能所需的一系列环境变量,例如:

SSH_AUTH_SOCK=/var/folders/nw/2vnhg_gj77v_cyfv0p1vdfj80000gn/T//ssh-alCh0yLKdoci/agent.53532; export SSH_AUTH_SOCK; SSH_AGENT_PID=53533; export SSH_AGENT_PID; echo Agent pid 53533;

当你通过eval运行它们时,这些命令在当前shell会话中执行,你可以看到最后一个( echo )的输出:

Agent pid 53533

但是,为当前进程和子进程设置了环境变量。 如果您从不同的流程调用Ansible playbook,则不会看到它们。

正如您已经想到的那样,Jenkins的SSH代理插件需要注意,以便其他进程(如Ansible插件)将继承这些环境变量。

When you execute ssh-agent -s it outputs a series of environment variables which are required for agent forwarding feature of SSH, for example:

SSH_AUTH_SOCK=/var/folders/nw/2vnhg_gj77v_cyfv0p1vdfj80000gn/T//ssh-alCh0yLKdoci/agent.53532; export SSH_AUTH_SOCK; SSH_AGENT_PID=53533; export SSH_AGENT_PID; echo Agent pid 53533;

When you run it through eval these commands get executed in the current shell session and you can see the output of the last one (echo):

Agent pid 53533

The environment variables however are set for the current process and subprocesses. If you call Ansible playbook from a different process, they won't be seen.

As you already figured out, the SSH Agent Plugin for Jenkins takes care so that other processes (like Ansible plugin) will inherit these environment variables.