Перейти к содержанию

Резервное копирование и восстановление

Всё долговременное состояние Umbryx лежит в двух местах: volume PostgreSQL и каталог /data. Для рабочего восстановления нужны оба.

Что включать в резервную копию

Объект Содержимое Зачем
Volume PostgreSQL (сервис db) все сущности, пользователи, audit-события база данных
DATA_DIR (по умолчанию ./data) загрузки, loot-файлы (зашифрованные), JSONL-зеркало аудита, secret.key, файл с паролем админа файлы + сгенерированные ключи
.env ENCRYPTION_KEY, JWT_SECRET, пароли БД/Redis без ENCRYPTION_KEY зашифрованные данные невосстановимы

Процедура

# бэкап
docker compose exec db pg_dump -U umbryx umbryx | gzip > umbryx-$(date +%F).sql.gz
tar czf umbryx-data-$(date +%F).tar.gz data/            # включает secret.key
cp .env umbryx-env-$(date +%F).backup                    # хранить надёжно

# восстановление (свежий хост или после аварии)
docker compose up -d db
gunzip -c umbryx-<date>.sql.gz | docker compose exec -T db psql -U umbryx umbryx
tar xzf umbryx-data-<date>.tar.gz
cp umbryx-env-<date>.backup .env
docker compose up -d

Держите .env (с ключом шифрования) в secret-менеджере, а не рядом с резервными копиями.

Ротация ключа при восстановлении

Если ENCRYPTION_KEY должен смениться — сначала восстановитесь со старым ключом, затем выполните ротацию ключа с помощью backend/scripts/rekey.py:

OLD_KEY=<old> NEW_KEY=<new> python3 backend/scripts/rekey.py --dry-run
OLD_KEY=<old> NEW_KEY=<new> python3 backend/scripts/rekey.py   # остановите API

Скрипт перешифровывает секреты учётных данных, зашифрованные notes/loot, loot-файлы и токены C2-интеграций одной транзакцией. Per-project DEK ротируются отдельно (POST /api/system/encryption/rotate-dek).

Верификация после восстановления

  1. /api/health возвращает ok
  2. Войдите; откройте проект с известными учётными данными и раскройте один секрет — расшифровка восстановленным ключом должна работать
  3. Скачайте loot-файл (проходит через файловое шифрование)
  4. GET /api/admin/audit/verify — отчёт о целостности событий timeline (при заданном AUDIT_INTEGRITY_KEY)

Режимы отказа

Симптом Причина
Секреты отдают ошибки расшифровки неверный/потерянный ENCRYPTION_KEY — намеренно невосстановимо
Вход не работает ни у кого JWT_SECRET отличается от того, которым были подписаны сессии, — войдите заново; если файл пароля админа потерян — сброс через БД или путь first-run
Loot-файлы скачиваются мусором data-volume не восстановлен или ключ не совпадает