Поиск по сайту:

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

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

У меня есть трехузловая лабораторная установка, на которой работают машины Ubuntu 20.04 LTS с использованием VirtualBox и Vagrant. Подробную статью о настройке лаборатории вы можете прочитать по ссылке ниже.

  • Автоматическая установка Ansible Lab с Vagrant и Virtualbox в Linux

Аутентификация на основе ключей в Ansible

Первое, что вам нужно понять при изучении ansible, — это то, как происходит связь между контроллером и управляемыми узлами. Ansible использует протокол SSH для подключения к управляемым узлам и выполнения задачи.

Каждый раз, когда вы запускаете playbook или специальные команды, вам необходимо предоставить пароль SSH для аутентификации ansible на управляемых узлах через SSH.

Чтобы избежать этого, рекомендуется создать пару ключей SSH и поделиться открытым ключом со всеми узлами, чтобы ansible мог взаимодействовать с использованием пары ключей.

Я создал две пары ключей с именами first_key и Second_key, используя для демонстрации приведенный ниже скрипт.

Создайте текстовый файл с именем create_keypair.sh со следующим содержимым.

#!/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

Когда вы запускаете специальную команду или книгу воспроизведения, вы можете использовать флаг --key-file или --private-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, который будет применяться к специальным командам и всем задачам playbook.

vim ansible.cfg

Добавьте следующую строку:

Private_key_file = /home/vagrant/.ssh/first_key

Замените /home/vagrant/.ssh/first_key своим собственным.

Файл закрытого ключа

Вы также можете добавить параметр "ansible_ssh_private_key" в файл инвентаря, который будет иметь более высокий приоритет по сравнению с файлом 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. Вы можете использовать модуль оболочки и запустить команду «whoami», чтобы проверить имя пользователя на управляемых узлах. В моем случае имя пользователя — "бродяга". Бродячий пользователь проходит аутентификацию с использованием ключей, которые я настроил в предыдущем разделе.

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

Запрос пароля SSH

Вы также можете сохранить пароль в файле и передать имя файла в качестве аргумента флагу --connection-password-file или --conn-pass-file. Это не рекомендуемый способ, поскольку вы храните пароль в текстовом файле. Вы можете использовать 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.

Когда вы запустите флаг справки вместе с 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 для пользователя «karthick», мне выдается сообщение об ошибке «Отсутствует пароль sudo» . .

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

Используйте флаг -K для запроса пароля Sudo

Пароль 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 в книгу сценариев на уровне задачи или уровне игры.

На изображении ниже показано, как директива become используется на уровне игры.

Директива «стать» на игровом уровне

На изображении ниже показано, как директива become используется на уровне задачи.

Директива 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 и файле инвентаризации. Но рекомендуется установить директиву в playbook. Вы можете получить различные параметры для файла ansible.cfg по ссылке ниже.

  • Стать директивой

Если вы хотите запустить задачу от имени другого пользователя после подключения к управляемым узлам, вам следует использовать флаг --become-user. По умолчанию это пользователь root.

Заключение

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

Чтобы углубиться в процесс, вы должны иметь четкое представление о том, как работают различные методы повышения привилегий, и в соответствии с вашими потребностями настраивать среду без ущерба для безопасности.

Читать далее:

  • Начало работы с специальными командами Ansible

Статьи по данной тематике