Блог "Дети ОИТа"
/поиск

Практическое руководство по безопасному хранению секретов

### Практическое руководство по безопасному хранению секретов ## Введение При автоматизации управления конфигурациями с помощью Ansible часто возникает необходимость хранить чувствительные данные: п

Введение

При автоматизации управления конфигурациями с помощью Ansible часто возникает необходимость хранить чувствительные данные: пароли, ключи API, сертификаты, приватные ключи SSH. Хранить их в открытом виде в плейбуках или переменных – плохая практика, особенно если код хранится в системах контроля версий (Git) и доступен широкому кругу лиц.

Ansible Vault – встроенный инструмент Ansible, который позволяет шифровать файлы или отдельные строки так, что они становятся безопасными для хранения в репозитории. В этой статье мы рассмотрим практические сценарии использования Ansible Vault: от шифрования файлов до интеграции в CI/CD.

1. Основы Ansible Vault

Ansible Vault использует симметричное шифрование (AES256). Для работы с зашифрованными данными требуется пароль (или ключ), который необходимо вводить при каждом запуске плейбука.

1.1. Создание зашифрованного файла

Создадим файл secrets.yml, содержащий переменные с секретами:

ansible-vault create secrets.yml

Система запросит пароль (дважды) и откроет текстовый редактор (обычно vi). Введём содержимое:

db_password: SuperSecret123
api_key: 1a2b3c4d5e

После сохранения файл будет зашифрован. Попытка прочитать его обычным способом покажет бинарные данные.

1.2. Просмотр зашифрованного файла

Для просмотра содержимого без расшифровки на диск:

ansible-vault view secrets.yml

Будет запрошен пароль, после чего содержимое отобразится на экране.

1.3. Редактирование зашифрованного файла

ansible-vault edit secrets.yml

Команда расшифровывает файл во временный, открывает редактор, а после закрытия снова шифрует.

1.4. Расшифровка файла (не рекомендуется, если не требуется)

Если нужно временно убрать шифрование (например, для миграции):

ansible-vault decrypt secrets.yml

Внимание: после этого файл станет открытым текстом.

1.5. Смена пароля

ansible-vault rekey secrets.yml

Будет запрошен старый пароль, затем новый (дважды).

2. Использование зашифрованных данных в плейбуках

2.1. Прямое указание переменных

Самый простой способ – включить зашифрованный файл с переменными в плейбук:


- hosts: all
  vars_files:
    - secrets.yml
  tasks:
    - name: Use secret variable
      debug:
        msg: "Database password is {{ db_password }}"

При запуске плейбука Ansible запросит пароль vault:

ansible-playbook site.yml

2.2. Включение зашифрованных файлов внутри других файлов переменных

Можно включить зашифрованный файл в обычный YAML через !vault tag, но проще использовать vars_files.

2.3. Зашифрованные переменные в inventory

Иногда нужно зашифровать отдельные переменные в inventory (например, ansible_become_password). Для этого файл inventory (или отдельный файл переменных группы/хоста) можно зашифровать целиком.

3. Управление паролями vault

Ввод пароля вручную удобен для локальной работы, но при автоматизации (cron, CI/CD) требуется передавать пароль без интерактива.

3.1. Файл с паролем

Создайте файл, содержащий только пароль (одна строка). Например, .vault_pass.txt. Затем используйте опцию --vault-password-file:

bash

ansible-playbook site.yml --vault-password-file .vault_pass.txt

Никогда не сохраняйте файл с паролем в Git! Добавьте его в .gitignore.

3.2. Переменная окружения ANSIBLE_VAULT_PASSWORD_FILE

Установите переменную окружения, указывающую на файл с паролем:

export ANSIBLE_VAULT_PASSWORD_FILE=/path/to/.vault_pass.txt
ansible-playbook site.yml

Это избавляет от необходимости каждый раз указывать опцию.

3.3. Использование скриптов-исполнителей

Вместо статического файла можно указать исполняемый скрипт, который выводит пароль (например, из менеджера секретов HashiCorp Vault, lastpass, или просто echo). Скрипт должен возвращать пароль в stdout.

Пример простого скрипта get_vault_pass.sh:

#!/bin/sh
echo -n "my-secret-password"

Сделайте его исполняемым и используйте:

ansible-playbook site.yml --vault-password-file ./get_vault_pass.sh

Это удобно для интеграции с внешними системами.

4. Шифрование отдельных строк (encrypt_string)

Иногда нецелесообразно шифровать целый файл, если нужно скрыть лишь одно значение. Ansible Vault позволяет зашифровать отдельную строку и вставить её прямо в YAML-файл.

ansible-vault encrypt_string 'SuperSecret123' --name 'db_password'

Результат будет выглядеть так:

db_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          666237313733363...

Такую строку можно вставить в любой YAML-файл. При использовании плейбука Ansible автоматически расшифрует её.

Также можно зашифровать строку для конкретного vault ID (см. раздел 5).

5. Работа с несколькими паролями (Vault IDs)

Начиная с Ansible 2.4 появилась возможность использовать несколько разных паролей для разных файлов или строк. Это полезно, если у вас есть разные окружения (dev, prod) и разные команды имеют доступ только к своим секретам.

При создании файла можно указать vault ID (метку):

ansible-vault create --vault-id dev@prompt secrets_dev.yml

Здесь dev – это идентификатор, @prompt означает, что пароль будет запрошен интерактивно. Можно указать файл: --vault-id prod@/path/to/prod.pass.

При запуске плейбука нужно указать все необходимые vault ID:

ansible-playbook site.yml --vault-id dev@.vault_pass_dev.txt --vault-id prod@.vault_pass_prod.txt

Ansible сам определит, какой пароль нужен для какого зашифрованного блока, по метке, сохранённой в зашифрованных данных.

Это особенно удобно, когда часть переменных зашифрована для разработчиков, а часть – только для админов продакшена.

6. Интеграция с CI/CD системами

В автоматических конвейерах (Jenkins, GitLab CI, GitHub Actions) нельзя вводить пароль вручную. Обычно используют один из подходов:

  • Хранят пароль vault в секретах CI/CD-системы и передают его через переменную окружения, а затем записывают во временный файл или используют скрипт-обёртку.
  • Используют внешние менеджеры секретов (HashiCorp Vault) и скрипт, который получает пароль оттуда.
  • Для GitLab CI можно использовать переменную типа VAULT_PASS и скрипт:
echo "$VAULT_PASS" > .vault_pass.txt
ansible-playbook playbook.yml --vault-password-file .vault_pass.txt

Важно: не выводите пароль в логах сборки.

7. Лучшие практики

7.1. Никогда не храните пароль от vault в репозитории

Добавьте в .gitignore все файлы, содержащие пароли (например, *.pass, .vault_pass.txt). Используйте скрипты или менеджеры паролей.

7.2. Ограничьте доступ к файлам с паролями

На серверах управления и в CI/CD убедитесь, что файлы с паролями доступны только нужным процессам и пользователям.

7.3. Регулярно меняйте пароли vault

Как и любые секреты, пароли vault должны периодически обновляться. Используйте ansible-vault rekey для смены пароля на всех зашифрованных файлах.

7.4. Шифруйте только чувствительные данные

Не шифруйте весь плейбук целиком – это затруднит ревью кода. Шифруйте отдельные файлы переменных или используйте encrypt_string.

7.5. Используйте vault ID для разделения окружений

Это позволит гибко управлять доступом к секретам.

7.6. Делайте резервные копии паролей

Потеря пароля vault сделает зашифрованные данные недоступными навсегда. Храните пароль в надёжном месте (менеджер паролей, физический сейф).

7.7. Проверяйте, что зашифровано

Команда ansible-vault view помогает быстро проверить содержимое. Также можно использовать grep на расшифрованном содержимом с осторожностью.

Заключение

Ansible Vault – мощный и простой инструмент для защиты конфиденциальных данных в ваших проектах Ansible. Его возможности покрывают большинство потребностей: от шифрования целых файлов до отдельных строк, поддержка нескольких паролей и интеграция с автоматизацией. Следуя лучшим практикам, вы обеспечите безопасность секретов и избежите их утечки.

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