Хотел бы понять механизм, зачем использовать становиться быть доступным пользователем вызывает "Permission denied (publickey)".
Пользователь анзибль для запуска ansible-playbook для проверки репозитория 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 только на сервере, на котором работает ansible-playbook, но не на целевом сервере. Как происходит аутентификация Github SSH на целевом сервере?
- 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
хозяева
[webservers]
ub01
#rh01
ansible.cfg
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes
Плейбук Ansible работает на RedHat.
NAME="Red Hat Enterprise Linux Server"
VERSION="7.3 (Maipo)"
Целевой хост - Ubuntu.
DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
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 -m u:ansible:r-x /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": "git@github.com: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. Однако SUDO исключает переменные среды, поэтому SSH-клиент sudo-ed не знает, как общаться с SSH-агентом. Следовательно, не может пройти аутентификацию SSh.
Решение находится в статье, предоставленной @Jakuje.
Когда вы вперед ssh-agent
socket, он создается с правами подключающегося пользователя. become
позже делает ansible
чтобы сменить пользователя на другого пользователя (ansible
) с помощью sudo
, что приводит к:
sudo
Если целевой пользователь root
, первое не должно быть проблемой. Вторую проблему можно решить, изменив /etc/sudoers
на сервере должна быть линия
Defaults env_keep += "SSH_AUTH_SOCK"
Далее это объясняется в сообщение на SO.
Преодолеть вторую проблему будет сложнее, потому что вы не хотите, чтобы ваш перенаправленный сокет был доступен всем пользователям. Вы рассматривали возможность подключения напрямую как пользователь? ansible
?