Перенаправление агента SSH с помощью Ansible

Я использую Ansible 1.5.3 и Git с пересылкой агента ssh (https://help.github.com/articles/using-ssh-agent-forwarding). Я могу войти на сервер, которым управляю с помощью Ansible, и проверить правильность настройки моего подключения к git:

ubuntu@test:~$ 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, но я подозреваю, что многие впервые столкнутся с проблемой в этом сценарии.


person Bob Barcklay    schedule 09.06.2014    source источник


Ответы (4)


Проблема решена удалением этой строки из плейбука:

sudo: yes

Когда sudo запускается на удаленном хосте, переменные среды, установленные ssh во время входа в систему, больше не доступны. В частности, SSH_AUTH_SOCK, который «определяет путь сокета UNIX-домена, используемого для связи с агентом», больше не отображается, поэтому пересылка агента ssh не работает.

Избегать sudo, когда он вам не нужен, - это один из способов обойти проблему. Другой способ - убедиться, что SSH_AUTH_SOCK остается во время сеанса sudo, создав файл sudoers:

/etc/sudoers:

     Defaults    env_keep += "SSH_AUTH_SOCK"
person Bob Barcklay    schedule 10.06.2014
comment
Может потребоваться явная установка sudo: no. - person Daniel Da Cunha; 06.02.2015
comment
Если вы используете SSH_AUTH_SOCK, по крайней мере, помните об угрозе безопасности serverfault.com/a/371788/67801 - person SystematicFrank; 29.07.2015
comment
@SystematicFrank: угроза безопасности в вашей ссылке касается chmod 777, а не SSH_AUTH_SOCK - person Bryan Larsen; 04.12.2015
comment
Это сработало для меня. Я автоматизировал это с помощью: - name: enable SSH creds passthrough lineinfile: dest = / etc / sudoers regexp = '^ #? Defaults \ W env_keep [^ $]' line = 'По умолчанию env_keep + = SSH_AUTH_SOCK ' - person Andrej Kyselica; 29.01.2017

Здесь есть несколько очень полезных частичных ответов, но, столкнувшись с этой проблемой несколько раз, я думаю, что обзор был бы полезен.

Во-первых, вам нужно убедиться, что пересылка агента 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: yesbecome_user: root) обычно отключает пересылку агента, потому что переменная среды SSH_AUTH_SOCK сбрасывается. (Меня шокирует то, что кажется, что 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"'

Эта задача playbook немного более консервативна, чем некоторые из других предложенных, поскольку она добавляет ее после любых других env_keep настроек по умолчанию (или в конце файла, если они не найдены), без изменения каких-либо существующих env_keep настроек или при условии, что SSH_AUTH_SOCK установлен. уже присутствует.

person Trevor Robinson    schedule 02.02.2017
comment
@AlouaniYounes Он продолжал работать у меня, когда я обновился до Ansible 2.4. - person Trevor Robinson; 11.02.2019
comment
@ trevor-robison О, ты только что сделал мне день. Добавление параметра ssh_connection в мой ansible.cfg работает очень хорошо, так что спасибо! :) - person Justin Finkelstein; 07.10.2020
comment
Sudo также позволяет сохранять только определенные переменные среды с помощью флагов. Поэтому -E в настройке become_flags ansible можно заменить более конкретным --preserve-env=SSH_AUTH_SOCK. Это помогает уменьшить побочные эффекты от сохранения всей окружающей среды. - person Septatrix; 16.05.2021

Другой ответ на ваш вопрос (за исключением того, что я использую Ansible 1.9) может быть следующим:

Вы можете проверить свой /etc/ansible/ansible.cfg (или три других потенциальных места, где параметры конфигурации можно переопределить) на предмет transport=smart в соответствии с рекомендациями в доступных документах. В какой-то момент во время предыдущей попытки установки мой по умолчанию использовал transport=paramiko, что не позволило моей управляющей машине использовать OpenSSH и, таким образом, переадресовывать агент. Вероятно, это серьезный случай, но кто знает? Это мог быть ты!

Хотя я не счел это необходимым для моей конфигурации, я должен отметить, что другие упоминали, что вы должны добавить -o ForwardAgent=yes в настройку ssh_args в том же файле, например:

[ssh_connection]
ssh_args=-o ForwardAgent=yes

Я упоминаю об этом здесь только для полноты картины.

person swendr    schedule 02.03.2015
comment
Мне пришлось добавить ssh_args к моему ansible.cfg, чтобы пересылка агента SSH вообще работала. Престижность тебе за то, что ты единственный, кто это предложил! Я на OSX 10.10, использую Ansible 1.9.1 - person staticfloat; 12.05.2015
comment
Если вы укажете ssh_args, это предотвратит предоставление ansible своих собственных аргументов, включая аргументы, которые устанавливают постоянные соединения. Это может вызвать огромное замедление. Соответствующие аргументы, которые будут добавлены: -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r. - person qqx; 18.11.2015
comment
Иногда также возникает проблема с sudo_flags, для которого по умолчанию установлено значение sudo_flags = -H -S -n, и может возникнуть сбой с sudo: требуется пароль. В этом случае вам нужно установить sudo_flags = -H -S опцию удаления -n. - person Michał Zalewski; 26.04.2016
comment
Я понимаю, что использование ssh_extra_args=-o ForwardAgent=yes предотвращает замедление (упомянутое qqx). - person simohe; 11.01.2019

Чтобы расширить ответ @ 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"
person AJcodez    schedule 11.06.2015
comment
Но разве нам не нужно запускать анзибл дважды? Один для настройки ssh fwding, а другой для фактического установления соединения с этим набором env var? - person alfetopito; 13.08.2015
comment
Звучит правильно. Я всегда заканчиваю тем, что запускаю и комментирую playbook несколько раз, ssh в коробки и проверяю вещи вручную. Это никогда не было гладким плаванием. - person AJcodez; 14.08.2015
comment
Чтобы избежать многократного запуска, я поместил этот шаг в сценарий, который запускаю при новой установке сервера. В конце концов, есть вещи, которые нужно настроить, прежде чем я смогу настроить свой сервер с помощью ansible ... - person alfetopito; 14.08.2015