В этой статье мы сосредоточимся на двух важных концепциях Ansible.
Первая концепция заключается в том, как в Ansible работает аутентификация на основе ключей SSH и паролей.
Вторая концепция – как повысить привилегии при работе со специальными командами и плейбуками.
Аутентификация на основе ключей в Ansible
Первое, что вы должны понять при изучении Ansible, это то, как происходит обмен данными между контроллером и управляемыми нодами.
Ansible использует протокол SSH для подключения к управляемым нодам и выполнения задач.
Каждый раз, когда вы запускаете playbook или специальные команды, вам необходимо указать пароль SSH, чтобы Ansible мог аутентифицироваться на управляемых нодах по SSH.
Чтобы избежать этого, рекомендуется создать пару ключей SSH и поделиться открытым ключом со всеми узлами, чтобы ansible мог взаимодействовать с помощью пары ключей.
Я создал две пары ключей с именами first_key и second_key с помощью приведенного ниже скрипта для демонстрации.
#!/usr/bin/env bash # THIS SCRIPT WILL CREATE SSH KEY PAIR AND DISTRIBUTE ACROSS ALL NODES read -p "Enter the name for the key : " KEY_NAME ssh-keygen -b 2048 -t rsa -f /home/vagrant/.ssh/${KEY_NAME} -q -N "" # LOOPING THROUGH AND DISTRIBUTING THE KEY for val in controller managed1 managed2; do echo "-------------------- COPYING KEY TO ${val^^} NODE ------------------------------" sshpass -p 'vagrant' ssh-copy-id -f -i /home/vagrant/.ssh/${KEY_NAME}.pub -o "StrictHostKeyChecking=no" vagrant@$val done
Дайте разрешение на выполнение скрипту и запустите его.
$ chmod +x path/to/create_keypair.sh
$ ./create_keypair.sh
Вы можете отредактировать раздел цикла for и добавить имена управляемых нод соответствующим образом.
$ tree .ssh/ .ssh/ ├── authorized_keys ├── first_key ├── first_key.pub ├── known_hosts ├── second_key └── second_key.pub
Если у вас созданы ключи с именами, отличными от имени по умолчанию (id_rsa), ssh попытается найти имена ключей по умолчанию и, если не найдет, запросит аутентификацию на основе пароля.
debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey,password debug1: Next authentication method: publickey debug1: Trying private key: /home/vagrant/.ssh/id_rsa debug1: Trying private key: /home/vagrant/.ssh/id_dsa debug1: Trying private key: /home/vagrant/.ssh/id_ecdsa debug1: Trying private key: /home/vagrant/.ssh/id_ecdsa_sk debug1: Trying private key: /home/vagrant/.ssh/id_ed25519 debug1: Trying private key: /home/vagrant/.ssh/id_ed25519_sk debug1: Trying private key: /home/vagrant/.ssh/id_xmss debug1: Next authentication method: password vagrant@managed1's password:
В этом случае необходимо явно указать файл закрытого ключа с помощью флага -i.
$ ssh -v -i /home/vagrant/.ssh/first_key vagrant@managed1
Когда вы запускаете специальную команду или playbook, вы можете использовать флаг –key-file или –private-key и передать файл закрытого ключа в качестве аргумента.
В приведенном ниже примере видно, что я использовал оба ключа (first_key & second_key) для успешной связи с управляемыми узлами.
# USING --key-file FLAG $ ansible managed1 -m ping --key-file /home/vagrant/.ssh/second_key managed1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" }
# USING --private-key FLAG $ ansible managed1 -m ping --private-key /home/vagrant/.ssh/first_key managed1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" }
Вы также можете добавить параметр “private_key_file” в конфигурационный файл ansible.cfg, который будет применяться к adhoc-командам и всем задачам playbook.
$ vim ansible.cfg
Добавьте следующую строку:
Private_key_file = /home/vagrant/.ssh/first_key
Замените /home/vagrant/.ssh/first_key на свой собственный.
Вы также можете добавить параметр “ansible_ssh_private_key” в файл inventory, который будет иметь больший приоритет над файлом ansible.cfg.
Ниже показано, как настроен мой инвентари.
Нода managed1 будет использовать “first_key”, а managed2 – “second_key”.
[ubuntu1] managed1 ansible_ssh_private_key_file=/home/vagrant/.ssh/first_key [ubuntu2] managed2 ansible_ssh_private_key_file=/home/vagrant/.ssh/second_key
Теперь, если вы снова запустите команду adhoc или playbook, вы увидите, что оба ключа успешно пройдут аутентификацию.
Вы можете увеличить сложность, чтобы проверить, используются ли соответствующие ключи в соответствии с нашими данными.
$ ansible -vvv all -m ping
Аутентификация на основе пароля SSH в Ansible
$ whoami vagrant
$ ansible all -m shell -a "whoami" managed2 | CHANGED | rc=0 >> vagrant managed1 | CHANGED | rc=0 >> vagrant
$ ansible all -m shell -a "whoami" -u karthick $ ansible all -m shell -a "whoami" --user karthick
$ ansible all -m shell -a "whoami" -u karthick -k $ ansible all -m shell -a "whoami" -u karthick --ask-pass
Вы также можете хранить пароль в файле и передавать имя файла в качестве аргумента для флага –connection-password-file или –conn-pass-file.
Этот способ не рекомендуется, поскольку вы храните пароль в обычном текстовом файле.
Вы можете использовать ansible vault для шифрования файла паролей, но это отдельная тема для обсуждения.
🔐 Как использовать Ansible Vault в плейбуках для защиты конфиденциальных данных $ ansible all -m shell -a "whoami" -u karthick --connection-password-file pass.txt $ ansible all -m shell -a "whoami" -u karthick --conn-pass-file pass.txt
Вы также можете передать имя пользователя и пароль в качестве параметров в файле инвентари.
Опять же, это не лучший способ хранения пароля.
Ниже показано, как настроен мой файл инвентари.
[ubuntu1] managed1 ansible_ssh_private_key_file=/home/vagrant/.ssh/first_key ansible_user=vagrant [ubuntu2] managed2 ansible_user=karthick ansible_ssh_pass=password
$ ansible all -m shell -a "whoami" -u karthick managed1 | CHANGED | rc=0 >> vagrant managed2 | CHANGED | rc=0 >> karthick
Повышение привилегий в Ansible
Бывают случаи, когда для успешного выполнения задачи требуется повышенная привилегия (root). Например, управление пакетами.
Вы можете устанавливать, удалять или обновлять пакеты только от имени пользователя root или с привилегиями sudo.
Если вы запустите флаг help вместе с ansible или ansible-playbook, вы найдете раздел об эскалации привилегий, как показано на рисунке.
$ ansible --help $ ansible-playbook --help
Если вы хотите запустить какое-либо задание с привилегиями root, вам следует использовать флаг -b или –become.
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -b managed1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "name": "sshd", "state": "started",
По умолчанию в качестве метода эскалации привилегий будет использоваться sudo.
Вы можете изменить метод, установив флаг –become-method.
Список поддерживаемых методов можно получить, выполнив следующую команду.
$ ansible-doc -t become -l ansible.netcommon.enable Switch to elevated permissions on a network device community.general.doas Do As user community.general.dzdo Centrify's Direct Authorize community.general.ksu Kerberos substitute user community.general.machinectl Systemd's machinectl privilege escalation community.general.pbrun PowerBroker run community.general.pfexec profile based execution community.general.pmrun Privilege Manager run community.general.sesu CA Privileged Access Manager community.general.sudosu Run tasks using sudo su - runas Run As user su Substitute User sudo Substitute User DO
Вы можете задать или не задавать пароль sudo для управляемых нод в зависимости от того, как настроен пользователь.
В моем случае я настроил пользователя vagrant для запуска sudo без запроса пароля.
Если ваш пользователь sudo требует пароль для работы, то вам следует использовать флаг -K или –ask-become-pass, который запросит пароль sudo.
Как видно из приведенной ниже ошибки, когда я пытаюсь запустить sudo без указания пароля sudo для пользователя “karthick”, выдает ошибку “Missing sudo password”.
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b SSH password: managed1 | FAILED! => { "msg": "Missing sudo password" }
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b -K
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b --become-password-file pass.txt $ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b --become-pass-file pass.txt
Вы также можете включить директиву “become” в плейбук.
Как видно из вывода, служба ssh перезапущена нормально на ноде managed1.
$ ansible-playbook restart_service.yml PLAY [Restart SSHD service] *************************************************************************** TASK [Restart SSHD in managed1.anslab.com] ************************************************************ changed: [managed1] PLAY RECAP ******************************************************************************************** managed1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Заключение
- 🔐 Создание самоподписанных сертификатов OpenSSL с помощью Ansible
- 📜 Как использовать Ansible Lint для сканирования плейбуков
- 📜 Управление пользователями и группами в Linux с помощью Ansible
- 🐧 Как временно остановить демон Auditd с Ansible
- 📜 Как создать зашифрованный пароль пользователя Linux для Ansible
- 🔐 Как использовать Ansible Vault в плейбуках для защиты конфиденциальных данных