Найти тему
Немного из мира ИБ

Ansible SSH аутентификация и повышение привилегий.

Оглавление

В этой статье мы сосредоточимся на двух важных концепциях 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

Теперь вы должны хорошо понимать, как работает аутентификация на основе ключей в ansible.Важно понимать приоритет при добавлении параметра в различные файлы.Параметр командной строки имеет больший приоритет, за ним следует файл инвентори и файл конфигурации ansible.cfg.Аутентификация на основе пароля SSH в Ansible

Когда вы запускаете любую задачу, Ansible будет использовать текущего пользователя на ноде контроллера для связи с управляемыми нодами по SSH.Вы можете использовать модуль shell и выполнить команду “whoami” для проверки имени пользователя на управляемых нодах.В моем случае имя пользователя – “vagrant”.Пользователь vagrant проходит аутентификацию с помощью ключей, которые я настроил в предыдущем разделе.$ whoami vagrant

$ ansible all -m shell -a "whoami" managed2 | CHANGED | rc=0 >> vagrant managed1 | CHANGED | rc=0 >> vagrant

Если вы хотите подключиться к управляемым нодам под другим пользователем, вы можете использовать флаг –u или –user и передать имя пользователя в качестве аргумента.Я пытаюсь использовать пользователя “karthick”, у которого не настроен SSH-ключ и ключи не распределены по управляемым узлам, поэтому подключение не происходит.$ ansible all -m shell -a "whoami" -u karthick $ ansible all -m shell -a "whoami" --user karthick

Чтобы использовать аутентификацию на основе пароля, можно использовать флаг -k или –ask-pass.Будет предложено ввести пароль SSH для пользователя (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

Пароль Sudo может храниться в файле и передаваться в качестве аргумента для флага –become-password-file или –become-pass-file.Для шифрования этого файла можно использовать Ansible vault, но это не рекомендуется.$ 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

Директива “become” также может быть установлена в конфигурационном файле ansible.cfg и в файле инвентари.Но рекомендуется устанавливать директиву в плейбуке.Заключение

  • В этой статье мы рассмотрели, как работает аутентификация на основе ключа и пароля в Ansible, а также различные флаги, поддерживаемые для аутентификации.Мы также рассмотрели, как работает эскалация привилегий в Ansible