MAATRIX / Блог / "HashiCorp Vault: управление секретами"

"HashiCorp Vault: управление секретами"

"HashiCorp Vault: управление секретами"

MAATRIX

Если у вас пять серверов и на каждом свой .env с паролями от базы, ключами API и токенами — рано или поздно кто-то из них утечёт в git-репозиторий, в лог или в бэкап, который лежит открытым на S3. HashiCorp Vault решает именно эту проблему: секреты хранятся в одном месте, доступ к ним контролируется политиками, а сами значения никогда не лежат в коде или конфигах открытым текстом. Разберём, как поставить Vault на VPS, разблокировать его после старта и настроить базовый доступ — с честной оговоркой, кому это реально нужно, а кому не стоит связываться.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Зачем Vault, а не просто .env-файлы

Пока у вас один сервер и одно приложение, .env с DATABASE_PASSWORD=... — нормальное решение. Проблемы начинаются, когда секретов и серверов становится много:

  • пароли и ключи расползаются по десяткам файлов, никто не помнит, где какой актуален;
  • ротация пароля означает ручной обход всех серверов и передеплой;
  • нет аудита — кто и когда читал секрет, непонятно;
  • секрет, случайно закоммиченный в репозиторий, живёт там вечно даже после удаления из HEAD.

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

Установка Vault на VPS

Официальный способ — репозиторий HashiCorp. На Ubuntu/Debian:

sudo apt update && sudo apt install -y gpg wget
wget -O- 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 -y vault
vault -version

Если предпочитаете контейнеры, есть официальный образ:

docker run -d --name vault \
  --cap-add=IPC_LOCK \
  -p 8200:8200 \
  -v vault-data:/vault/data \
  -v $(pwd)/vault-config:/vault/config \
  hashicorp/vault server -config=/vault/config/config.hcl

Оба пути равнозначны — пакет проще для systemd-интеграции и обновлений через apt, Docker удобнее, если у вас уже весь стек в контейнерах и есть приватный Docker registry для образов. Дальше в статье считаем, что Vault поставлен пакетом и работает как systemd-сервис vault.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Конфигурация и первый запуск

Минимальный конфиг для одного сервера — файл /etc/vault.d/vault.hcl:

storage "raft" {
  path    = "/opt/vault/data"
  node_id = "vault-node-1"
}

listener "tcp" {
  address       = "0.0.0.0:8200"
  tls_cert_file = "/etc/vault.d/tls/vault.crt"
  tls_key_file  = "/etc/vault.d/tls/vault.key"
}

api_addr     = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
ui           = true

Storage backend raft — встроенный, не требует внешней базы или Consul и подходит для одиночного сервера или небольшого кластера. TLS обязателен: без него токены и секреты будут передаваться по сети открытым текстом. Для теста можно временно поставить tls_disable = true в блоке listener, но в продакшене — только сертификат (Let's Encrypt через certbot тоже подойдёт).

Запуск:

sudo systemctl enable --now vault
export VAULT_ADDR="https://127.0.0.1:8200"
vault status

vault status на этом этапе покажет Sealed: true — это ожидаемо, Vault ещё не инициализирован.

Инициализация и unseal: ключевая концепция Vault

После установки и до первого запуска Vault не хранит никаких ключей шифрования — он их ещё не создал. Инициализация делает это один раз:

vault operator init

Команда выведет 5 unseal-ключей (Shamir's Secret Sharing) и root-токен. Сохраните их немедленно и не в этом же VPS — если сервер скомпрометируют, а ключи лежат рядом в текстовом файле, всё шифрование Vault теряет смысл. По умолчанию для разблокировки нужно 3 из 5 ключей.

Дальше — та самая идея, которую стоит понять один раз и запомнить: Vault по умолчанию "запечатан" (sealed) после каждого запуска или перезапуска процесса. Это не баг и не лишний шаг — это осознанная защита: даже если атакующий получит полный доступ к диску сервера, зашифрованные данные Vault останутся бесполезны без unseal-ключей, которые физически не хранятся вместе с данными. Разблокировка:

vault operator unseal   # ввести первый ключ
vault operator unseal   # ввести второй ключ
vault operator unseal   # ввести третий ключ

После третьего ключа Sealed станет false. При каждом перезапуске сервиса (обновление, перезагрузка сервера) unseal нужно повторять вручную — либо настраивать auto-unseal через внешний KMS (AWS KMS, GCP KMS), что для одного VPS обычно избыточно.

Залогиньтесь root-токеном для дальнейшей настройки:

vault login <root-token>

Базовые операции: vault kv put/get

Включите KV-движок версии 2 (хранит историю версий секрета):

vault secrets enable -path=secret kv-v2

Запись секрета:

vault kv put secret/myapp/database \
  username="app_user" \
  password="Sup3rSecretPass!"

Чтение:

vault kv get secret/myapp/database

Только значение конкретного поля — удобно для скриптов:

vault kv get -field=password secret/myapp/database

Из приложения секреты обычно читают через API (curl, официальные клиентские библиотеки для Go/Python/Node) или через Vault Agent, который сам аутентифицируется и кладёт актуальные значения в файл на диске перед стартом сервиса — так код приложения вообще не знает про Vault. Это удобнее, чем вручную прокидывать .env, особенно если приложение запущено в Docker Compose и секреты нужны нескольким контейнерам сразу.

Политики доступа (policies)

Root-токен — это ключ от всего, использовать его в приложениях нельзя. Политики (policies) описывают, к каким путям и с какими правами у токена есть доступ. Пример myapp-policy.hcl:

path "secret/data/myapp/*" {
  capabilities = ["read"]
}

path "secret/data/myapp/database" {
  capabilities = ["read", "update"]
}

Применение и выпуск ограниченного токена:

vault policy write myapp-policy myapp-policy.hcl
vault token create -policy="myapp-policy" -ttl="720h"

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

Для сервисов на серверах вместо статических токенов лучше настроить auth-метод AppRole: приложение аутентифицируется парой role_id/secret_id, а сам secret_id можно ротировать без пересоздания политик. Это отдельная тема, но именно так Vault используют в реальных пайплайнах CI/CD.

Когда Vault оправдан, а когда это лишнее

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

  • ещё один сервис, который надо мониторить, обновлять и бэкапить;
  • ручной unseal после каждого перезапуска (или отдельную настройку auto-unseal);
  • новую точку отказа — если Vault недоступен, приложения, которые читают секреты при старте, не запустятся.

Для такого сценария разумнее использовать простой .env с правильными правами доступа (chmod 600), не хранить его в git и, если нужна дополнительная защита — зашифрованный файл через sops или ansible-vault, без отдельного сервера.

Vault оправдан, когда:

СценарийНужен ли Vault
Один сервер, один проектНет — .env + sops/ansible-vault
5-10 серверов, общие БД и API-ключиДа, если нужна ротация и аудит
Множество микросервисов, CI/CD с динамическими credentialsДа
Требования комплаенса (аудит доступа к секретам)Да
Команда из 1-2 человек, всё под контролемСкорее нет

Иными словами: Vault решает проблему координации доступа к секретам между многими людьми и сервисами. Если этой проблемы у вас пока нет — не создавайте её искусственно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Что делать, если потеряны unseal-ключи?

Ничего — это осознанное свойство защиты. Без кворума ключей (обычно 3 из 5) данные в Vault невозможно расшифровать даже разработчикам HashiCorp. Восстановление возможно только из бэкапа storage backend, сделанного до потери, либо через полную переинициализацию с потерей всех текущих секретов.

Нужно ли вводить unseal-ключи после каждой перезагрузки сервера?

Да, при обычной установке — это ручной шаг безопасности. Auto-unseal через внешний KMS убирает его, но добавляет зависимость от внешнего облачного сервиса, что для одиночного VPS не всегда оправдано.

Чем KV-движок Vault лучше зашифрованного .env-файла?

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

Можно ли использовать Vault только для хранения, без динамических секретов?

Да, статический KV-движок из этой статьи — легитимный и частый сценарий. Динамические секреты (временные учётные данные БД, облачные ключи) — более продвинутая возможность, которую можно подключить позже, когда появится реальная потребность.

Безопасно ли открывать порт 8200 наружу?

Только с TLS и firewall-правилами, ограничивающими доступ к конкретным IP серверов, которым нужен Vault. Для одного VPS часто проще держать Vault доступным только через localhost или внутреннюю сеть (VPN/WireGuard), а не через публичный интернет.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →