Ansible访问Github:成为原因Permission denied(publickey)

目的

想了解为什么使用成为完全的用户导致“权限被拒绝(publickey)”的机制。

用户可以运行安全的手册来检出一个Github仓库。 SSH密钥已经与用户的ssh-copy-id复制在一起。

没有成为 ,剧本运行。

[ansible@ip-172-31-39-108 playbooks]$ whoami ansible [ansible@ip-172-31-39-108 playbooks]$ ansible-playbook git.yml PLAY [Git example] ************************************************************* TASK [setup] ******************************************************************* ok: [ub01] TASK [check out the repository on the host] ************************************ changed: [ub01] PLAY RECAP ********************************************************************* ub01 : ok=2 changed=1 unreachable=0 failed=0 

但是,使用“成为:是”会导致错误。

 [ansible@ip-172-31-39-108 playbooks]$ ansible-playbook git.yml PLAY [Git example] ************************************************************* TASK [setup] ******************************************************************* ok: [ub01] TASK [check out the repository on the host] ************************************ fatal: [ub01]: FAILED! => {"changed": false, "cmd": "/usr/bin/git clone --origin origin '' /home/ansible/project/mezzanine-example", "failed": true, "msg": "Cloning into '/home/ansible/project/mezzanine-example'...\nPermission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.", "rc": 128, "stderr": "Cloning into '/home/ansible/project/mezzanine-example'...\nPermission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n", "stdout": "", "stdout_lines": []} to retry, use: --limit @/home/ansible/playbooks/git.retry PLAY RECAP ********************************************************************* ub01 : ok=1 changed=0 unreachable=0 failed=1 

ssh-agent正在运行,私钥已被添加。

 [ansible@ip-172-31-39-108 playbooks]$ eval $(ssh-agent -s) Agent pid 1513 [ansible@ip-172-31-39-108 playbooks]$ ssh-add ~/.ssh/id_rsa Identity added: /home/ansible/.ssh/id_rsa (/home/ansible/.ssh/id_rsa) 

请提供解释为什么会发生这种情况,或者指出要查看的资源。

另外,我只在启动了剧本的服务器上启动ssh-agent,但不在目标服务器上运行。 如何在目标服务器上进行Github SSH身份validation?

剧本

 - name: Git example hosts: webservers become: no # <----- Changing to yes cause the issue become_user: ansible become_method: sudo vars: repo_url: git@github.com:lorin/mezzanine-example.git proj_dirname: /home/ansible/project proj_name: mezzanine-example proj_path: "{{ proj_dirname }}/{{ proj_name }}" tasks: - name: check out the repository on the host git: repo={{ repo_url }} dest={{ proj_path }} accept_hostkey=yes 

configuration

主机

 [webservers] ub01 #rh01 

ansible.cfg

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

环境

Ansible playbook在RedHat上运行。

 NAME="Red Hat Enterprise Linux Server" VERSION="7.3 (Maipo)" 

目标主机是Ubuntu。

 DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS" 

相关问题

  • 与Github Ansible:权限被拒绝(公钥
  • 如何解决“权限被拒绝(publickey)”。 Ansible和“git clone”问题
  • 从另一个非root用户访问SSH_AUTH_SOCK

控制台-vvvvv输出

 TASK [check out the repository on the host] ************************************ task path: /home/ansible/playbooks/git.yml:12 Using module file /usr/lib/python2.7/site-packages/ansible/modules/core/source_control/git.py <ub01> ESTABLISH SSH CONNECTION FOR USER: None <ub01> SSH: ansible.cfg set ssh_args: (-o)(ControlMaster=auto)(-o)(ControlPersist=60s)(-o)(ForwardAgent=yes) <ub01> SSH: ansible_password/ansible_ssh_pass not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no) <ub01> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10) <ub01> SSH: PlayContext set ssh_common_args: () <ub01> SSH: PlayContext set ssh_extra_args: () <ub01> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r) <ub01> SSH: EXEC ssh -vvv -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r ub01 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /tmp/ansible-tmp-1485919043.94-240537002849590 `" && echo ansible-tmp-1485919043.94-240537002849590="` echo /tmp/ansible-tmp-1485919043.94-240537002849590 `" ) && sleep 0'"'"'' <ub01> PUT /tmp/tmpAjaOMc TO /tmp/ansible-tmp-1485919043.94-240537002849590/git.py <ub01> SSH: ansible.cfg set ssh_args: (-o)(ControlMaster=auto)(-o)(ControlPersist=60s)(-o)(ForwardAgent=yes) <ub01> SSH: ansible_password/ansible_ssh_pass not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no) <ub01> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10) <ub01> SSH: PlayContext set ssh_common_args: () <ub01> SSH: PlayContext set sftp_extra_args: () <ub01> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r) <ub01> SSH: EXEC sftp -b - -vvv -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r '[ub01]' <ub01> ESTABLISH SSH CONNECTION FOR USER: None <ub01> SSH: ansible.cfg set ssh_args: (-o)(ControlMaster=auto)(-o)(ControlPersist=60s)(-o)(ForwardAgent=yes) <ub01> SSH: ansible_password/ansible_ssh_pass not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no) <ub01> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10) <ub01> SSH: PlayContext set ssh_common_args: () <ub01> SSH: PlayContext set ssh_extra_args: () <ub01> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r) <ub01> SSH: EXEC ssh -vvv -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r ub01 '/bin/sh -c '"'"'setfacl -mu:ansible:rx /tmp/ansible-tmp-1485919043.94-240537002849590/ /tmp/ansible-tmp-1485919043.94-240537002849590/git.py && sleep 0'"'"'' <ub01> ESTABLISH SSH CONNECTION FOR USER: None <ub01> SSH: ansible.cfg set ssh_args: (-o)(ControlMaster=auto)(-o)(ControlPersist=60s)(-o)(ForwardAgent=yes) <ub01> SSH: ansible_password/ansible_ssh_pass not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no) <ub01> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10) <ub01> SSH: PlayContext set ssh_common_args: () <ub01> SSH: PlayContext set ssh_extra_args: () <ub01> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r) <ub01> SSH: EXEC ssh -vvv -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r -tt ub01 '/bin/sh -c '"'"'sudo -H -S -n -u ansible /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-cxuzmrsbxdvydelfnjrsmgvocgkeptxd; /usr/bin/python /tmp/ansible-tmp-1485919043.94-240537002849590/git.py'"'"'"'"'"'"'"'"' && sleep 0'"'"'' <ub01> ESTABLISH SSH CONNECTION FOR USER: None <ub01> SSH: ansible.cfg set ssh_args: (-o)(ControlMaster=auto)(-o)(ControlPersist=60s)(-o)(ForwardAgent=yes) <ub01> SSH: ansible_password/ansible_ssh_pass not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no) <ub01> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10) <ub01> SSH: PlayContext set ssh_common_args: () <ub01> SSH: PlayContext set ssh_extra_args: () <ub01> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r) <ub01> SSH: EXEC ssh -vvv -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/home/ansible/.ansible/cp/ansible-ssh-%h-%p-%r ub01 '/bin/sh -c '"'"'rm -f -r /tmp/ansible-tmp-1485919043.94-240537002849590/ > /dev/null 2>&1 && sleep 0'"'"'' fatal: [ub01]: FAILED! => { "changed": false, "cmd": "/usr/bin/git clone --origin origin '' /home/ansible/project/mezzanine-example", "failed": true, "invocation": { "module_args": { "accept_hostkey": true, "bare": false, "clone": true, "depth": null, "dest": "/home/ansible/project/mezzanine-example", "executable": null, "force": false, "key_file": null, "recursive": true, "reference": null, "refspec": null, "remote": "origin", "repo": "[email protected]:lorin/mezzanine-example.git", "ssh_opts": null, "track_submodules": false, "umask": null, "update": true, "verify_commit": false, "version": "HEAD" }, "module_name": "git" }, "msg": "Cloning into '/home/ansible/project/mezzanine-example'...\nPermission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.", "rc": 128, "stderr": "Cloning into '/home/ansible/project/mezzanine-example'...\nPermission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n", "stdout": "", "stdout_lines": [] } to retry, use: --limit @/home/ansible/playbooks/git.retry PLAY RECAP ********************************************************************* ub01 : ok=1 changed=0 unreachable=0 failed=1 

更新

感谢来自@Jakuje和其他文章的回答,了解到SSH代理侦听UNIX套接字文件。 文件名存储在SSH_AUTH_SOCK环境variables中。 但是,SUDO消除了环境variables,因此sudo-ed的SSH客户端不知道如何与SSH代理交谈。 所以不能通过SShauthentication。

  • 了解ssh-agent和ssh-add
  • SSH权威指南6.3。 SSH代理
  • SSH代理转发的图解指南

解决scheme由@Jakuje提供。

在这里输入图像说明

当您转发ssh-agent套接字时,将使用正在连接的用户的权限创build它。 become后来使用sudo来改变用户到一些不同的用户( ansible ),这导致:

  • 目标用户无权访问转发的套接字
  • sudo不会保留环境variables“持有连接”到代理套接字

如果目标用户是root用户,第一个应该不成问题。 第二个问题可以通过修改服务器上的/etc/sudoers来解决

  Defaults env_keep += "SSH_AUTH_SOCK" 

SO上的post进一步解释了这一点。

为了克服第二个问题会更复杂,因为你不想让你的转发套接字可供所有用户使用。 你有没有考虑直接作为一个用户连接?