Как заставить Ansible использовать пароль, если ключ был отклонен?

14

Мои новые экземпляры сервера настроены для входа в систему с правами root через ssh с паролем. Я хочу, чтобы моя книга воспроизведения Ansible реконфигурировала его, вместо этого использовала ключи и отключила root-логин с паролем при первом запуске, поэтому мне нужно что-то вроде этого:

  • попробуйте войти с ключом
  • если не могу войти с ключом:

    • войти с паролем
    • добавить ключ для авторизованных ключей
    • отключить root-логин с паролем
    • по желанию переподключиться с помощью ключа
  • делать другие задачи

Как я могу это сделать?

РЕДАКТИРОВАТЬ : Чтобы было ясно, я не спрашиваю, как добавить ключ или отключить root, это только для контекста. Я спрашиваю, как вернуться к паролю, если он не может аутентифицироваться с ключом. С --ask-passили ansible_ssh_passустановлен, Ansible даже не будет пытаться использовать аутентификацию с открытым ключом

petr0
источник
Хороший вопрос, что вы пробовали до сих пор?
Дауд
1
Я перенес конфигурацию ssh в отдельный playbook и запускаю ее с опцией -k, затем запускаю основной playbook без -k (используя ключ от агента). Я надеялся, что это может быть обернуто в одну книгу, хотя ...
petr0
@ petr0 Это работает для меня, когда пароль Ask-Pass предназначен для пользователя, отличного от ключа (т. е. когда вы переключаете удаленного пользователя после отключения пароля SSH). Не уверен, что это поможет.
DylanYoung

Ответы:

6

Вы можете попробовать PreferredAuthenticationsвариант, установив его на publickey,password. Значение по умолчанию включает их в этом порядке, наряду с другими параметрами, так что ansible, вероятно, устанавливает это. Добавление через -oили клиент ssh_configможет предотвратить это.

Вы можете использовать скрипт-обертку. Например, при этом в key_or_password.shи a, pass.shкоторый дает пароль, во время работы bash key_or_password.sh root@hostбудет пытаться использовать публичный ключ, за которым следует неинтерактивный вход в систему с паролем.

export DISPLAY=dummy:0
export SSH_ASKPASS=$PWD/pass.sh
exec setsid ssh -v -o 'PreferredAuthentications publickey,password' "$@"

В журнале указывается, какой метод был успешным, например,

debug1: Authentication succeeded (publickey).
eisd
источник
7

Вот что я делаю, если ansible_userотличается для «первого запуска» playbook (например, если у вас есть только rootпользователь, и вы собираетесь настроить нового пользователя с ключом SSH):

  • Сохраните пароль, ansible_passкак если бы вы использовали пароли для входа (не забудьте использовать Vault), это должен быть пароль пользователя, которого вы используете для «первого запуска» книги.
  • Задайте ansible_userимя пользователя, которого вы хотите использовать после первого запуска, когда пользователи правильно настроены на сервере.
  • ansible_user_first_runНапример, установите переменную для пользователя, которого вы собираетесь использовать для «первого запуска» книги root.
  • Используйте локальную команду, чтобы попытаться подключиться к серверу с правильным ключом SSH, используя ignore_errorsиchanged_when: False
  • Если это не удается, обновите ansible_userзначениеansible_user_first_run

Вот код:

---
- name: Check if connection is possible
  command: ssh -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ inventory_hostname }} echo "Worked"
  register: result
  connection: local
  ignore_errors: yes
  changed_when: False
- name: If no connection, change user_name
  connection: local
  set_fact:
    ansible_user: "{{ ansible_user_first_run }}"
  when: result|failed

Примечание: стоит установить, так transport = sshкак paramiko может неожиданно не войти в систему на сервере в некоторых конфигурациях (например, когда сервер настроен так, чтобы не принимать пароли, и вы сначала пытаетесь ввести ключ, а затем пароль ... странно!) Кроме того, SSH транспорт быстрее, так что оно того стоит.

Примечание: если вы используете этот метод, вам нужно указать gather_facts: falseв файле определения playbook, чтобы задачи по сбору / установке фактов не запускались автоматически до того, как вы приступите к тестированию паролей. Если вам нужен какой-либо из возможных фактов, вам необходимо явно вызвать setupсвою роль, прежде чем получить доступ к любым данным, обычно доступным в таких местах, как ansible_devices, и т. Д. Один из хороших способов сделать это - вызвать setupс помощью whenпункта, который проверяет, является ли факт, который вы используете, пуст или нет, прежде чем вы называете его в своей роли.

Том Булл
источник
Ваше решение хорошо, но вы должны добавить a, gather_facts: noчтобы прекратить пытаться подключиться при запуске playbook :)
k4cy
Ты прав. У меня для всех моих сборников play_facts установлено значение off, поэтому мне нужно явно вызывать «setup». Я забыл упомянуть об этом в ответе, сейчас обновлю.
Том Булл
5

Вы можете использовать --ask-passпри запуске ansible-playbook.

Для других заданий, которые вы задали, это возможно различными способами, например, с помощью модуля копирования.
Отключение входа в систему root также может быть сделано, например. шаблонизируя sshd_confили вставляя строку в файл conf.

Titus
источник
--ask-pass (то же самое, что и -k) - это то, что я делаю, и я написал об этом в комментарии выше
petr0