Безопасное управление конфиденциальными данными с помощью Vault в Ubuntu 16.04

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

В этом мануале вы:

  • Установите Vault и настроите его как системный сервис.
  • Инициализируете зашифрованное хранилище данных на диске.
  • Научитесь безопасно хранить и извлекать конфиденциальные значения по TLS.

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

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

Требования

1: Установка Vault

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

Сначала загрузите сжатый ZIP-архив Vault для 64-битной Linux. Вы можете найти ссылку на последнюю версию (0.9.5 на момент написания) на странице загрузки Vault.

wget https://releases.hashicorp.com/vault/0.9.5/vault_0.9.5_linux_amd64.zip

Затем загрузите контрольную сумму, чтобы проверить загрузку:

wget https://releases.hashicorp.com/vault/0.9.5/vault_0.9.5_SHA256SUMS

Затем проверьте целостность zip-архива. Команда подтвердит, что содержимое zip-архива соответствует версии 0.9.5 Vault от Hashicorp.

grep linux_amd64 vault_*_SHA256SUMS | sha256sum -c -

Каждая строка в файле SHA256SUMS имеет контрольную сумму и имя файла, по одному для каждого архива zip, который предоставляет HashiCorp. Компонент grep вышеприведенной команды выводит строку с контрольной суммой и именем 64-битного двоичного файла Linux, а затем передает (|) эту строку следующей команде. Команда SHA-256 подтверждает, что файл с таким именем в этой строке соответствует контрольной сумме из этой строки.

Команда подтвердит целостность архива:

vault_0.9.5_linux_amd64.zip: OK

Если этого не произошло, загрузите архив заново.

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

sudo apt-get update
sudo apt-get install unzip

Затем распакуйте бинарный файл Vault в рабочем каталоге:

unzip vault_*.zip
Archive:  vault_0.9.5_linux_amd64.zip
inflating: vault

Переместите исполняемый файл Vault в PATH, чтобы сделать его доступным в оболочке.

sudo cp vault /usr/local/bin/

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

sudo setcap cap_ipc_lock=+ep /usr/local/bin/vault

Теперь у вас есть доступ к команде vault. Запросите версию:

vault --version
Vault v0.7.2 ('d28dd5a018294562dbc9a18c95554d52b5d12390')

Vault успешно установлен на сервер.

2: Создание unit-файла Vault

Systemd – это система инициализации Ubuntu, которая, среди прочего, управляет сервисами системы. Чтобы установить Vault в качестве системного сервиса, необходимо настроить:

  • Системного пользователя, с помощью которого будет запускаться демон Vault.
  • Каталог данных для хранения информации Vault.
  • Конфигурационный файл Vault.
  • Unit-файл systemd.

Читайте также: Основы Systemd: управление сервисами и журналирование

Примечание: В этом мануале используется бэкэнд для хранения зашифрованных данных в локальной файловой системе в /var/lib/vault. Это подходит для локальных или односерверных развертываний, которые не требуют репликации. Другие бэкэнды Vault, такие как бэкэнд Consul, будут хранить зашифрованные секретные данные в распределенном хранилище «ключ-значение».

Создайте пользователя vault:

sudo useradd -r -d /var/lib/vault -s /bin/nologin vault

Здесь в качестве домашнего каталога пользователя используется /var/lib/vault. Он также будет каталогом данных Vault. Также нужно настроить оболочку /bin/nologin для ограничения пользователя и настройки неинтерактивной системной учетной записи.

Передайте права на /var/lib/vault пользователю и группе vault.

sudo install -o vault -g vault -m 750 -d /var/lib/vault

Теперь нужно настроить конфигурационный файл Vault, /etc/vault.hcl. Он нужен для управления различными опциями Vault (например, здесь можно указать, где хранятся зашифрованные секретные данные). Создайте файл.

sudo nano /etc/vault.hcl

Вставьте в файл следующие строки:

backend "file" {
path = "/var/lib/vault"
}
listener "tcp" {
tls_disable = 0
tls_cert_file = "/etc/letsencrypt/live/example.com/fullchain.pem"
tls_key_file = "/etc/letsencrypt/live/example.com/privkey.pem"
}

Согласно этому конфигурационному файлу Vault хранит зашифрованные секреты в /var/lib/vault на диске и прослушивает соединения через HTTPS, используя сертификаты, созданные в мануале по Let’s Encrypt.

Сохраните и закройте файл, а затем ограничьте доступ к Vault, передав право на чтение пользователю vault.

sudo chown vault:vault /etc/vault.hcl
sudo chmod 640 /etc/vault.hcl

Чтобы система systemd управляла демоном Vault, создайте unit-файл /etc/systemd/system/vault.service.

sudo nano /etc/systemd/system/vault.service

Скопируйте и вставьте в файл следующие строки. Это позволит Vault работать в фоновом режиме в качестве постоянного системного демона.

[Unit]
Description=a tool for managing secrets
Documentation=https://vaultproject.io/docs/
After=network.target
ConditionFileNotEmpty=/etc/vault.hcl
[Service]
User=vault
Group=vault
ExecStart=/usr/local/bin/vault server -config=/etc/vault.hcl
ExecReload=/usr/local/bin/kill --signal HUP $MAINPID
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
Capabilities=CAP_IPC_LOCK+ep
SecureBits=keep-caps
NoNewPrivileges=yes
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target

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

  • ConditionFileNotEmpty подтверждает, что /etc/vault.hcl существует.
  • User и Group управляют правами демона Vault.
  • ExecStart указывает на исполняемый файл, который вы установили ранее, и определяет, как запустить сервис.
  • ExecReload вызывается, когда Vault перезагружает конфигурационный файл (например, при запуске systemctl reload vault).
  • [Install] позволяет автоматически запускать сервис во время загрузки, чтобы вам не пришлось этого делать вручную.

Vault нужны права на чтение сертификатов, созданных с помощью Certbot. По умолчанию эти сертификаты и закрытые ключи доступны только пользователю root. Чтобы сделать их доступными для Vault, но не открывать всем, создайте специальную группу pki для доступа к этим файлам, а затем добавьте в нее пользователя vault.

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

Создайте группу pki:

sudo groupadd pki

Обновите права доступа к каталогам в /etc/letsencrypt, чтобы группа pki могла прочитать содержимое.

sudo chgrp pki /etc/letsencrypt/{archive,live}
sudo chmod g+rx /etc/letsencrypt/{archive,live}

Затем добавьте пользователя vault в группу pki. Это предоставит Vault доступ к сертификатам, чтобы он мог безопасно обрабатывать запросы по HTTPS.

sudo gpasswd -a vault pki

Теперь для удобства добавьте правило в /etc/hosts, чтобы направлять запросы Vault на localhost.

По умолчанию Vault будет слушать запросы только из интерфейса loopback (lo, или 127.0.0.1). Это делается, чтобы сервис не имел выхода в интернет до того, как он будет полностью защищен. Вы можете изменить это позже. На данный момент этот параметр позволит вам использовать команду vault и правильно разрешать имя домена, защищенное HTTPS.

Замените example.com в следующей команде своим  доменом, на который вы получили сертификат Let’s Encrypt:

echo 127.0.0.1 example.com | sudo tee -a /etc/hosts

Это добавит строку 127.0.0.1 example.com в /etc/hosts, благодаря чему любые HTTP-запросы на example.com направляются на localhost.

Теперь можно запустить Vault и инициализировать хранилище конфиденциальных данных.

3: Инициализация Vault

При первом запуске Vault не будет инициализирован – то есть пока что он не будет готов к получению и хранению данных. Бэкэнд, который фактически хранит зашифрованные секретные данные, тоже не инициализирован. Запустите сервис Vault, чтобы инициализировать бэкэнд и запустить Vault.

sudo systemctl start vault

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

sudo systemctl status vault

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

. . .
Active: active (running)
. . .

Если сервис не активен, посмотрите на сопровождающие строки логов в конце вывода команды, чтобы понять, в чем проблема.

Затем установите переменную среды, чтобы сообщить команде vault, как подключиться к серверу Vault. На данный момент Vault прослушивает только локальный интерфейс loopback, поэтому установите в переменной VAULT_ADDR локальную конечную точку HTTPS.

export VAULT_ADDR=https://example.com:8200

Команда vault теперь может взаимодействовать с демоном. Обратите внимание, что вместо простого localhost или 127.0.0.1 необходимо указать имя хоста для проверки сертификата HTTPS.

Убедитесь, что хранилище vault не было инициализировано.

vault status

Сервер должен вернуть ошибку 400, что говорит о том, что хранилище не инициализировано

Error checking seal status: Error making API request.
URL: GET https://example.com:8200/v1/sys/seal-status
Code: 400. Errors:
* server is not yet initialized

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

  • Исходный токен root: эквивалентен правам root на развертывание Vault, что позволяет управлять всеми политиками Vault, монтированием и т. д.
  • Ключи разблокировки: используются для вскрытия Vault при запуске демона, что позволяет демону Vault расшифровывать хранилище секретных данных бэкэнда.

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

Обычно запрашивается три ключа вскрытия, два из которых используется непосредственно в момент вскрытия. Благодаря этому недостаточно взломать один ключ, чтобы вскрыть Vault.

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

Инициализируйте Vault с такими параметрами:

vault init -key-shares=3 -key-threshold=2

Сохраните токены для вкрытия и исходный токен root в безопасном месте. Например, можно сохранить один токен вскрытия в диспетчере паролей, второй на USB-накопителе, а третий в GPG-зашифрованном файле.

Теперь вы можете вскрыть хранилище с помощью токенов. Начните с одного ключа.

vault operator unseal

Команда запросит токен:

Key (will be hidden):

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

Sealed: true
Key Shares: 3
Key Threshold: 2
Unseal Progress: 1
Unseal Nonce: 3bdc838e-1b74-bc13-1d6f-c772f1694d83

Еще раз запустите команду unseal:

vault operator unseal

Введите второй токен:

Key (will be hidden):

Вывод команды указывает, что процесс вскрытия и завершен успешно.

Seal Type       shamir
Sealed          false
Total Shares    3
Threshold       2
Version         0.9.5
Cluster Name    vault-cluster-5511b3ff
Cluster ID      53522534-8ee1-8aec-86db-e13e4a499dd0
HA Enabled      false

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

Тем не менее, вскрытие не является частью обычного взаимодействия с Vault (как, например, чтение и запись значений), которое аутентифицируется токенами. На последнем этапе нужно создать токены доступа и политики для хранения секретных значений.

4: Чтение и запись конфиденциальных данных

Vault предоставляет документацию по нескольким бэкэндам. В данном примере используется бэкэнд generic. Он хранит простые пары «ключ-значение».

Сохраните сгенерированные ранее токены в переменную оболочки.

root_token=your_root_token_here

Для начала запишите значение в путь в Vault.

VAULT_TOKEN=$root_token vault write secret/message value=mypassword

В этой команде префикс secret/ указывает на то, что данные пишутся на общий бэкэнд, смонтированный в пути secret. Ключ value хранится в пути message  со значением mypassword. Для этого использовался токен root, который имеет привилегии суперпользователя.

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

Создайте файл policy.hcl.

nano policy.hcl

Добавьте в файл следующую политику Vault, которая определяет доступ только для чтения к секретному пути в рабочем каталоге:

path "secret/message" {
capabilities = ["read"]
}

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

Запишите политику в Vault. Следующая команда создаст политику message-readonly:

VAULT_TOKEN=$root_token vault policy write message-readonly policy.hcl

Создайте токен с объявленными в политике правами.

VAULT_TOKEN=$root_token vault token create -policy="message-readonly"
Key             Value
---             -----
token           your_token_value
token_accessor  your_token_accessor
token_duration  768h0m0s
token_renewable true
token_policies  [default message-readonly]

Сохраните токен в переменную app_token.

app_token=your_token_value

Вы можете использовать значение app_token только для доступа к данным, хранящимся в пути secret/message.

VAULT_TOKEN=$app_token vault read secret/message
Key                     Value
---                     -----
refresh_interval        768h0m0s
value                   mypassword

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

VAULT_TOKEN=$app_token vault list secret/
Error reading secret/: Error making API request.
URL: GET https://example.com:8200/v1/secret?list=true
Code: 403. Errors:
* permission denied

Это подтверждает, что менее привилегированный токен приложения не причинит вреда данным или не получит доступ к другим секретным значениям.

Заключение

Теперь вы умеете устанавливать, настраивать и инициализировать хранилище Vault в Ubuntu 16.04. В документации Vault есть информация о дополнительных способах хранения и доступа к секретным данным, а также об альтернативных методах аутентификации.

Инструкции в документации довольно простые. Некоторые изменения, которые следует внести:

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