Секреты в Git, в переменных окружения и в заметках администратора — распространённая практика, которая рано или поздно заканчивается утечкой. HashiCorp Vault решает задачу иначе: он не просто хранит пароли, а выдаёт их по запросу, на ограниченное время и только тем, кому это разрешено. Ниже — установка на собственный сервер, инициализация, модель политик, AppRole и повседневная диагностика. Примеры рассчитаны на Linux и один узел с хранилищем Raft.
Как устроен Vault
Vault — это сервер с HTTP API и набором подключаемых компонентов. Секреты лежат в storage backend — в простейшем случае в каталоге Raft, и шифруются барьером до записи на диск. При старте сервер запечатан: мастер-ключ разбит по схеме Шамира на несколько частей, и для распечатывания нужно собрать пороговое число. После распечатывания Vault выдаёт токены с TTL — и каждый токен привязан к политикам. Secrets engine отвечает за тип секрета: KV хранит статические значения, database выдаёт временные учётные записи. Auth method проверяет, кто пришёл: человек, приложение или другая система.
Установка из официального репозитория
Пакеты HashiCorp распространяются через собственный APT-репозиторий. Ключ и список источников добавляются один раз, дальше Vault обновляется с остальными пакетами.
sudo apt install gpg curl
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vault
Для RHEL-подобных систем используется DNF-репозиторий с тем же ключом. Пакет создаёт пользователя vault и unit-файл systemd — но конфигурацию нужно подготовить самостоятельно.
Конфигурация и первое распечатывание
Минимальный конфиг для одного узла выглядит так: Raft хранит данные в /opt/vault/data, listener слушает только localhost, TLS на этом этапе отключён, потому что доступ идёт через SSH-туннель. Для боевого контура TLS обязателен.
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-1"
}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = true
}
api_addr = "http://127.0.0.1:8200"
После запуска службы Vault отвечает, что запечатан. Инициализация создаёт ключи распечатывания и initial root token. Ключи нужно разложить по носителям и хранить офлайн; root token используется один раз — для создания административных политик, после чего его отзывают.
export VAULT_ADDR=http://127.0.0.1:8200
vault operator init -key-shares=5 -key-threshold=3
vault operator unseal
vault status
Статус показывает прогресс распечатывания. Если сервер перезагрузился, процедуру нужно повторить: Vault не хранит ключи на диске.
KV второго поколения
KV v2 добавляет версионирование, мягкое удаление и метаданные. Путь монтирования выбирается один раз; дальше секреты пишутся в data, а служебная информация лежит в metadata.
vault secrets enable -path=secret kv-v2
vault kv put secret/billing/db username=app password='CHANGE_ME'
vault kv get secret/billing/db
Команда kv get без версии возвращает последнюю. Откат к предыдущей версии делается командой rollback, а destroy удаляет данные безвозвратно. В политиках путь data и путь metadata указываются отдельно — это частая причина ошибок доступа.
Политики и AppRole
Политика описывает пути и разрешённые операции. Принцип минимальных привилегий здесь работает буквально: приложению нужен только read на конкретный префикс.
path "secret/data/billing/*" {
capabilities = ["read"]
}
path "secret/metadata/billing/*" {
capabilities = ["read", "list"]
}
AppRole — способ аутентификации для сервисов. role_id не является секретом — secret_id выдаётся приложению и может быть одноразовым или короткоживущим. После логина приложение получает токен с ограниченным TTL и обновляет его, пока сессия жива.
vault policy write billing-read billing.hcl
vault auth enable approle
vault write auth/approle/role/billing token_policies=billing-read token_ttl=1h token_max_ttl=4h
vault read auth/approle/role/billing/role-id
vault write -f auth/approle/role/billing/secret-id
vault write auth/approle/login role_id="$ROLE_ID" secret_id="$SECRET_ID"
Ответ login содержит client_token. Его передают в заголовке X-Vault-Token. Если приложение умеет только читать файлы, токен можно записать в tmpfs с правами 0400 и удалить при остановке.
Динамические учётные записи для PostgreSQL
Вместо статического пароля базы можно включить engine database: Vault сам создаст роль, выдаст пароль и удалит пользователя по истечении TTL.
vault secrets enable database
vault write database/config/billing plugin_name=postgresql-database-plugin \
allowed_roles=billing-ro \
connection_url="postgresql://{{username}}:{{password}}@127.0.0.1:5432/billing" \
username="vault" password="CHANGE_ME"
vault write database/roles/billing-ro db_name=billing \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';" \
default_ttl=1h max_ttl=24h
vault read database/creds/billing-ro
Ответ содержит username, password и lease_id. Продление аренды выполняется командой vault lease renew, отзыв — vault lease revoke. Для приложения это означает, что пароль живёт час, а не год.
Аудит и обслуживание
Аудит включается до того, как в Vault появятся реальные секреты. Файловый audit device пишет JSON-события с замаскированными чувствительными полями; сам файл нужно защищать и ротировать.
vault audit enable file file_path=/var/log/vault/audit.log
vault operator raft snapshot save /var/backups/vault.snap
Снимок Raft — корректный способ резервного копирования. Его можно снять на работающем узле и восстановить на другом. Проверять восстановление нужно заранее — иначе копия остаётся теоретической. Для диагностики полезны vault token lookup, vault operator raft list-peers и журнал systemd. Типичные ошибки — истёкший токен, неверный путь политики и попытка записи в запечатанный сервер.
Чек-лист эксплуатации
- Отдельный администратор вместо root token, сам root отозван.
- Ключи распечатывания на разных офлайн-носителях, доступ к ним по регламенту.
- TLS на listener, сетевой доступ закрыт файрволом.
- Политики с минимальными правами и регулярный пересмотр.
- Аудит включён, журнал защищён и ротируется.
- Снимки Raft снимаются по расписанию и проверяются восстановлением.
Итог
Vault стоит внедрять там, где секретов больше десятка и ими пользуются несколько сервисов. Он добавляет эксплуатационную сложность: распечатывание после перезагрузки, ротацию, резервные копии. Зато исчезают пароли в репозиториях и бессрочные учётные записи. Начните с KV v2 и AppRole, затем переведите базы на динамические пароли. Если нужен только менеджер паролей для людей, Vault избыточен — для этой задачи есть более простые решения.