Що не так із паролями в .env і в коді
Зберігання секретів — паролів баз даних, API-ключів, приватних ключів SSH — часто зводиться до файлу .env у корені проєкту. Файл випадково комітять у Git, копіюють цілком на бекап-сервер, читають через cat будь-яким процесом із доступом на сервер. Витік одного файлу розкриває одразу всі сервіси.
Проблема глибша, ніж «не комітити .env». У пароля в текстовому файлі немає історії звернень: невідомо, хто і коли його читав, не можна відкликати доступ одному співробітнику без зміни пароля для всіх інших. Саме для цього існують окремі системи зберігання секретів.
Змінні середовища: мінімальний рівень захисту
Поки Vault не розгорнутий, дотримуйтеся базових правил для змінних середовища:
- Файл
.envповинен мати права 600 і належати користувачу сервісу, а не root. - Додавайте
.envу.gitignoreдо першого коміту, а не після витоку. - Не передавайте секрети через аргументи командного рядка — вони видні у виводі
ps auxусім локальним користувачам. - У systemd використовуйте
EnvironmentFile=із правами 600, а неEnvironment=у юніті — юніт-файли читаються всіма.
chmod 600 /etc/myapp/.env
chown myapp:myapp /etc/myapp/.env
Це знижує ризик витоку, але не вирішує завдання ротації й аудиту — для цього потрібен окремий сервіс зберігання секретів, наприклад HashiCorp Vault.
HashiCorp Vault: як влаштоване зберігання секретів
Vault — сервер, який зберігає секрети в зашифрованому вигляді і видає їх за запитом через API, перевіряючи права клієнта. Три ключові поняття:
- Secrets engine — модуль зберігання: KV для пар ключ-значення, Database для тимчасових облікових записів MySQL і PostgreSQL, PKI для випуску сертифікатів.
- Seal і Unseal — Vault запускається в запечатаному стані, дані на диску зашифровані майстер-ключем. Розпечатати сервер можна лише зібравши 3 із 5 частин ключа.
- Lease і TTL — кожен виданий секрет живе обмежений час, після закінчення TTL він відкликається автоматично.
Така модель замінює статичні паролі короткоживучими токенами і дає повний журнал: хто, коли і який секрет запитав.
Встановлення Vault на VPS: покроково
Приклад для Ubuntu 24.04 на VDS із 2 ГБ RAM — мінімальна конфігурація для одного вузла:
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp.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
Налаштуйте бекенд зберігання у файлі /etc/vault.d/vault.hcl — для одного сервера підходить файловий storage, і запустіть сервіс:
sudo systemctl enable --now vault
export VAULT_ADDR='https://127.0.0.1:8200'
vault operator init
vault operator unseal
Команда vault operator init виводить 5 ключів розпечатування й один root-токен — збережіть їх у різних місцях, не на цьому ж сервері. Root-токен потрібен лише для первинного налаштування політик, після чого його краще відкликати.
Динамічні секрети для бази даних
Замість одного постійного пароля до MySQL налаштуйте Database secrets engine — Vault створюватиме тимчасовий обліковий запис на кожен запит:
vault secrets enable database
vault write database/config/mysql \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \
allowed_roles="app-role" \
username="vaultadmin" password="StrongRootPass"
vault write database/roles/app-role \
db_name=mysql \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; GRANT SELECT, INSERT, UPDATE ON appdb.* TO '{{name}}'@'%';" \
default_ttl="1h" max_ttl="24h"
Застосунок запитує облікові дані через API і отримує логін із TTL 1 година. Через годину обліковий запис видаляється автоматично, навіть якщо застосунок забув про нього. Компрометація одного токена не дає постійного доступу до бази.
Ротація, аудит і чек-лист
Увімкніть audit device, щоб кожен запит секрету записувався в лог:
vault audit enable file file_path=/var/log/vault_audit.log
Для статичних секретів налаштуйте ротацію за розкладом через cron-завдання з одночасним оновленням пароля в цільовій системі. Політики доступу видавайте за принципом мінімальних прав — окрема політика на кожен застосунок, а не спільний root-токен.
- Секрети не лежать у Git і не передаються через аргументи командного рядка.
- Файли зі змінними середовища мають права 600 і власника — користувача сервісу.
- Для баз даних використовуються динамічні секрети з TTL, а не постійний пароль.
- Root-токен Vault відкликаний після налаштування, для роботи — іменовані токени з політиками.
- Увімкнено audit log, доступ до нього обмежений окремою роллю.
Детальніше про шифрування самих файлів на диску — у статті про GPG-шифрування файлів і резервних копій, а про права доступу — у матеріалі про права на файли Linux. Загальний порядок налаштування нового сервера описано в чек-листі безпеки Linux-сервера.