Как использовать Vault для защиты конфиденциальных данных в Ubuntu 16.04

Вступление

Ansible Vault - это функция, которая позволяет пользователям шифровать значения и структуры данных в проектах Ansible. Это обеспечивает возможность защиты любых конфиденциальных данных, которые необходимы для успешного запуска Ansible play, но не должны быть публично видимыми, например пароли или закрытые ключи. Ansible автоматически дешифрует зашифрованное хранилище содержимое во время выполнения, когда ключ предоставлен.

В этом руководстве мы покажем, как использовать Ansible Vault, и рассмотрим некоторые рекомендуемые методы для упрощения его использования. Мы будем использовать сервер Ubuntu 16.04 для управляющей машины Ansible. Удаленные хосты не нужны.

Предпосылки

Для продолжения вам понадобится сервер Ubuntu 16.04 с пользователем без полномочий root с привилегиями + sudo +. Вы можете следовать нашему Ubuntu 16.04 начальному руководству по настройке сервера, чтобы создать пользователя с соответствующими разрешениями.

На сервере вам нужно будет установить и настроить Ansible. Вы можете следовать нашему руководству на install Ansible в Ubuntu 16.04, чтобы установить соответствующий пакеты.

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

Что такое Ansible Vault?

Vault - это механизм, позволяющий прозрачно включать зашифрованный контент в рабочие процессы Ansible. Утилита + ansible-vault + защищает конфиденциальные данные, шифруя их на диске. Чтобы объединить эти секреты с обычными данными Ansible, обе команды + ansible + и + ansible-playbook + для выполнения специальных задач и структурированного playbook соответственно имеют поддержку дешифрования зашифрованного в хранилище содержимого во время выполнения.

Хранилище реализовано с детализацией на уровне файлов, что означает, что файлы либо полностью зашифрованы, либо не зашифрованы. Он использует алгоритм + AES256 + для обеспечения симметричного шифрования, связанного с предоставленным пользователем паролем. Это означает, что один и тот же пароль используется для шифрования и дешифрования контента, что полезно с точки зрения удобства использования. Ansible может идентифицировать и дешифровать любые файлы, зашифрованные в хранилище, которые он обнаруживает при выполнении книги воспроизведения или задачи.

Хотя t есть предложения по изменению этого, на момент написания этой статьи пользователи могли передать Ansible только один пароль. Это означает, что каждый из зашифрованных файлов должен иметь общий пароль.

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

Настройка редактора Ansible Vault

Перед использованием команды + ansible-vault + рекомендуется указать предпочитаемый текстовый редактор. Некоторые из команд Vault включают открытие редактора для управления содержимым зашифрованного файла. Ansible будет искать переменную окружения + EDITOR +, чтобы найти предпочитаемый вами редактор. Если это не установлено, по умолчанию будет + vi +.

Если вы не хотите редактировать с помощью редактора + vi, вы должны установить переменную` + EDITOR of` в вашей среде.

Чтобы установить редактор для отдельной команды, добавьте к команде присвоение переменной среды, например:

EDITOR= ansible-vault

Чтобы сделать это постоянным, откройте файл + ~ / .bashrc +:

nano ~/.bashrc

Укажите предпочитаемый редактор, добавив присваивание + EDITOR + в конец файла:

~ / .Bashrc

export EDITOR=

Сохраните и закройте файл, когда вы закончите.

Снова загрузите файл, чтобы прочитать изменения в текущем сеансе:

. ~/.bashrc

Отобразите переменную + EDITOR +, чтобы проверить, что ваши настройки были применены:

echo $EDITOR
Output

Теперь, когда вы установили предпочитаемый редактор, мы можем обсудить доступные операции с помощью команды + ansible-vault +.

Как управлять конфиденциальными файлами с ansible-vault

Команда + ansible-vault + является основным интерфейсом для управления зашифрованным содержимым в Ansible. Эта команда используется для первоначального шифрования файлов и впоследствии используется для просмотра, редактирования или дешифрования данных.

Создание новых зашифрованных файлов

Чтобы создать новый файл, зашифрованный с помощью Vault, используйте команду + ansible-vault create +. Передайте имя файла, который вы хотите создать. Например, чтобы создать зашифрованный файл YAML с именем + vault.yml + для хранения конфиденциальных переменных, вы можете набрать:

ansible-vault create

Вам будет предложено ввести и подтвердить пароль:

OutputNew Vault password:
Confirm New Vault password:

Когда вы подтвердите свой пароль, Ansible немедленно откроет окно редактирования, где вы можете ввести желаемое содержимое.

Чтобы проверить функцию шифрования, введите тестовый текст:

vault.yml

Secret information

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

cat
Output$ANSIBLE_VAULT;1.1;AES256
65316332393532313030636134643235316439336133363531303838376235376635373430336333
3963353630373161356638376361646338353763363434360a363138376163666265336433633664
30336233323664306434626363643731626536643833336638356661396364313666366231616261
3764656365313263620a383666383233626665376364323062393462373266663066366536306163
31643731343666353761633563633634326139396230313734333034653238303166

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

Шифрование существующих файлов

Если у вас уже есть файл, который вы хотите зашифровать с помощью Vault, используйте команду + ansible-vault encrypt +.

Для тестирования мы можем создать файл примера, набрав:

echo 'unencrypted stuff' >

Теперь вы можете зашифровать существующий файл, набрав:

ansible-vault encrypt

Вам снова будет предложено ввести и подтвердить пароль. После этого сообщение подтвердит шифрование:

OutputNew Vault password:
Confirm New Vault password:
Encryption successful

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

Если мы проверим файл, мы должны увидеть похожий зашифрованный шаблон:

cat
Output$ANSIBLE_VAULT;1.1;AES256
66633936653834616130346436353865303665396430383430353366616263323161393639393136
3737316539353434666438373035653132383434303338640a396635313062386464306132313834
34313336313338623537333332356231386438666565616537616538653465333431306638643961
3636663633363562320a613661313966376361396336383864656632376134353039663662666437
39393639343966363565636161316339643033393132626639303332373339376664

Как вы можете видеть, Ansible шифрует существующий контент почти так же, как и новые файлы.

Просмотр зашифрованных файлов

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

Передайте зашифрованный файл хранилища команде:

ansible-vault view

Вам будет предложено ввести пароль файла. После успешного ввода его содержимое будет отображено:

OutputVault password:
Secret information

Как видите, запрос пароля смешивается с выводом содержимого файла. Помните об этом при использовании + ansible-vault view + в автоматизированных процессах.

Редактирование зашифрованных файлов

Когда вам нужно отредактировать зашифрованный файл, используйте команду + ansible-vault edit +:

ansible-vault edit

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

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

Расшифровка зашифрованных файлов вручную

Чтобы расшифровать зашифрованный файл хранилища, используйте команду + ansible-vault decrypt +.

Передайте имя зашифрованного файла:

ansible-vault decrypt

Вам будет предложено ввести пароль для шифрования файла. Как только вы введете правильный пароль, файл будет расшифрован:

OutputVault password:
Decryption successful

Если вы просматриваете файл снова, вместо шифрования хранилища, вы должны увидеть фактическое содержимое файла:

cat
OutputSecret information

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

Изменение пароля зашифрованных файлов

Если вам нужно изменить пароль зашифрованного файла, используйте команду + ansible-vault rekey +:

ansible-vault rekey

Когда вы вводите команду, вам сначала будет предложено ввести текущий пароль файла:

OutputVault password:

После его ввода вам будет предложено выбрать и подтвердить новый пароль хранилища:

OutputVault password:

После успешного подтверждения нового пароля вы получите сообщение об успешном завершении процесса повторного шифрования:

OutputRekey successful

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

Запуск Ansible с зашифрованными файлами

После того как вы зашифровали свою конфиденциальную информацию с помощью Vault, вы можете начать использовать файлы с помощью традиционных инструментов Ansible. Команды + ansible + и + ansible-playbook + знают, как дешифровать файлы, защищенные хранилищем, с помощью правильного пароля. Существует несколько различных способов предоставления паролей к этим командам в зависимости от ваших потребностей.

Чтобы продолжить, вам понадобится зашифрованный в хранилище файл. Вы можете создать его, набрав:

ansible-vault create secret_key

Выберите и подтвердите пароль. Заполните все пустышки, которые вы хотите:

Секретный ключ

Сохраните и закройте файл.

Мы также можем создать временный файл + hosts + в качестве инвентаря:

nano hosts

Мы добавим только Ansible localhost к нему. Чтобы подготовиться к следующему шагу, мы поместим его в группу + [база данных] +:

хостов

[database]
localhost ansible_connection=local

Сохраните и закройте файл, когда вы закончите.

Затем создайте файл + ansible.cfg + в текущем каталоге, если он еще не существует:

nano ansible.cfg

А пока просто добавьте раздел + [defaults] + и укажите Ansible для только что созданного инвентаря:

ansible.cfg

[defaults]
inventory = ./hosts

Когда вы будете готовы, продолжайте.

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

Самый простой способ расшифровки контента во время выполнения - попросить Ansible запросить соответствующие учетные данные. Вы можете сделать это, добавив + - ask-vault-pass + к любой команде + ansible + или + ansible-playbook +. Ansible запросит у вас пароль, который он будет использовать для расшифровки любого найденного содержимого, защищенного хранилищем.

Например, если нам нужно скопировать содержимое файла, зашифрованного в хранилище, на хост, мы можем сделать это с помощью модуля + copy + и флага + - ask-vault-pass +. Если файл на самом деле содержит конфиденциальные данные, вы, скорее всего, захотите заблокировать доступ на удаленном хосте с разрешениями и правами собственности.

ansible  -bK -m copy -a 'src= dest=/tmp/ mode=0600 owner=root group=root'

В нашей задаче указано, что владелец файла должен быть изменен на + root +, поэтому требуются права администратора. Флаг + -bK + указывает Ansible запрашивать пароль + sudo + для целевого хоста, поэтому у вас спросят пароль + sudo +. Затем вам будет предложено ввести пароль хранилища:

OutputSUDO password:
Vault password:

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

Outputlocalhost | SUCCESS => {
   "changed": true,
   "checksum": "7a2eb5528c44877da9b0250710cba321bc6dac2d",
   "dest": "/tmp/secret_key",
   "gid": 0,
   "group": "root",
   "md5sum": "270ac7da333dd1db7d5f7d8307bd6b41",
   "mode": "0600",
   "owner": "root",
   "size": 18,
   "src": "/home/sammy/.ansible/tmp/ansible-tmp-1480978964.81-196645606972905/source",
   "state": "file",
   "uid": 0
}

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

Использование Ansible Vault с файлом паролей

Если вы не хотите вводить пароль Vault при каждом выполнении задачи, вы можете добавить свой пароль Vault в файл и ссылаться на файл во время выполнения.

Например, вы можете поместить свой пароль в файл + .vault_pass + следующим образом:

echo '' > .vault_pass

Если вы используете контроль версий, обязательно добавьте файл паролей в файл игнорирования вашего программного обеспечения для контроля версий, чтобы избежать его случайной фиксации:

echo '.vault_pass' >> .gitignore

Теперь вы можете ссылаться на файл вместо. Флаг + - vault-password-file доступен в командной строке. Мы могли бы выполнить ту же задачу из последнего раздела, набрав:

ansible  -bK -m copy -a 'src= dest=/tmp/ mode=0600 owner=root group=root'

На этот раз вам не будет предложено ввести пароль хранилища.

Чтение файла паролей автоматически

Чтобы вообще не указывать флаг, вы можете установить переменную окружения + ANSIBLE_VAULT_PASSWORD_FILE с путем к файлу паролей:

export ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass

Теперь вы сможете выполнить команду без флага + - vault-password-file для текущего сеанса:

ansible -bK -m copy -a 'src= dest=/tmp/ mode=0600 owner=root group=root'

Чтобы Ansible знал о расположении файла паролей между сеансами, вы можете отредактировать файл + ansible.cfg +.

Откройте локальный файл + ansible.cfg +, который мы создали ранее:

nano ansible.cfg

В разделе + [defaults] + установите параметр + vault_password_file +. Укажите местоположение вашего файла паролей. Это может быть относительный или абсолютный путь, в зависимости от того, какой из них наиболее полезен для вас:

ansible.cfg

[defaults]
. . .
vault_password_file = ./.vault_pass

Теперь, когда вы запускаете команды, требующие расшифровки, вам больше не будет предложено ввести пароль хранилища. В качестве бонуса + ansible-vault + будет не только использовать пароль в файле для расшифровки любых файлов, но и будет применять пароль при создании новых файлов с помощью + ansible-vault create + и + ansible-vault encrypt + ,

Чтение пароля из переменной среды

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

Однако, если ваш файл паролей исполняемый, Ansible запустит его как скрипт и будет использовать полученный вывод в качестве пароля. В GitHub выпуск, Brian Schwind предлагает использовать следующий скрипт для извлечения пароля из переменной окружения.

Откройте ваш файл + .vault_pass + в вашем редакторе:

nano .vault_pass

Замените содержимое следующим скриптом:

vault_pass
#!/usr/bin/env python

import os
print os.environ['VAULT_PASSWORD']

Сделайте файл исполняемым, набрав:

chmod +x .vault_pass

Затем вы можете установить и экспортировать переменную окружения + VAULT_PASSWORD +, которая будет доступна для вашего текущего сеанса:

export VAULT_PASSWORD=

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

Использование зашифрованных переменных Vault с обычными переменными

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

Настройка примера

Представьте, что вы настраиваете сервер базы данных. Когда вы создали файл + hosts + ранее, вы поместили запись + localhost + в группу под названием + database +, чтобы подготовиться к этому шагу.

Для баз данных обычно требуется сочетание чувствительных и нечувствительных переменных. Они могут быть назначены в каталоге + group_vars + в файле с именем группы:

mkdir -p group_vars
nano group_vars/database

Внутри файла + group_vars / database + установите несколько переменных. Некоторые переменные, такие как номер порта MySQL, не являются секретными и могут свободно распространяться. Другие переменные, такие как пароль базы данных, будут конфиденциальными:

group_vars / база данных

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password:

Мы можем проверить, что все переменные доступны нашему хосту с помощью модуля Ansible + debug и переменной` + hostvars`:

ansible -m debug -a 'var=hostvars[inventory_hostname]'
Outputlocalhost | SUCCESS => {
   "hostvars[inventory_hostname]": {
       "ansible_check_mode": false,
       "ansible_version": {
           "full": "2.2.0.0",
           "major": 2,
           "minor": 2,
           "revision": 0,
           "string": "2.2.0.0"
       },
       "group_names": [
           "database"
       ],
       "groups": {
           "all": [
               "localhost"
           ],
           "database": [
               "localhost"
           ],
           "ungrouped": []
       },
       "inventory_dir": "/home/sammy",
       "inventory_file": "hosts",
       "inventory_hostname": "localhost",
       "inventory_hostname_short": "localhost",




       "omit": "__omit_place_holder__1c934a5a224ca1d235ff05eb9bda22044a6fb400",
       "playbook_dir": "."
   }
}

Вывод подтверждает, что все переменные, которые мы установили, применяются к хосту. Однако наш файл + group_vars / database + в настоящее время содержит все наши переменные. Это означает, что мы можем либо оставить его незашифрованным, что является проблемой безопасности из-за переменной пароля базы данных, либо зашифровать все переменные, что создает проблемы удобства использования и совместной работы.

Перемещение чувствительных переменных в Ansible Vault

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

Можно использовать каталог переменных вместо переменной Ansible file, чтобы применять переменные из более чем одного файла. Мы можем рефакторинг, чтобы воспользоваться этой способностью. Сначала переименуйте существующий файл из + database в в` + var`. Это будет наш незашифрованный переменный файл:

mv group_vars/database group_vars/vars

Затем создайте каталог с тем же именем, что и у старого файла переменных. Переместите файл + vars + внутрь:

mkdir group_vars/database
mv group_vars/vars group_vars/database/

Теперь у нас есть каталог переменных для группы + database in вместо одного файла, и у нас есть один незашифрованный файл переменных. Поскольку мы будем шифровать наши конфиденциальные переменные, мы должны удалить их из нашего незашифрованного файла. Отредактируйте файл + group_vars / database / vars +, чтобы удалить конфиденциальные данные:

nano group_vars/database/vars

В этом случае мы хотим удалить переменную + mysql_password +. Теперь файл должен выглядеть так:

group_vars / базы данных / вары

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

Затем создайте зашифрованный в хранилище файл в каталоге, который будет находиться вместе с незашифрованным файлом + vars +:

ansible-vault create group_vars/database/vault

В этом файле определите чувствительные переменные, которые были в файле + vars +. Используйте те же имена переменных, но добавьте строку + vault_ +, чтобы указать, что эти переменные определены в файле, защищенном хранилищем:

group_vars / базы данных / хранилище

---
mysql_password:

Сохраните и закройте файл, когда вы закончите.

Результирующая структура каталогов выглядит так:

.
├── . . .
├── group_vars/
│   └── database/
│       ├── vars
│       └── vault
└── . . .

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

Чтобы решить эту проблему, проект Ansible обычно рекомендует немного другой подход.

Ссылка на переменные хранилища из незашифрованных переменных

Когда мы переместили наши конфиденциальные данные в файл, защищенный хранилищем, мы предваряли имена переменных с помощью + vault_ + (+ mysql_password + стал + vault_mysql_password +). Мы можем добавить исходные имена переменных (+ mysql_password +) обратно в незашифрованный файл. Вместо того, чтобы устанавливать их для чувствительных значений напрямую, мы можем использовать шаблонные операторы Jinja2 для ссылки на зашифрованные имена переменных из нашего незашифрованного файла переменных. Таким образом, вы можете увидеть все определенные переменные, ссылаясь на один файл, но конфиденциальные значения останутся в зашифрованном файле.

Чтобы продемонстрировать, снова откройте файл незашифрованных переменных:

nano group_vars/database/vars

Снова добавьте переменную + mysql_password +. На этот раз используйте шаблон Jinja2 для ссылки на переменную, определенную в файле, защищенном хранилищем:

group_vars / базы данных / вары

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password:

Переменная + mysql_password + будет установлена ​​в значение переменной + vault_mysql_password +, которая определена в файле хранилища.

С помощью этого метода вы можете понять все переменные, которые будут применены к хостам в группе + database +, просмотрев файл + group_vars / database / vars +. Чувствительные части будут скрыты шаблонами Jinja2. + Group_vars / database / vault + нужно открывать только тогда, когда сами значения необходимо просмотреть или изменить.

Вы можете убедиться, что все переменные + mysql _ * + по-прежнему правильно применяются, используя тот же метод, что и в прошлый раз.

ansible -m debug -a 'var=hostvars[inventory_hostname]'
Outputlocalhost | SUCCESS => {
   "hostvars[inventory_hostname]": {
       "ansible_check_mode": false,
       "ansible_version": {
           "full": "2.2.0.0",
           "major": 2,
           "minor": 2,
           "revision": 0,
           "string": "2.2.0.0"
       },
       "group_names": [
           "database"
       ],
       "groups": {
           "all": [
               "localhost"
           ],
           "database": [
               "localhost"
           ],
           "ungrouped": []
       },
       "inventory_dir": "/home/sammy/vault",
       "inventory_file": "./hosts",
       "inventory_hostname": "localhost",
       "inventory_hostname_short": "localhost",




       "omit": "__omit_place_holder__6dd15dda7eddafe98b6226226c7298934f666fc8",
       "playbook_dir": ".",

   }
}

И + vault_mysql_password + и + mysql_password + доступны. Такое дублирование безвредно и не повлияет на использование вами этой системы.

Заключение

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

Related