Ansible Vault
- Что можно зашифровать с помощью Vault
- Vault ID и несколько паролей Vault
- Создание зашифрованных файлов
- Редактирование зашифрованных файлов
- Перешифрование зашифрованных файлов
- Шифрование незашифрованных файлов
- Расшифрование зашифрованных файлов
- Просмотр зашифрованных файлов
- Использование encrypt_string для создания зашифрованных переменных для встраивания в YAML
- Предоставление паролей Vault
- Сценарии клиентов паролей Vault
- Ускорение операций Vault
- Формат Vault
- Формат полезной нагрузки Vault 1.1 — 1.2
Ansible Vault — это функция Ansible, которая позволяет хранить конфиденциальные данные, такие как пароли или ключи, в зашифрованных файлах вместо открытого текста в playbooks или ролях. Эти файлы vault можно затем распространять или размещать в системе управления версиями.
Для активации этой функции используется командная утилита — ansible-vault — для редактирования файлов, и используется командный флаг (--ask-vault-pass, --vault-password-file или --vault-id). В качестве альтернативы вы можете указать расположение файла пароля или попросить Ansible всегда запрашивать пароль в файле ansible.cfg. Эти параметры не требуют использования командных флагов.
Для получения рекомендаций по лучшим практикам обратитесь к Переменные и хранилища.
Что можно зашифровать с помощью Vault
Шифрование на уровне файлов
Ansible Vault может шифровать любые структурированные файлы данных, используемые Ansible.
Это могут быть переменные инвентаризации «group_vars/» или «host_vars/», переменные, загружаемые с помощью «include_vars» или «vars_files», или файлы переменных, переданные в командной строке ansible-playbook с помощью -e @file.yml или -e @file.json. Также включаются переменные и значения по умолчанию ролей.
Также к данным относятся задачи, обработчики Ansible и т. д., поэтому их тоже можно зашифровать с помощью vault. Чтобы скрыть имена используемых переменных, можно зашифровать файлы задач целиком.
Ansible Vault также может шифровать произвольные файлы, даже бинарные. Если файл, зашифрованный vault, используется как аргумент src для модулей copy, template, unarchive, script или assemble, файл будет размещён на целевом хосте расшифрованным (при условии, что при выполнении play предоставлен действительный пароль vault).
Примечание
Преимущества шифрования на уровне файлов заключаются в простоте использования и простоте ротации паролей с помощью перешифрования. Недостаток заключается в том, что содержимое файлов больше не является легко доступным для чтения. Это может быть проблематично, если это список задач (при шифровании файла переменных, лучшая практика заключается в том, чтобы хранить ссылки на эти переменные в незашифрованном файле).
Шифрование на уровне переменных
Ansible также поддерживает шифрование отдельных значений внутри файла YAML с использованием тега !vault для информирования YAML и Ansible о специальной обработке. Эта функция описана более подробно ниже.
Примечание
Преимущества шифрования на уровне переменных заключаются в том, что файлы по-прежнему легко читаемы, даже если они содержат как открытый текст, так и зашифрованные переменные. Недостаток заключается в том, что ротация паролей не такая простая, как при шифровании на уровне файлов: команда перешифрования не работает с этим методом.
Vault ID и несколько паролей Vault
Vault ID — это идентификатор одного или нескольких секретов Vault; Ansible поддерживает несколько паролей Vault.
Vault ID предоставляют метки для различения отдельных паролей Vault.
Чтобы использовать Vault ID, необходимо указать выбранный вами ID-метку и источник получения пароля (либо prompt или путь к файлу):
--vault-id label@source
Этот переключатель доступен для всех команд Ansible, которые могут взаимодействовать с Vault: ansible-vault, ansible-playbook и т. д.
Зашифрованное содержимое Vault может указывать, с каким ID Vault оно было зашифровано.
Например, playbook теперь может включать файл vars, зашифрованный с ID Vault «dev» и «prod».
Создание зашифрованных файлов
Чтобы создать новый зашифрованный файл данных, выполните следующую команду:
ansible-vault create foo.yml
Сначала вам будет запрошен пароль. После ввода пароля инструмент запустит редактор, который вы указали в переменной среды $EDITOR (по умолчанию vi). После завершения работы с редактором файл будет сохранён как зашифрованные данные.
По умолчанию используется шифр AES (который основан на общем секрете).
Чтобы создать новый зашифрованный файл данных с присвоенным ему ID Vault «password1» и запросить пароль, выполните:
ansible-vault create --vault-id password1@prompt foo.yml
Редактирование зашифрованных файлов
Чтобы отредактировать зашифрованный файл на месте, используйте команду ansible-vault edit. Эта команда расшифрует файл во временный файл и позволит вам отредактировать файл, сохранив его при завершении и удалив временный файл:
ansible-vault edit foo.yml
Чтобы отредактировать файл, зашифрованный с файлом пароля «vault2» и присвоенным ID Vault «pass2»:
ansible-vault edit --vault-id pass2@vault2 foo.yml
Перешифрование зашифрованных файлов
Если вам нужно изменить пароль для файла или файлов Vault, вы можете сделать это с помощью команды rekey:
ansible-vault rekey foo.yml bar.yml baz.yml
Эта команда может перешифровать несколько файлов данных одновременно и запросит исходный пароль, а также новый пароль.
Чтобы перешифровать файлы, зашифрованные с ID Vault «preprod2» и файлом «ppold», и запросить новый пароль:
ansible-vault rekey --vault-id preprod2@ppold --new-vault-id preprod2@prompt foo.yml bar.yml baz.yml
Разный ID можно было установить для перешифрованных файлов, передав его в --new-vault-id.
Шифрование незашифрованных файлов
Если у вас есть существующие файлы, которые вы хотите зашифровать, используйте команду ansible-vault encrypt. Эта команда может работать с несколькими файлами одновременно:
ansible-vault encrypt foo.yml bar.yml baz.yml
Чтобы зашифровать существующие файлы с ID «project» и запросить пароль:
ansible-vault encrypt --vault-id project@prompt foo.yml bar.yml baz.yml
Примечание
Технически возможно отдельно зашифровать файлы или строки с одним ID Vault, но с разными паролями, если каждый раз предоставляются разные файлы паролей или пароли, запрошенные вручную. Это может быть желательно, если вы используете ID Vault как ссылки на классы паролей (а не на один пароль), и вы всегда знаете, какой конкретный пароль или файл использовать в контексте. Однако это может быть излишне сложный случай. Если два файла зашифрованы с одинаковым ID Vault, но с разными паролями по ошибке, вы можете использовать команду перешифрования для исправления проблемы.
Расшифрование зашифрованных файлов
Если у вас есть существующие файлы, которые вы больше не хотите хранить в зашифрованном виде, вы можете окончательно расшифровать их, выполнив команду ansible-vault decrypt. Эта команда сохранит их в незашифрованном виде на диске, поэтому убедитесь, что вы не хотите использовать ansible-vault edit:
ansible-vault decrypt foo.yml bar.yml baz.yml
Просмотр зашифрованных файлов
Если вы хотите просмотреть содержимое зашифрованного файла без редактирования, вы можете использовать команду ansible-vault view:
ansible-vault view foo.yml bar.yml baz.yml
Использование encrypt_string для создания зашифрованных переменных для встраивания в YAML
Команда ansible-vault encrypt_string зашифрует и отформатирует предоставленную строку в формат, который можно включить в файлы YAML ansible-playbook.
Для шифрования строки, переданной в качестве аргумента командной строки:
ansible-vault encrypt_string --vault-password-file a_password_file 'foobar' --name 'the_secret'
Результат:
the_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383764373764613633653634306231386433626436623361
6134333665353966363534333632666535333761666131620a663537646436643839616531643561
63396265333966386166373632626539326166353965363262633030333630313338646335303630
3438626666666137650a353638643435666633633964366338633066623234616432373231333331
6564
Для использования метки vault-id для vault-id ‘dev’:
ansible-vault encrypt_string --vault-id dev@a_password_file 'foooodev' --name 'the_dev_secret'
Результат:
the_dev_secret: !vault |
$ANSIBLE_VAULT;1.2;AES256;dev
30613233633461343837653833666333643061636561303338373661313838333565653635353162
3263363434623733343538653462613064333634333464660a663633623939393439316636633863
61636237636537333938306331383339353265363239643939666639386530626330633337633833
6664656334373166630a363736393262666465663432613932613036303963343263623137386239
6330
Для шифрования строки, считанной со стандартного ввода, и присвоения ей имени ‘db_password’:
echo -n 'letmein' | ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'db_password'
Предупреждение
Этот метод оставляет строку в истории вашей оболочки. Не используйте его вне тестирования.
Результат:
Reading plaintext input from stdin. (ctrl-d to end input)
db_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;dev
61323931353866666336306139373937316366366138656131323863373866376666353364373761
3539633234313836346435323766306164626134376564330a373530313635343535343133316133
36643666306434616266376434363239346433643238336464643566386135356334303736353136
6565633133366366360a326566323363363936613664616364623437336130623133343530333739
3039
Для запроса строки для шифрования, её шифрования и присвоения ей имени ‘new_user_password’:
ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'new_user_password'
Вывод:
Reading plaintext input from stdin. (ctrl-d to end input)
Пользователь вводит ‘hunter2’ и нажимает ctrl-d.
Предупреждение
Не нажимайте Enter после ввода строки. Это добавит новую строку к зашифрованному значению.
Результат:
new_user_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;dev
37636561366636643464376336303466613062633537323632306566653533383833366462366662
6565353063303065303831323539656138653863353230620a653638643639333133306331336365
62373737623337616130386137373461306535383538373162316263386165376131623631323434
3866363862363335620a376466656164383032633338306162326639643635663936623939666238
3161
См. также Одну зашифрованную переменную
Предоставление паролей Vault
Когда все данные зашифрованы с помощью одного пароля, следует использовать опции командной строки --ask-vault-pass или --vault-password-file.
Например, для использования хранилища паролей в текстовом файле /path/to/my/vault-password-file:
ansible-playbook --vault-password-file /path/to/my/vault-password-file site.yml
Для запроса пароля:
ansible-playbook --ask-vault-pass site.yml
Для получения пароля из исполняемого скрипта пароля vault my-vault-password.py:
ansible-playbook --vault-password-file my-vault-password.py
Опция конфигурации DEFAULT_VAULT_PASSWORD_FILE может быть использована для указания файла пароля vault, чтобы не приходилось указывать опцию командной строки --vault-password-file каждый раз.
Разметка хранилищ
Начиная с Ansible 2.4, можно использовать --vault-id, чтобы указать, к какому идентификатору vault (‘dev’, ‘prod’, ‘cloud’ и т. д.) относится пароль, а также как получить пароль (запрос, путь к файлу и т. д.).
По умолчанию метка vault-id является лишь подсказкой; все значения, зашифрованные паролем, будут расшифрованы. Опция конфигурации DEFAULT_VAULT_ID_MATCH может быть установлена так, чтобы требовать соответствия метки vault-id метке vault-id, используемой при шифровании значения. Это может снизить количество ошибок, когда разные значения зашифрованы с помощью разных паролей.
Например, для использования файла пароля dev-password для vault-id ‘dev’:
ansible-playbook --vault-id dev@dev-password site.yml
Для запроса пароля для vault-id ‘dev’:
ansible-playbook --vault-id dev@prompt site.yml
Для получения пароля vault-id ‘dev’ из исполняемого скрипта my-vault-password.py:
ansible-playbook --vault-id dev@my-vault-password.py
Опция конфигурации DEFAULT_VAULT_IDENTITY_LIST может использоваться для указания стандартного vault-id и источника пароля, чтобы не приходилось указывать опцию командной строки --vault-id каждый раз.
Опция --vault-id также может быть использована без указания vault-id. Это поведение эквивалентно --ask-vault-pass или --vault-password-file, поэтому используется редко.
Например, для использования файла пароля dev-password:
ansible-playbook --vault-id dev-password site.yml
Для запроса пароля:
ansible-playbook --vault-id @prompt site.yml
Для получения пароля из исполняемого скрипта my-vault-password.py:
ansible-playbook --vault-id my-vault-password.py
Примечание
До Ansible 2.4 опция --vault-id не поддерживалась, поэтому необходимо было использовать --ask-vault-pass или --vault-password-file.
Несколько паролей Vault
Ansible 2.4 и более поздние версии поддерживают использование нескольких паролей vault; --vault-id можно указать несколько раз.
Например, для использования пароля ‘dev’, считанного из файла, и запроса пароля ‘prod’:
ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml
По умолчанию метки vault-id (dev, prod и т. д.) являются лишь подсказками; Ansible будет пытаться расшифровать содержимое vault с помощью каждого пароля. Пароль с той же меткой, что и зашифрованные данные, будет пробоваться первым, а затем каждый секрет vault будет пробоваться в порядке, в котором они были предоставлены в командной строке.
В случаях, когда у зашифрованных данных нет метки или метка не совпадает ни с одной из предоставленных меток, пароли будут пробоваться в указанном порядке.
В приведенном выше случае пароль ‘dev’ будет пробоваться первым, а затем пароль ‘prod’ в тех случаях, когда Ansible не знает, какой vault-id используется для шифрования чего-либо.
Чтобы добавить метку vault-id к зашифрованным данным, используйте опцию --vault-id с меткой при шифровании данных.
Опция конфигурации DEFAULT_VAULT_ID_MATCH может быть установлена таким образом, чтобы Ansible использовал только пароль с той же меткой, что и зашифрованные данные. Это более эффективно и может быть более предсказуемо при использовании нескольких паролей.
Опция конфигурации DEFAULT_VAULT_IDENTITY_LIST может содержать несколько значений, что эквивалентно нескольким опциям командной строки --vault-id.
Опция --vault-id может использоваться вместо опций --vault-password-file или --ask-vault-pass, или её можно использовать вместе с ними.
При использовании команд ansible-vault, шифрующих содержимое (ansible-vault encrypt, ansible-vault encrypt_string и т. д.), можно использовать только один vault-id.
Скрипты клиентов паролей Vault
При реализации скрипта для получения пароля vault может быть удобно знать, какая метка vault-id была запрошена. Например, скрипт, загружающий пароли из системы управления секретами, может использовать метку vault-id для выбора пароля ‘dev’ или ‘prod’.
Начиная с Ansible 2.5, это поддерживается с помощью скриптов клиентов. Скрипт клиента — это исполняемый скрипт с именем, заканчивающимся на -client. Скрипты клиентов используются для получения паролей vault так же, как и любые другие исполняемые скрипты. Например:
ansible-playbook --vault-id dev@contrib/vault/vault-keyring-client.py
Разница заключается в реализации скрипта. Скрипты клиентов выполняются с опцией --vault-id, чтобы они знали, какая метка vault-id была запрошена. Таким образом, выполнение Ansible выше приводит к выполнению скрипта клиента ниже:
contrib/vault/vault-keyring-client.py --vault-id dev
contrib/vault/vault-keyring-client.py — пример скрипта клиента, загружающего пароли из системного хранилища ключей.
Ускорение операций Vault
По умолчанию Ansible использует PyCrypto для шифрования и расшифрования файлов vault. Если у вас много зашифрованных файлов, их расшифровка при запуске может привести к ощутимой задержке. Для ускорения этого процесса установите пакет cryptography:
pip install cryptography
Формат Vault
Файл vault, зашифрованный vault, — это текстовый файл UTF-8.
Формат файла включает заголовок, завершаемый новой строкой.
Например:
$ANSIBLE_VAULT;1.1;AES256
или:
$ANSIBLE_VAULT;1.2;AES256;vault-id-label
Заголовок содержит идентификатор формата vault, версию формата vault, шифр vault и метку vault-id (с версией формата 1.2), разделенные символом «;».
Первый элемент $ANSIBLE_VAULT — это идентификатор формата. В настоящее время $ANSIBLE_VAULT — единственный допустимый идентификатор формата файла. Он используется для идентификации файлов, зашифрованных vault (через vault.is_encrypted_file()).
Второй элемент (1.X) — это версия формата vault. Все поддерживаемые версии ansible по умолчанию будут использовать ‘1.1’ или ‘1.2’, если предоставлен vault-id с меткой.
Формат ‘1.0’ поддерживается только для чтения (и будет автоматически преобразован в формат ‘1.1’ при записи). Версия формата в настоящее время используется только для точного сравнения строк (версии в настоящее время не сравниваются).
Третий элемент (AES256) определяет алгоритм шифрования, используемый для шифрования данных. В настоящее время единственный поддерживаемый шифр — ‘AES256’. [Формат vault 1.0 использовал ‘AES’, но текущий код всегда использует ‘AES256’]
Четвертый элемент (vault-id-label) определяет метку vault-id, используемую для шифрования данных. Например, использование vault-id dev@prompt приводит к использованию метки vault-id ‘dev’.
Примечание: в будущем заголовок может измениться. Все, что после идентификатора и версии vault, можно считать зависящим от версии формата vault. Это включает идентификатор шифра и любые дополнительные элементы, которые могут находиться после него.
Остальная часть содержимого файла — это ‘vaulttext’. Vaulttext — это зашифрованная версия зашифрованного шифртекста. Каждая строка будет иметь ширину 80 символов, за исключением последней строки, которая может быть короче.
Формат полезной нагрузки хранилища 1.1 — 1.2
Vaulttext представляет собой конкатенацию шифртекста и хэш-суммы SHA256 с результатом ‘hexlifyied’.
‘hexlify’ относится к методу hexlify() модуля binascii стандартной библиотеки Python.
Результат hexlify()’ed:
- Строка hexlify()’ed соли, за которой следует символ новой строки (
0x0a) - Строка hexlify()’ed зашифрованного HMAC, за которой следует символ новой строки. HMAC:
- HMAC в стиле RFC2104
- Входы:
- Зашифрованный с помощью AES256 шифртекст
- Ключ PBKDF2. Этот ключ, ключ шифра и IV шифра генерируются из:
- соль в байтах
- 10000 итераций
- алгоритм SHA256()
- первые 32 байта — ключ шифра
- следующие 32 байта — ключ HMAC
- оставшиеся 16 байт — IV шифра
- Входы:
- HMAC в стиле RFC2104
- Строка hexlify()’ed шифртекста. Шифртекст:
- Данные, зашифрованные с помощью AES256. Данные шифруются с помощью:
- потоковый шифр AES-CTR
- ключ шифра
- IV
- блок счётчика 128 бит, инициализированный целым числом IV
- открытый текст
- исходный открытый текст
- дополнение до размера блока AES256. (Данные, используемые для дополнения, основаны на RFC5652)
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.8/user_guide/vault.html