【问题标题】:Public key denied when fetching from Bitbucket in Ansbile with Jenkins使用 Jenkins 从 Ansible 中的 Bitbucket 获取时公钥被拒绝
【发布时间】:2017-01-13 09:45:08
【问题描述】:

我想做什么:

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

路线:

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

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

出了什么问题:

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

我检查过的内容:

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

Jenkins 代码

在运行 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": []}

【问题讨论】:

  • ssh-add -L 是否显示转发的公钥(在check SSH_AUTH_SOCK 任务旁边)?
  • @techraf 奇怪的是,上面写着Could not open a connection to your authentication agent.
  • @techraf AllowForwardingAgent 已在 /etc/ssh/sshd_config 中设置为 yes。 (默认为 yes)我可以从我的笔记本电脑上执行相同的 ansible 脚本,但不能从 jenkins 机器上执行。 ansible-playbook 开始运行后,ssh-agent 似乎丢失了(在 App 服务器中设置了 SSH_AUTH_SOCK,但在 Jenkins 服务器中没有设置),但仍然不知道为什么。
  • Kinda 找到了解决方案:使用 jenkins 的 ssh-agent 插件,而不是在 shell 脚本中运行 ssh-agentssh-add。但是还是不知道为什么shell脚本的方式会出错。
  • 我猜如果你从调用 eval 的同一个脚本运行 Ansible,它会起作用。

标签: git jenkins ssh ansible ssh-agent


【解决方案1】:

当你执行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 插件)继承这些环境变量。

【讨论】:

  • 我假设 jenkins 在同一个会话中运行构建脚本,这似乎是错误的。谢谢!
  • 它可能在同一个会话中运行,但会为任务生成单独的进程(脚本和 Ansible 是兄弟姐妹)。否则它将不得不进行级联执行(一个进程在最后调用另一个进程),这将是一项相当大的努力。
猜你喜欢
  • 2018-03-11
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多