Ansible не поддерживает управление хостами с двухфакторной аутентификацией (2FA), причина этого разъясняется в FAQ.
Рекомендации различных ресурсов интернета по обходу этого ограничения можно свести к трем группам:
выделить на хосте пользователя, под которым будет исполняться Ansible и для этого пользователя в настройках
sudo
отменить запрос пароля;также выделить пользователя для Ansible и изменить настройки PAM либо SSH-сервера, чтобы для этого пользователя 2FA стала необязательной;
разработать become plugin для Ansible, который будет служить оберткой программы
sudo
и обрабатывать приглашение 2FA.
Однако когда Ansible обслуживает тот же хост, на котором она запускается, существует простая лазейка.
Вначале опишу симптомы проблемы.
Я использую RuToken ЭЦП для локального входа на рабочую станцию под Linux, токен используется как необязательное средство аутентификации. Настроено по документации RuToken (https://dev.rutoken.ru/pages/viewpage.action?pageId=3440696 и https://dev.rutoken.ru/pages/viewpage.action?pageId=3440665).
Для подключения к хосту этой рабочей станции в Ansible используется локальное соединение, повышение привилегий --- по умолчанию (в sudo
). Файлы inventory зашифрованы в Ansible Vault.
Файл hosts.yml
:
all:
hosts:
workstation1:
ansible_python_interpreter: /usr/bin/python3.9
ansible_connection: local
ansible_become_pass: PASSWORD
Если к компьютеру токен не подключен, повышение привилегий происходит успешно:
$ ansible workstation1 -m ping -b
Vault password:
workstation1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Если же токен подключен, повышение привилегий не происходит: после ввода пароля от vault на терминал ничего не выводится, а после прерывания работы Ansible клавиатурной комбинацией Ctrl+C
приходит уведомление безопасности, содержащее «a password is required».
Лазейка — в том, чтобы в терминале, где позже будет запущена Ansible, выполнить команду sudo
. В течение некоторого времени после этого (по умолчанию — 15 минут) повышение привилегий произойдет без повторной аутентификации.
Пример:
$ sudo which false
Login with RuToken001:
/usr/bin/false
$ ansible workstation1 -m ping -b
Vault password:
workstation1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Пусть такое решение — очевидный костыль, надеюсь, оно будет вам полезным.