Перейти к основному содержимому

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

MonoPbx создаёт резервные копии Postgres (один согласованный снимок), ClickHouse (записи вызовов, качество связи, события, журнал аудита и журналы приложений), секретов установки, включая главный ключ, несекретной конфигурации, а также, если вы это запросите, записей разговоров и голосовой почты. Всё шифруется парольной фразой, которую вы выбираете, и записывается в локальный каталог, в сервис, совместимый с S3, или в Google Cloud Storage. Для восстановления на новом сервере нужны две вещи: резервная копия и её парольная фраза.

:::warning Сохраните парольную фразу MonoPbx не может её восстановить. Храните копию вне сервера. Без неё резервная копия бесполезна. :::

Что входит в резервную копию​

ЧастьСодержимое
postgresВсе таблицы: компании, пользователи, внутренние номера, транки, настройки, зашифрованные секреты, сертификаты и сами настройки резервного копирования.
clickhouseЗаписи вызовов, участки вызова, качество связи, события вызовов, журнал аудита и журналы приложений. Необязательно.
secretsГлавный ключ и его идентификатор, пара ключей подписи JWT, пара ключей ретранслятора и секрет автоматической настройки. Пароли к базам данных и токен установки не входят в резервную копию: они принадлежат серверу.
configНесекретное окружение и любые указанные вами файлы конфигурации. При восстановлении они извлекаются для проверки, но не применяются.
objectsЗаписи разговоров и голосовая почта. Необязательно; каждый раз создаётся полная копия. Для крупных установок вместо этого используйте версионирование или репликацию бакета.

Намеренно не включаются: сеансы и refresh-токены (после восстановления все выходят из системы), очереди исходящих событий и история запусков резервного копирования. Valkey не резервируется: он хранит текущее состояние, которое восстанавливается при запуске.

Резервная копия — это каталог backups/<id>/ в месте назначения. Набор без manifest.json неполон и никогда не отображается в списке и не восстанавливается.

Безопасность​

Из парольной фразы (не менее 12 символов) с помощью Argon2id получается ключ. Каждая часть шифруется AES-256-GCM блоками с аутентификацией, поэтому любое изменение, усечение или перестановка приводят к ошибке открытия. Манифест содержит размер и SHA-256 каждой части, поэтому целостность можно проверить без парольной фразы. Парольная фраза никогда не читается из командной строки: используйте файл с правами 0600, стандартный ввод, переменную окружения или запрос.

Создание резервной копии​

Docker Compose​

В комплекте есть разовый сервис mpbx-ops (профиль ops, он никогда не запускается командой up):

cd deploy/compose/prod
umask 077; openssl rand -base64 24 > backup.pass # keep a copy OFF this host
docker compose run --rm --user "$(id -u):$(id -g)" -v "$PWD/backup.pass:/run/backup.pass:ro" \
mpbx-ops backup --passphrase-file /run/backup.pass --prune

Место назначения по умолчанию — ./backups (MPBX_BACKUP_DIR в .env). Скопируйте её туда, где она переживёт сервер. При установке на виртуальной машине запускайте Compose через sudo mpbx-ctl compose ....

По расписанию​

mpbx run включает планировщик. Задайте расписание и место назначения один раз через API: каждый узел проверяет время, и один из них выполняет каждый слот. Задание cron не требуется.

PUT /api/v1/system/backups/settings
{"enabled": true, "schedule": "daily", "run_hour": 2,
"retention": {"keep_last": 7, "keep_daily": 7, "keep_weekly": 4, "keep_monthly": 6},
"target": {"backend": "s3", "bucket": "pbx-backups", "prefix": "mpbx",
"region": "eu-central-1", "access_key_id": "...", "secret_access_key": "..."},
"passphrase": "..."}

POST /api/v1/system/backups/settings/check-target writes, reads back and deletes a test file
POST /api/v1/system/backups back up now (202 and a run to poll)
GET /api/v1/system/backups the sets on the target
GET /api/v1/system/backups/runs/{run_id} poll a run
POST /api/v1/system/backups/{id}/verify
DELETE /api/v1/system/backups/{id}

Для этих маршрутов нужно право system.settings:read или system.settings:write, которое есть у владельца системы и администратора системы. Место назначения и парольная фраза доступны только для записи и хранятся в зашифрованном виде. Неудачная плановая копия повторяется через 15 минут, по три попытки на каждый слот.

Примеры места назначения: {"backend":"local","root":"/var/backups/mpbx"}, {"backend":"s3",...} (добавьте endpoint и path_style для MinIO или других сервисов, совместимых с S3) и {"backend":"gcs","bucket":"...","service_account_path":"..."}. Не используйте бакет, в котором хранятся ваши записи разговоров, если можно этого избежать: резервная копия рядом с защищаемыми данными не переживёт потерю этого бакета.

Проверка​

mpbx backup verify latest --target ... # sizes and SHA-256 of every part
mpbx backup verify latest --target ... --passphrase-file ... # also decrypts every chunk
mpbx restore latest --target ... --passphrase-file ... --dry-run # a restore rehearsal

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

Восстановление на новом сервере​

  1. Установите, как обычно, и выполните mpbx init. Команда создаст новые секреты и базы данных. Пока не создавайте администратора и не запускайте mpbx.
  2. Запустите только базы данных: docker compose up -d --wait postgres valkey clickhouse.
  3. Сделайте резервную копию доступной для чтения на сервере и выполните:
docker compose run --rm --user "$(id -u):$(id -g)" -v "$PWD:/work" -v "$PWD/backup.pass:/run/backup.pass:ro" \
mpbx-ops restore latest --passphrase-file /run/backup.pass --sink env-file:/work/.env \
--extract-config /work/restored-config
docker compose up -d --wait

Восстановление останавливается на первой проблеме. Сначала проверяется парольная фраза (неверная ничего не меняет), затем проверяется каждая часть, требуется, чтобы эта версия знала ровно те миграции, которые есть в резервной копии (MPBX-BACKUP-SCHEMA-MISMATCH: восстановите версией, которая создала копию, а затем обновите её), отказывается работать с базой, в которой уже есть пользователи, если не указан --force, заменяет Postgres одной транзакцией, затем ClickHouse, а секреты приложения записывает последними.

После восстановления все входят в систему заново. Ключ восстановления восстановленного главного ключа — это тот, что был сохранён при создании исходной установки, а не тот, что напечатал новый сервер. Удалите все строки MPBX_SETUP_TOKEN_*, которые mpbx init оставил в .env.

Восстановить более раннее состояние работающей установки также можно маршрутом POST /api/v1/system/backups/{id}/restore (с парольной фразой этой резервной копии и идентификатором копии в качестве подтверждения), но только для резервной копии с тем же главным ключом. По окончании запуска перезапустите АТС.

Ограничения​

  • Таблицы ClickHouse согласованы по отдельности, но не между собой.
  • Копии объектов полные; инкрементального режима пока нет.
  • Резервная копия восстанавливается только на ту же версию схемы.
  • На одной установке одновременно выполняется только одна резервная копия или восстановление.
  • Периодические автоматические тестовые восстановления запланированы, но не реализованы.