Пересылка агента SSH с помощью Ansible
Im использует Ansible 1.5.3 и Git с пересылкой агента ssh (https://help.github.com/articles/using-ssh-agent-forwarding). Я могу войти на сервер, с которым я управляю с помощью Ansible, и проверить правильность настройки моего подключения к Git:
[email protected]:~$ ssh -T [email protected]
Hi gituser! You've successfully authenticated, but GitHub does not provide shell access.
Я также могу клонировать и обновлять один из моих репозиториев, используя эту учетную запись, поэтому моя конфигурация Git выглядит хорошо и использует пересылку ssh при входе на мой сервер непосредственно через ssh.
Проблема: когда я пытаюсь выполнить тот же тест, показанный выше, используя командный модуль Ansible. Он не работает с "Permission denied". Часть выходного сигнала 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).
Вот простая игра, в которой выполняется эта команда:
- hosts: webservers
sudo: yes
remote_user: ubuntu
tasks:
- name: Test that git ssh connection is working.
command: ssh -T [email protected]
Вопрос: почему все работает правильно, когда я вручную регистрируюсь через ssh и запускаю команду, но не удается, когда одна и та же команда запускается как один и тот же пользователь через Ansible?
Я отправлю ответ в ближайшее время, если меня никто не будет бить. Хотя я использую Git для демонстрации проблемы, это может произойти с любым модулем, который зависит от пересылки агента ssh. Это не относится к Ansible, но я подозреваю, что многие впервые столкнутся с проблемой в этом сценарии.
Ответы
Ответ 1
Проблема разрешена удалением этой строки из учебника:
sudo: yes
Когда sudo запускается на удаленном хосте, переменные среды, заданные ssh во время входа в систему, больше не доступны. В частности, SSH_AUTH_SOCK, который "идентифицирует путь к сокету UNIX-домена, используемого для связи с агентом", больше не отображается, поэтому пересылка агента ssh не работает.
Избегайте sudo, когда вам это не нужно, это один из способов обойти проблему. Другой способ - убедиться, что SSH_AUTH_SOCK работает во время сеанса sudo, создав файл sudoers:
/etc/sudoers:
Defaults env_keep += "SSH_AUTH_SOCK"
Ответ 2
Другой ответ на ваш вопрос (за исключением того, что я использую Ansible 1.9) может быть следующим:
Вы можете проверить свой /etc/ansible/ansible.cfg(или другие три потенциальных местоположения, где настройки конфигурации могут быть переопределены) для transport=smart
как рекомендовано в несовместимых документах. В какой-то момент Mine отказалась от transport=paramiko
во время предыдущей попытки установки, не позволяя моей машине управления использовать OpenSSH и, таким образом, переадресацию агента. Это, вероятно, массивный край, но кто знает? Это может быть вы!
Хотя я не нашел нужным для своей конфигурации, я должен отметить, что другие упоминали, что вы должны добавить -o ForwardAgent=yes
в свой параметр ssh_args в том же файле, что и так:
[ssh_connection]
ssh_args=-o ForwardAgent=yes
Я только упоминаю это здесь ради полноты.
Ответ 3
Чтобы расширить ответ на @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"
Ответ 4
Здесь есть некоторые очень полезные частичные ответы, но после ряда проблем я думаю, что обзор будет полезен.
Во-первых, вам необходимо убедиться, что пересылка агента SSH включена при подключении вашего клиента, работающего на Ansible, к целевой машине. Даже при 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
Далее вам, вероятно, придется иметь дело с тем фактом, что become: yes
(и become_user: root
) обычно отключает пересылку агента, поскольку переменная среды SSH_AUTH_SOCK
reset. (Я нахожу это шокирующим, что Ansible, похоже, предполагает, что люди будут SSH как root, поскольку это делает любой полезный аудит невозможным.) Есть несколько способов чтобы справиться с этим. Начиная с Ansible 2.2, самый простой способ - сохранить (целую) среду при использовании sudo
, указав флаг -E
:
become_flags: "-E"
Однако это может иметь нежелательные побочные эффекты, сохраняя такие переменные, как PATH
. Самый чистый подход - сохранить SSH_AUTH_SOCK
, включив его в env_keep
в ваш файл /etc/sudoers
:
Defaults env_keep += "SSH_AUTH_SOCK"
Чтобы сделать это с помощью 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"'
Задача этой книги немного более консервативна, чем некоторые из предложенных, поскольку она добавляет это после любых других настроек по умолчанию env_keep
(или в конце файла, если они не найдены), без изменения существующих env_keep
или предполагается, что SSH_AUTH_SOCK
уже присутствует.