Как безопасно управлять секретами с помощью HashiCorp Vault в Ubuntu 16.04

Вступление

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

В этом уроке вы будете:

  • Установите Vault и настройте его как системную службу

  • Инициализировать зашифрованное хранилище данных на диске

  • Надежно храните и извлекайте конфиденциальное значение по TLS

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

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

Предпосылки

Прежде чем начать это руководство, вам понадобится следующее:

Шаг 1 - Установка Vault

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

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

wget https://releases.hashicorp.com/vault//vault__linux_amd64.zip

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

wget https://releases.hashicorp.com/vault//vault__SHA256SUMS

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

grep linux_amd64 vault_*_SHA256SUMS | sha256sum -c -

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

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

Outputvault__linux_amd64.zip:

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

sudo apt-get update
sudo apt-get install unzip

Затем разархивируйте двоичный файл Vault в рабочий каталог.

unzip vault_*.zip
OutputArchive:  vault__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, чтобы убедиться, что она работает.

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

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

Шаг 2 - Создание файла хранилища

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

  • Системный пользователь для запуска демона Vault от имени

  • Каталог данных для хранения информации Vault

  • Файл конфигурации Vault

  • Сам файл + systemd + unit.

Сначала создайте системного пользователя * vault *.

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

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

Установите право собственности на + / var / lib / vault + для пользователя * vault * и исключительно для группы * vault *.

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

Теперь давайте настроим файл конфигурации Vault + / etc / vault.hcl +. Вы будете использовать это для управления различными опциями в Vault, например, где хранятся зашифрованные секреты.

Создайте + vault.hcl +, используя + nano + или ваш любимый текстовый редактор.

sudo nano /etc/vault.hcl

Вставьте следующее в файл и убедитесь, что подставили под свое имя домена:

/etc/vault.hcl

backend "file" {
       path = "/var/lib/vault"
}

listener "tcp" {
       tls_disable = 0
       tls_cert_file = "/etc/letsencrypt/live//fullchain.pem"
       tls_key_file = "/etc/letsencrypt/live//privkey.pem"

}

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

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

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

Затем, чтобы позволить Systemd управлять постоянным демоном Vault, создайте файл unit в `+ / etc / systemd / система / vault.service + `.

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

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

/etc/systemd/system/vault.service

[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

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

  • + ConditionFileNotEmpty + гарантирует, что файл конфигурации + / etc / vault.hcl + существует.

  • + User и` + Group`, которые управляют пользовательскими правами, с которыми будет работать демон Vault.

  • + ExecStart +, который указывает на исполняемый файл, который мы установили ранее, и определяет, с чего начать запуск сервиса.

  • + ExecReload +, который вызывается, когда Vault перезагружает свой файл конфигурации, например, при запуске + systemctl reload vault +.

  • + [Install] +, что позволяет нам постоянно запускать этот сервис при запуске, поэтому нам не нужно запускать его вручную после перезагрузки.

Наконец, Vault требуется разрешение для чтения сертификатов, которые вы создали с помощью Certbot. По умолчанию эти сертификаты и закрытые ключи доступны только для * root *. Чтобы сделать их доступными безопасным образом, мы создадим специальную группу * 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 будет прослушивать только запросы от интерфейса обратной связи (+ lo + или адрес + 127.0.0.1 +). Это делается для того, чтобы служба не была доступна общедоступному Интернету до того, как она была должным образом защищена. Вы можете обновить это позже, но сейчас это изменение конфигурации позволит нам использовать команду + vault + и правильно разрешить HTTPS-защищенное доменное имя.

Замените ++ в следующей команде доменом, для которого вы получили сертификат Let Encrypt:

echo 127.0.0.1  | sudo tee -a /etc/hosts

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

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

Шаг 3 - Инициализация Vault

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

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

sudo systemctl start vault

Вы можете выполнить быструю проверку, чтобы подтвердить, что служба успешно запущена.

sudo systemctl status vault

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

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

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

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

export VAULT_ADDR=https://:8200

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

Убедитесь, что хранилище находится в неинициализированном состоянии, проверив его состояние.

vault status

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

OutputError 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 предоставит во время инициализации, и которые не будут доступны в любой другой точке:

  • * Первоначальный корневой токен *. Это эквивалентно корневым разрешениям для вашего развертывания Vault, которое позволяет управлять всеми политиками Vault, монтированием и т. Д.

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

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

Типичное простое значение для параметров распечатки - создать три ключа и потребовать, по крайней мере, два из этих ключей одновременно. Это позволяет разделять важные ключевые ключи и хранить их в разных местах, чтобы компрометации не хватило для вскрытия Vault.

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

Инициализируйте Vault с вышеупомянутыми параметрами:

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

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

Теперь вы можете распечатать Vault, используя только что созданные токены. Начните с распечатывания, используя один ключ.

vault operator unseal

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

OutputKey (will be hidden):

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

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

Запустите команду + unseal + снова.

vault operator unseal

И введите токен, отличный от того, который вы уже использовали:

OutputKey (will be hidden):

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

OutputSeal 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 (например, чтение и запись значений), которые аутентифицируются tokens. На последнем шаге мы создадим необходимые токены и политики доступа для хранения секретных значений и чтения / записи по определенным путям в Vault.

Шаг 4 - Чтение и запись секретов

Существует несколько secret бэкэндов, перечисленных в документации по Vault, но в этом примере мы будем использовать https://www.vaultproject.io/docs/ secrets / generic / index.html [общий секретный бэкэнд]. Этот бэкэнд хранит простые пары ключ / значение в Vault.

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

root_token=

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

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

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

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

Создайте файл с именем + policy.hcl +.

nano policy.hcl

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

policy.hcl

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"

Вывод будет выглядеть так:

OutputKey             Value
---             -----
token
token_accessor  your_token_accessor
token_duration  768h0m0s
token_renewable true
token_policies  [default message-readonly]

Сохраните значение + token в переменную с именем` + id_token`.

app_token=

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

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

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

VAULT_TOKEN=$app_token vault list secret/
OutputError reading secret/: Error making API request.

URL: GET https://example.com:8200/v1/secret?list=true
Code: 403. Errors:

*

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

Заключение

В этой статье вы установили, настроили и развернули Vault в Ubuntu 16.04. Хотя в этом руководстве демонстрировалось использование только непривилегированного токена, документация Vault содержит дополнительную информацию о additions для хранения и доступа к секретам, а также https: //www.vaultproject.io/docs/auth/index.htm[al альтернативные методы аутентификации].

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

  • Создание менее привилегированных токенов для повседневного использования. Конкретные политики, которые должны использовать эти токены, зависят от конкретного варианта использования, но предыдущий + app_token + иллюстрирует, как можно создавать токены и политики с ограниченными правами.

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

Related