Решение с использованием узла-бастиона
Даже используя хост-бастион ssh, мне потребовалось довольно много времени, чтобы заставить это работать. Если это поможет кому-то еще, вот что я придумал. Он использует параметры конфигурации ControlMaster
ssh, и, поскольку ansible использует обычный ssh, его можно настроить на использование тех же функций ssh и повторное использование соединения с хостом-бастионом независимо от того, сколько подключений он открывает к удаленным хостам. Я видел, что эти параметры управления рекомендуются в целом (предположительно из соображений производительности, если у вас много хостов), но не в контексте 2FA для хоста-бастиона.
При таком подходе вам не нужны какие-либо изменения конфигурации sshd, поэтому вам понадобится AuthenticationMethods publickey,keyboard-interactive
в качестве единственного параметра метода аутентификации на сервере-бастионе, а publickey
— только для всех других ваших серверов, к которым вы проксируете через бастион. Поскольку хост-бастион — единственный, который принимает внешние подключения из Интернета, он единственный, для которого требуется 2FA, а внутренние хосты полагаются на переадресацию агента для аутентификации с открытым ключом, но не используют 2FA.
На клиенте я создал новый файл конфигурации ssh для моей среды ansible в каталоге верхнего уровня, из которого я запускаю ansible (т. Это содержит:
Host bastion-persistent-connection
HostName <bastion host>
ForwardAgent yes
IdentityFile ~/.ssh/my-key
ControlMaster auto
ControlPath ~/.ssh/ansible-%r@%h:%p
ControlPersist 10m
Host 10.0.*.*
ProxyCommand ssh -W %h:%p bastion-persistent-connection -F ./ssh.config
IdentityFile ~/.ssh/my-key
Затем в ansible.cfg у меня есть:
[ssh_connection]
ssh_args = -F ./ssh.config
Несколько замечаний:
Моя частная подсеть в этом случае — 10.0.0.0/16, что соответствует параметру подстановочного знака хоста выше. Бастион проксирует все ssh-соединения с серверами в этой подсети.
Это немного хрупко, поскольку я могу запускать свои команды ssh или ansible только в этом каталоге из-за того, что ProxyCommand
передает локальный путь к этому файлу конфигурации. К сожалению, я не думаю, что есть переменная ssh, которая сопоставляется с текущим используемым файлом конфигурации, чтобы я мог автоматически передать тот же файл конфигурации в ProxyCommand. В зависимости от вашей среды может быть лучше использовать для этого абсолютный путь.
Единственная загвоздка в том, что это делает запуск более сложным. К сожалению, из того, что я могу сказать, Ansible вообще не поддерживает 2FA. Поэтому, если у вас нет существующего ssh-соединения с бастионом, ansible будет распечатывать Verification code:
один раз для каждого частного сервера, к которому он подключается, но на самом деле он не прослушивает входные данные, поэтому независимо от того, что вы делаете, соединения не будут выполнены.
Итак, я сначала запускаю: ssh -F ssh.config bastion-persistent-connection
Это создает файл сокета в ~/.ssh/ansible-*
, и агент ssh локально закроет и удалит этот сокет по истечении настраиваемого времени (я установил 10 минут).
Как только сокет открыт, я могу запускать команды ansible, как обычно, например. ansible all -m ping
и им это удается.
person
danny
schedule
13.02.2017