Подключение через SSH Proxy
Indeed PAM поддерживает подключение Ansible к ресурсам через прокси-сервер. При таком сценарии Ansible подключается к компоненту SSH Proxy, который предоставляет доступ к ресурсам по протоколам SSH, SCP и SFTP.
Компонент SSH Proxy контролирует доступ к ресурсу, устанавливает соединение от имени указанной учетной записи и записывает все действия пользователя в журналы События, Активные сессии и Все сессии.
В сценарии работы Ansible через SSH Proxy не поддерживается двухфакторная аутентификация. Рекомендуется использовать отдельную учетную запись с настроенной аутентификацией по SSH-ключам.
Требования
Для работы Ansible через SSH Proxy требуется:
- Ansible 2.14 и выше — установите компонент на хосте, с которого выполняется подключение к SSH Proxy
- Доступ к компоненту Indeed PAM SSH Proxy
- Учетная запись Indeed PAM с доступом к SSH-ресурсу
- AAPM-лицензия, если используется Ansible Lookup Plugin
Настройка подключения
Чтобы настроить подключение из Ansible-плейбука через SSH Proxy:
Сформируйте строку подключения к SSH Proxy в кодировке UTF-8 по шаблону:
<pam_user>#<resource_address>#<account_name>#[reason]pam_user— имя пользователя Indeed PAM для аутентификации в SSH Proxyresource_address— IP-адрес или DNS-имя целевого ресурсаaccount_name— имя учетной записи, от имени которой пользователь подключается к целевому ресурсуreason— причина подключения к ресурсу, если ее требуется указать согласно политике
Пример:
pam.admin#192.168.0.100#PAM.LOCAL\pam-admin#ОбслуживаниеПример без указания причины:
pam.admin#192.168.0.100#PAM.LOCAL\pam-admin##Настройте конфигурацию Ansible для подключения к Indeed PAM в одном из файлов:
Ansible-плейбук — укажите параметры в секции
vars.Конфигурационный файл inventory.yml — укажите параметры в секции
hosts.Параметры конфигурации
Параметр Требование Описание ansible_hostОбязательный DNS-имя или IP-адрес компонента SSH Proxy ansible_portОбязательный Порт компонента SSH Proxy.
Порт по умолчанию:2222.ansible_userОбязательный Строка подключения к SSH Proxy.
Пример:pam.admin#10.0.0.1#DOMAIN\admin.ansible_passwordНеобязательный Пароль пользователя PAM. Укажите, если настроена аутентификация по паролю. Рекомендуется шифровать пароль с помощью Ansible Vault. ansible_ssh_private_key_fileНеобязательный Путь к SSH-ключу пользователя PAM. Укажите, если настроена аутентификация по SSH-ключу.
Пример:/home/user/.ssh/id_rsa.ansible_ssh_retriesНеобязательный Количество повторных попыток подключения. Укажите, чтобы подключиться заново после разрыва соединения или закрытия сессии в консоли администратора Indeed PAM. ansible_ssh_extra_argsНеобязательный Позволяет передавать дополнительные аргументы командной строки SSH-клиенту. Используйте для настройки SCP- и SFTP-подключений. Примеры
- Ansible-плейбук
- inventory.yml
- name: Выполнить команду через PAM SSH Proxy
hosts: all
gather_facts: false
vars:
ansible_host: "pam.company.com"
ansible_port: 2222
ansible_user: "pam.admin#192.168.0.100#DOMAIN\\admin"
ansible_password: "{{ pam_password }}"
tasks:
- name: Получить информацию о системе
ansible.builtin.raw: uname -a
register: result
changed_when: false
- name: Показать результат
ansible.builtin.debug:
msg: "{{ result.stdout | trim }}"Один ресурс---
all:
hosts:
target_server:
ansible_host: pam.company.com
ansible_port: 2222
ansible_user: "pam.admin#192.168.0.100#DOMAIN\\admin"
ansible_password: "{{ vault_pam_password }}"Несколько ресурсов---
all:
vars:
ansible_port: 2222
ansible_host: pam.company.com
ansible_password: "{{ vault_pam_password }}"
hosts:
web_server:
ansible_user: "pam.admin#10.11.5.10#DOMAIN\\web-admin"
db_server:
ansible_user: "pam.admin#10.11.5.20#DOMAIN\\db-admin"
app_server:
ansible_user: "pam.admin#190.160.1.100#LINUX-SERVER\\db-admin#Обслуживание"
Запуск сценария
Чтобы запустить сессию, откройте терминал и выполните команду для подключения к ресурсу
ansible-playbook <playbook> [-i <inventory>] [-e <variable>]
playbook— название Ansible-плейбукаinventory— имя конфигурационного файла с настройками подключенияvariable— имя переменной окружения
Примеры команд запуска
ansible-playbook playbook.yml
ansible-playbook playbook.yml -i inventory.yml
ansible-playbook playbook.yml -i inventory.yml -e "pam_password=${PAM_PASSWORD}"
Использование Ansible Vault
Рекомендуется шифровать учетные с помощью компонента Ansible Vault, а не хранить их в открытом виде.
Чтобы зашифровать пароль пользователя PAM:
Откройте терминал и выполните команду:
ansible-vault encrypt_string --ask-vault-pass '<password>' --name '<variable>'password— пароль пользователя Indeed PAM, который нужно зашифроватьvariable— имя переменной для шифрования
Введите пароль, который используется для расшифровки переменной при запуске плейбука.
В результате в терминале отобразится зашифрованная переменная.Создайте файл в формате YAML или JSON и сохраните в него результат команды.
- YAML
- JSON
vault_pam_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31643864386664376639656162346664313937633035346638656139376138656163376638656164
6337663961383964666137633930626439656637666137660a31323334353637383930616263646566
30313233343536373839616263646566303132333435363738396162636465660a6162636465663132{
"vault_pam_password": "$ANSIBLE_VAULT;1.1;AES256\n31643864386664376639656162346664313937633035346638656139376138656163376638656164\n6337663961383964666137633930626439656637666137660a31323334353637383930616263646566\n30313233343536373839616263646566303132333435363738396162636465660a6162636465663132"
}Укажите параметры переменной в плейбуке:
vars_files— путь к файлу, в котором хранится зашифрованная переменнаяpassword— имя переменной
Пример
---
- name: Выполнить команду через PAM SSH Proxy с использованием Ansible Vault
hosts: all
gather_facts: false
vars_files:
- ./vault.yml
vars:
ansible_host: "pam.company.com"
ansible_port: 2222
ansible_user: "pam.admin#192.168.0.100#PAM.LOCAL\\pam-admin"
ansible_password: "{{ vault_pam_password }}"
tasks:
- name: Проверить подключение
ansible.builtin.raw: id
register: result
changed_when: false
no_log: trueЗапустите плейбук с параметров
--ask-vault-pass, чтобы Ansible запросил пароль для расшифровки переменной:Если настройки подключения указаны в плейбукеansible-playbook playbook.yml --ask-vault-passЕсли настройки подключения указаны в файле inventory.ymlansible-playbook playbook.yml -i inventory.yml --ask-vault-pass
Передача файлов по SCP и SFTP
С хоста, на котором запущен плейбук, можно передать файлы на SSH-ресурс по следующим протоколам:
- SCP — для быстрой передачи одного файла на ресурс.
- SFTP — для CI/CD-автоматизаций или передачи нескольких файлов на ресурс.
При передаче файла используйте модуль ansible.builtin.shell и утилиту sshpass.
Модуль ansible.builtin.copy не подходит для передачи файлов через SSH Proxy. Модуль на ресурсе создает временную директорию и загружает туда файл, перемещает файл из временной директории в целевую, назначает права доступа и удаляет временную директорию. Для этого требуется отдельный канал связи, но SSH Proxy разрешает только передачу файлов по SCP и SFTP и завершает сессию сразу после того, как файл передан.
Предварительные настройки
В консоли администратора Indeed PAM выполните следующие действия:
- Перейдите в раздел Политики и нажмите на нужную политику.
- Перейдите в подраздел SSH → Передача данных.
- Для протоколов SCP и SFTP выберите опцию Разрешена только на ресурс или Разрешена в обоих направлениях.
- Нажмите Сохранить.
Настройка хоста
На хосте, с которого планируется подключение к SSH-ресурсу, выполните следующие действия:
Установите утилиту sshpass, которая позволяет автоматически заполнять пароль для SSH-подключения.
- RPM
- DEB
sudo dnf install sshpasssudo apt install sshpassНастройте конфигурацию для подключения к SSH-ресурсу одним из способов:
Укажите параметры в файле ssh_config и передайте путь к файлу в переменной
ansible_ssh_extra_args— рекомендуемый способ. Настройка в этом файле позволит не экранировать содержимое строки подключения.Укажите параметры напрямую в
ansible_ssh_extra_argsв файле inventory.yml или Ansible-плейбуке.Экранирование специальных символовСтрока подключения к SSH Proxy содержит спецсимволы
#и\— их необходимо экранировать. При настройке конфигурации в YML-файле указывайте строку подключения в одинарных кавычках.При подстановке переменных в команду, например
src_fileилиansible_user, используйте фильтрquote, чтобы обработать пробелы и спецсимволы.Параметры
Параметр ОписаниеHostNameDNS-имя или IP-адрес компонента SSH Proxy.
Можно указать в параметреansible_hostв inventory.yml или плейбуке.PortПорт компонента SSH Proxy. Порт по умолчанию: 2222.
Можно указать в параметреansible_hostв inventory.yml или плейбуке.UserСтрока подключения к SSH Proxy.
Пример:pamadmin@pam.local#ssh-host.example.com#RESOURCE\user##.
Можно указать в параметреansible_userв inventory.yml или плейбуке.PreferredAuthenticationsПорядок методов аутентификации, которые используются при подключении к прокси-серверу. Возможные значения: keyboard-interactive— интерактивная аутентификация (запрос-ответ)password— аутентификация по паролюpublickey— аутентификация по SSH-ключам
publickey,keyboard-interactive— сначала проверяется SSH-ключ, и, если он не подошел, сервер запросит пароль.KbdInteractiveAuthenticationРазрешить интерактивную аутентификацию методом keyboard-interactive. Возможные значения:truefalse
PubkeyAuthenticationРазрешить вход по SSH-ключам. Возможные значения: truefalse
NumberOfPasswordPromptsКоличество попыток ввода пароля. При превышении количества попыток соединение с прокси-сервером разрывается. UserKnownHostsFileПуть к файлу known_hosts StrictHostKeyCheckingПроверка SSH-ключа сервера: yes— строгая проверка. Если ключ сервера не найден в файле known_hosts или не совпадает с сохраненным для этого хоста, подключение прерывается с ошибкой.no— проверка отключена. Если ключа нет в файле known_hosts, он автоматически добавляется.accept-new— проверка только для новых хостов. Если ключа нет в файле known_hosts, он автоматически добавляется, и соединение устанавливается. Если указанный ключ не совпадает с ключом в known_hosts, соединение разрывается.
ConnectTimeoutВремя ожидания ответа (в секундах) на установку TCP-соединения с сервером Примеры
- inventory.yml
- ansible.cfg
- Ansible-плейбук
Параметры заданы в inventory.ymlall:
hosts:
pam_target:
ansible_connection: ssh
ansible_host: pam.example.com
ansible_port: 2222
ansible_user: 'pamadmin@pam.local#ssh-host.example.com#RESOURCE\pam-user##'
ansible_password: "{{ vault_pam_password }}"
ansible_ssh_extra_args: >-
-tt
-o PreferredAuthentications=keyboard-interactive,password
-o KbdInteractiveAuthentication=yes
-o PubkeyAuthentication=no
-o NumberOfPasswordPrompts=1
-o StrictHostKeyChecking=yes
-o UserKnownHostsFile=./known_hosts
-o ConnectTimeout=10В inventory.yml указан путь к ssh_configall:
hosts:
pam_target:
ansible_connection: ssh
ansible_password: "{{ vault_pam_password }}"
ansible_ssh_extra_args: '-tt -F ./ssh_config'В ansible.cfg указан путь к ssh_config[defaults]
inventory = ./inventory.yml
[ssh_connection]
pipelining = False
ssh_args = -F ./ssh_configПараметры указаны в плейбуке- block:
- name: Передача файла через SSH Proxy по протоколу SFTP
delegate_to: localhost
environment:
SSHPASS: "{{ ansible_password }}"
ansible.builtin.shell: >-
sshpass -e sftp
-P {{ ansible_port }}
-o PreferredAuthentications=keyboard-interactive,password
-o KbdInteractiveAuthentication=yes
-o PubkeyAuthentication=no
-o NumberOfPasswordPrompts=1
-o StrictHostKeyChecking=accept-new
-o UserKnownHostsFile=./known_hosts
-o ConnectTimeout=10
-o BatchMode=no
-b {{ sftp_batch_file.path | quote }}
{{ ansible_user | quote }}@{{ ansible_host }}
register: sftp_result
no_log: trueВ плейбуке указан путь к ssh_configansible.builtin.shell: >-
sshpass -e sftp
-F ./ssh_config
-o BatchMode=no
-b {{ sftp_batch_file.path | quote }}
{{ inventory_hostname }}Пример файла ssh_configHost pam_target
HostName pam.example.com
Port 2222
User pamadmin@pam.local#ssh-host.example.com#RESOURCE\pam-user##
PreferredAuthentications keyboard-interactive,password
KbdInteractiveAuthentication yes
PubkeyAuthentication no
NumberOfPasswordPrompts 1
UserKnownHostsFile ./known_hosts
StrictHostKeyChecking yes
ConnectTimeout 10
Добавьте открытый ключ компонента SSH Proxy в файл known_hosts.
ПредупреждениеЭтот шаг обязателен, если для параметра
StrictHostKeyCheckingуказаноyes. Если не записать отпечаток прокси-сервера перед первым запуском, плейбук завершится с ошибкой.ssh-keyscan [-p <port>] <host> >> ./known_hostsport— порт компонента SSH Proxyhost— DNS-имя или IP-адрес компонента SSH Proxy
Чтобы подтвердить отпечаток, в терминале введите
yes.Запустите плейбук и передайте файлы с хоста на SSH-ресурс по выбранному протоколу.
ansible-playbook <playbook> \
-e src_file=<source_path> \
-e dest_dir=<destination_dir> \
--ask-vault-passplaybook— название Ansible-плейбукаsource_path— путь к файлу, который требуется передать с хоста на целевой ресурсdest_dir— директория, куда передается файл с хостаask-vault-pass— запрос пароля для расшифровки переменных в плейбуке
Пример плейбука
- SCP
- SFTP
---
- name: Передача файла через SSH Proxy по протоколу SCP
hosts: all
gather_facts: false
vars:
src_file: /tmp/file.txt
dest_dir: /home/user
dest_file: "{{ dest_dir }}/{{ src_file | basename }}"
tasks:
- name: Передача файла через SSH Proxy по протоколу SCP
delegate_to: localhost
environment:
SSHPASS: "{{ ansible_password }}"
ansible.builtin.shell: >-
sshpass -e scp
-F ./ssh_config
-O
{{ src_file | quote }}
{{ inventory_hostname }}:{{ dest_file | quote }}
register: scp_result
failed_when: false
- name: Verify file exists on target
ansible.builtin.raw: "test -f {{ dest_file | quote }} && echo OK"
register: verify_result
changed_when: false
failed_when: "'OK' not in verify_result.stdout"---
- name: Передача файла через SSH Proxy по протоколу SFTP
hosts: all
gather_facts: false
vars:
src_file: /tmp/file.txt
dest_dir: /home/user
dest_file: "{{ dest_dir }}/{{ src_file | basename }}"
tasks:
- name: Create temporary batch file
delegate_to: localhost
ansible.builtin.tempfile:
state: file
suffix: .sftp
register: sftp_batch_file
- name: Write SFTP batch commands
delegate_to: localhost
ansible.builtin.copy:
dest: "{{ sftp_batch_file.path }}"
content: "put {{ src_file }} {{ dest_file }}\n"
- block:
- name: Передача файла через SSH Proxy по протоколу SFTP
delegate_to: localhost
environment:
SSHPASS: "{{ ansible_password }}"
ansible.builtin.shell: >-
sshpass -e sftp
-F ./ssh_config
-o BatchMode=no
-b {{ sftp_batch_file.path | quote }}
{{ inventory_hostname }}
register: sftp_result
no_log: true
- name: Verify file exists on target
ansible.builtin.raw: "test -f {{ dest_file | quote }} && echo OK"
register: verify_result
changed_when: false
failed_when: "'OK' not in verify_result.stdout"
always:
- name: Remove temporary batch file
delegate_to: localhost
ansible.builtin.file:
path: "{{ sftp_batch_file.path }}"
state: absent
Рекомендации по безопасности
Для аутентификации сервера и поддержки сценариев автоматизации перед первым подключением к PAM добавьте открытый ключ
компонента SSH Proxy в файл known_hosts:ssh-keyscan [-p <port>] <host> >> ~/.ssh/known_hostsport— порт компонента SSH Proxyhost— DNS-имя или IP-адрес компонента SSH Proxy
предупреждениеУбедитесь в подлинности открытого ключа: команда
ssh-keyscanиспользует механизм Trust on first use (TOFU), при котором ключ добавляется без проверки.При настройке подключения включите проверку открытого ключа: для параметра
StrictHostKeyCheckingукажитеyes.Не храните пароли в открытом виде — используйте Ansible Vault для шифрования учетных данных.
Используйте параметр
no_log: true, чтобы учетные данные не попадали в логи Ansible при завершении задачи.В CI/CD-сценариях передавайте пароль и SSH-ключ через переменные окружения.
Файл ssh_config содержит данные подключения. Рекомендуется ограничить права на файл командой:
chmod 600 ~/.ssh/configДля повышения уровня безопасности рекомендуется использовать следующие параметры:
gather_facts: false— отключает сбор информации о хосте и позволяет не выводить в логи команды запуска Python-скриптов.no_log: true— отключает вывод в консоль и запись в логи Ansible. Используйте для задач с учетными данными.become: trueиbecome_method: sudo— повышает привилегии пользователя для выполнения команд, требующих правroot.Модуль
raw— позволяет выполнять команды через SSH Proxy без установки Python на целевом ресурсе и предоставляет информативный лог в профиле сессии в консоли администратора.Пример сценария
---
- name: Выполнить команду через PAM SSH Proxy
hosts: all
gather_facts: false
become: true
become_method: sudo
vars:
ansible_host: "pam.company.com"
ansible_port: 2222
ansible_user: "pam.admin#10.10.5.190#PAM.LOCAL\\pam-admin"
ansible_password: "{{ pam_password }}"
tasks:
- name: Выполнить команду (учетные данные скрыты)
ansible.builtin.raw: uname -a
register: result
changed_when: false
no_log: true
- name: Показать результат команды (лог отображается)
ansible.builtin.debug:
msg: "{{ result.stdout | trim }}"
no_log: false