Обратите внимание, что 403 ошибки обычно происходят из-за неправильно сконфигурированных полномочий файла/каталога. Apache пытается загружать/служить файл, но не может считать его. Посмотрите здесь для хорошего списка других вещей проверить связанный с 403.
Вы можете попробовать опцию PreferredAuthentication
, установив для нее значение публичный ключ, пароль
. По умолчанию они включаются в этом порядке вместе с другими параметрами, поэтому вероятно, что ansible устанавливает это. Добавление с помощью -o
или клиента ssh_config
может предотвратить это.
Вы можете использовать сценарий оболочки. Например, с этим в key_or_password.sh
и 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).
You can use --ask-pass
when running ansible-playbook.
For other tasks you asked, it is achievable by various means, eg, copy module.
Отключение входа в систему root также может быть выполнено, например. путем создания шаблона sshd_conf
или вставки строки в файл conf.
Вот что я делаю, если ansible_user
отличается для «первого запуска» playbook (например, если у вас есть только пользователь root
и вы собираетесь создать нового пользователя с ключом SSH):
ansible_pass
, как если бы вы использовали парольные логины (не забудьте использовать Vault), это должен быть пароль пользователя, которого вы используете для «первого запуска» playbook. ansible_user
имя пользователя, которого вы хотите использовать после первого запуска, если пользователи правильно настроены на сервере. ansible_user_first_run
пользователю, которого вы собираетесь использовать для «первого запуска» playbook, например root
. 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
, которое проверяет, является ли используемый вами факт пустым, прежде чем вы вызовете его в своей роли.
Недавно я реализовал вариант ответа, данного выше Тома Булла, который работает для нескольких хостов, последовательно проверяя доступ и запрашивая учетные данные, если это необходимо, а затем выполняя задачи. чтобы завершить настройку (например, добавить авторизованные ключи или настроить пользователя для Ansible):
playbook.yaml
:
# Checking access to hosts must run sequentially
- hosts: all
gather_facts: no
serial: 1
tasks:
- include_tasks: check-access.yaml
# Subsequent tasks can run in parallel as usual
- hosts: all
tasks:
- include_tasks: setup-tasks.yaml
check-access.yaml
:
- name: check ansible user exists
command: ssh -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ ansible_host }} echo "Worked"
register: remote
connection: local
ignore_errors: yes
become: false
changed_when: False
- name: collect credentials
block:
- name: collect username
pause:
prompt: "Username for {{ inventory_hostname }} ({{ ansible_host }})"
echo: yes
register: username_result
- name: collect password
pause:
prompt: "Password for {{ username_result.user_input }}"
echo: no
register: password_result
- name: update ansible credentials
set_fact:
ansible_user: "{{ username_result.user_input }}"
ansible_password: "{{ password_result.user_input }}"
ansible_become_password: "{{ password_result.user_input }}"
when: remote.failed
setup-tasks.yaml
затем будет запущен на всех хостах и может включать любые задачи, необходимые для обеспечения успешной начальной проверки доступа при следующем запуске playbook.yaml
.
Хотя сохранение задач check-access.yaml
в отдельном файле облегчает чтение основного сборника, возможно, можно перенести их в основной сборник, однако я этого не пробовал. нельзя быть уверенным, что они будут выполняться в правильном порядке.
Обратите внимание, что эти задачи нельзя поместить в роль, так как подсказка
работает только внутри задач