![](https://habrastorage.org/getpro/habr/upload_files/8e1/54a/496/8e154a496f39b26df4a0fcfbc65e23bc.png)
Задачи автоматизации развертывания какого-либо ПО или изменения настроек системы практически всегда связаны с использованием учетных записей, обладающих необходимым набором прав для выполнения данных действий. И одна из самых важных проблем при использовании различных скриптов автоматизации состоит в том, что в этом сценарии приходится указывать учетные данные в открытом виде. Соответственно возникает проблема обеспечения безопасности этих данных, ведь к исходному коду скрипта может получить доступ любой пользователь, обладающий соответствующими правами. Кроме того, репозитории, в которых хранится исходный код сценариев тоже нуждаются в защите, так как здесь тоже любой имеющий доступ на чтение может узнать пароли. Конечно, можно попробовать хранить секретную информацию в отдельных файлах и считывать при выполнении сценария, но это не всегда возможно и часто требует дополнительного ручного труда, что несколько снижает преимущества автоматизации.
Склеп для секретов
И здесь на помощь нам приходит Ansible Vault – утилита для шифрования любых файлов в которых вы хотите хранить секретные переменные (пароли, ключи и т.д.). В качестве алгоритма шифрования Ansible Vault использует алгоритм симметричного шифрования AES256.
В этой статье мы рассмотрим использование Ansible Vault для работы с секретной информацией. Сразу замечу, что многие предпочитают использовать Hashicorp Vault для работы с Ansible, однако этого мощного средства в данной статье касаться не будем и поговорим только о встроенных в Ansible средствах.
Итак, основное предназначение Vault это хранение конфиденциальной информации, такой как учетные данные и секретные ключи. Как происходит обработки зашифрованных данных: в процессе выполнения плейбука данные автоматически расшифровываются и наша задача при выполнении плейбука правильно указать ключи, необходимые для расшифровки. Для шифрования используется парольная фраза и, соответственно, чем сложнее фраза, тем сложнее злоумышленнику расшифровать данные.
Важное уточнение. Ansible Vault защищает данные только когда они находятся в состоянии покоя, после того, как они расшифрованы Vault уже никаким образом не может их защитить и об их безопасности необходимо заботиться уж другими средствами.
Приступая к работе
Для работы с Vault нам прежде всего потребуется сам Ansible. В предыдущих статьях мы уже рассматривали его установку, поэтому будем считать, что все что нужно у вас уже есть.
Для работы с файлами мы можем вводить парольную фразу с клавиатуры при каждом обращении к Vault или же использовать файл, в котором хранится парольная фраза. В первом случае в строку вызова добавляется ключ —ask-vault-pass
, во втором добавляется параметр —vault-password-file=<путь к файлу>.
Но прежде, чем начать работу с утилитой официальное руководство по Ansible предлагает нам определиться со стратегией управления паролями вашего хранилища. А именно, для начала нам нужно определиться с тем, будем ли мы шифровать весь контент одним паролем или же мы будем применять разные парольные фразы для разных случаев. Также, очень важный вопрос это где вы собираетесь хранить свои пароли.
В случае, если у вас небольшая команда или немного данных, вы можете использовать один пароль для всего, что вы шифруете с помощью Ansible Vault. Здесь важно помнить, что не стоит пытаться шифровать все данные, шифруйте только то, что является действительно секретной информацией, что критично для бизнеса и инфраструктуры.
Несколько паролей удобны если у вас большая команда или большой объем конфиденциальных данных. Например, вы можете использовать разные пароли для разных пользователей или для разграничения разных уровней доступа. В зависимости от решаемых задач вам может потребоваться другой пароль для каждого зашифрованного файла или каталога. Например, у вас может быть playbook, который включает в себя два файла vars, один для среды разработки и один для рабочей среды, зашифрованные двумя разными паролями. При запуске плейбука вам потребуется выбрать правильный пароль хранилища для среды, на которую вы ориентируетесь, используя идентификатор хранилища.
Начнем с простого примера. Создадим зашифрованный файл с консольным вводом пароля. Пока никакой автоматизации.
ansible-vault create --vault-id @prompt secret.yml
New vault password (default):
Confirm new vault password (default):
Содержимое файла плейбука может быть например следующим:
---
- name: This is a secret file
hosts: s1.otus.local
tasks:
- name: Execute command 'ls'
command: ls
После сохранения yml файла убедимся что он зашифрован.
![](https://habrastorage.org/getpro/habr/upload_files/bbf/06b/c33/bbf06bc3335c8a55173219c3d29694f1.png)
Как видно, все кроме заголовка превратилось в бессмысленный набор цифр. Однако, зашифровать данные недостаточно, важно еще и расшифровать их и для этого мы воспользуемся следующей командой.
ansible-vault view --vault-id @prompt secret.yml
Как видно все достаточно просто. Если нам необходимо внести изменения в зашифрованный файл то можно воспользоваться следующей командой:
ansible-vault edit secret.yml
![](https://habrastorage.org/getpro/habr/upload_files/27e/eb8/36e/27eeb836e0696cd81a0aa8453935c68b.png)
Но я думаю, что большинство системных администраторов согласится с тем, что это не самый лучший подход к автоматизации работы. Интерактивный ввод пароля требует участия человека который знает это пароль. То есть делегировать кому-либо запуск зашифрованного плейбука нам будет проблематично. Ну а с точки зрения безопасности хотелось бы напомнить, что существует такой класс вредоносов как кейлоггеры, то есть приложения, которые сохраняют все нажатые клавиши и интерактивный ввод парольной фразы позволит таким клавиатурным шпионам перехватить нажатые клавиши.
Поэтому в качестве альтернативы предлагается использовать файл с паролями. Здесь тоже надо помнить про безопасность и обеспечить ограничение доступа посторонних к каталогу, в котором хранятся такие файлы.
Для начала создадим файл с “очень сложным” паролем:
echo “P@ssw0rd” > password_file
И теперь применим этот файл для редактирования нашего yml файла. В случае, если для шифрования файла в предыдущем примере у вас использовался другой пароль, то для корректной расшифровки secret.yml необходимо указать его.
ansible-vault edit --vault-password-file password_file secret.yml
Если же у нас уже имеется готовый плейбук и мы хотим его зашифровать, то пригодится команда encrypt:
ansible-vault encrypt --vault-id @prompt secret_conditional.yml
Практическое применение
Приведенные выше примеры демонстрировали возможности ansible-vault как отдельного средства шифрования/дешифрования файлов. Однако, на практике шифрование используется в плейбуках и нам нужно иметь возможность сообщить плейбуку как получить доступ к любым зашифрованным данным, с которыми он может столкнуться. Здесь важно понимать что плейбук не знает, что по умолчанию он имеет дело с зашифрованными данными, поэтому при запуске команды ansible-playbook ему необходимо передать соответствующую информацию. Так, для запуска нашего зашифрованного плейбука с интерактивным запросом пароля нам необходимо выполнить следующую команду:
ansible-playbook --vault-id @prompt secret.yml
Ну а если мы хотим использовать файл с паролями, то команда будет иметь следующий вид:
ansible-playbook secret.yml --vault-password-file=password_file
Когда не нужно все
Далеко не всегда необходимо шифровать файл плейбука целиком. Иногда удобнее зашифровать значение только определенной переменной, например пароль, а все остальное оставить в открытом виде для того, чтобы другие специалисты также могли вносить свои правки при необходимости.
Для этого мы можем воспользоваться параметром encrypt_string. В примере ниже у нас имеется переменная my_secret значение которой неплохо бы скрыть от посторонних.
---
- name: inline secret variable demonstration
hosts: s1.otus.local
gather_facts: false
vars:
my_secret: my_very_long_password
tasks:
- name: print the secure variable
debug:
var: my_secret
Для этого используем следующую команду:
ansible-vault encrypt_string --vault-id @prompt my_very_long_password
![](https://habrastorage.org/getpro/habr/upload_files/00c/b72/7b4/00cb727b43d2a3e7c262a57f12335819.png)
Теперь мы можем заменить значение переменной на этот набор цифр и получить в итогк следующее:
![](https://habrastorage.org/getpro/habr/upload_files/db4/1ca/196/db41ca1962f4c0bf352a8384d3fd1286.png)
Для запуска этого плейбука воспользуемся командой
ansible-playbook --vault-id @prompt secret1.yml
Управление паролями
В завершении статьи немного поговорим об управлении паролями, используемыми для шифрования. Общеизвестно, что пароли необходимо на регулярной основе менять, в противном случае со времени они перестанут быть секретом.
Для замены пароля необходимо указать старый пароль и затем два раза ввести новый:
ansible-vault rekey --ask-vault-pass secret.yml
![](https://habrastorage.org/getpro/habr/upload_files/b95/36c/d09/b9536cd092a998d8cf67c389b5c9d542.png)
Как видно все достаточно просто.
Заключение
Сегодня мы рассмотрели работу с шифрованием данных в Ansible с помощью Ansible Vault. Данная утилита предоставляет базовый функционал для шифрования, а для более решения более сложных задач управления шифрованием рекомендуется использовать Hashicorp Vault.
Также я хочу порекомендовать вам бесплатный урок от OTUS в рамках которого мы рассмотрим различные типы анализа исходного кода (SAST/SCA/DAST/IAST/RASP) и поговорим об инструментах, позволяющих внедрить их в ваш CI/CD пайплайн.