MAATRIX / Блог / Бэкап и восстановление PowerDNS

Бэкап и восстановление PowerDNS

MAATRIX

Если вы держите собственные доменные зоны на PowerDNS с базой данных вместо файлов, то простой cp -r вам не поможет — зоны, записи, DNSSEC-ключи и метаданные разбросаны по таблицам, и восстановить всё это «на глаз» после сбоя почти невозможно. Ниже — рабочая схема бэкапа и восстановления PowerDNS с бэкендами MySQL и PostgreSQL, которую можно развернуть за вечер и не вспоминать о ней до реального инцидента.

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

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

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

Почему PowerDNS требует отдельного подхода к бэкапам

PowerDNS Authoritative Server в связке с БД-бэкендом хранит всё состояние в реляционной базе: таблицы domains, records, domainmetadata, cryptokeys, comments, supermasters. Никаких зонных файлов на диске нет — есть только pdns.conf с параметрами подключения к БД. Это удобно (можно менять записи через API или веб-панель, а не редактировать текст), но означает, что бэкап сервера DNS фактически сводится к бэкапу базы данных плюс конфигурации.

Есть три уровня, которые нужно закрыть отдельно:

  • Данные зон — сами домены и записи в таблицах domains/records.
  • DNSSEC-материал — приватные ключи в cryptokeys, без них подписанная зона не восстановится, даже если записи на месте.
  • Конфигурация процесса/etc/powerdns/pdns.conf, файлы pdns.d/*.conf, systemd-юниты, TSIG-ключи для AXFR между мастером и слейвами.

Если бэкапите только записи через pdnsutil list-all-zones и pdnsutil export-zone — вы получите зоны без DNSSEC-ключей, и после восстановления придётся заново подписывать зону новыми ключами. Это меняет DS-записи у регистратора и на несколько часов ломает резолвинг для доменов с DNSSEC. Поэтому дамп БД целиком — не опция, а необходимость.

Бэкап MySQL-бэкенда PowerDNS

Если PowerDNS настроен через gmysql, конфигурация в pdns.conf выглядит примерно так:

launch=gmysql
gmysql-host=127.0.0.1
gmysql-dbname=pdns
gmysql-user=pdns
gmysql-password=пароль_из_секретов

Полный дамп базы — стандартный mysqldump с флагом --single-transaction, чтобы не блокировать таблицы во время снятия дампа на живом сервере:

mysqldump \
  --single-transaction \
  --routines \
  --triggers \
  -u pdns -p pdns > /var/backups/pdns/pdns_db_$(date +%F).sql

Для InnoDB-таблиц (а PowerDNS их создаёт по умолчанию) --single-transaction даёт консистентный снимок без блокировки чтения/записи, поэтому DNS-сервер продолжает отвечать на запросы во время бэкапа. Если у вас база на MyISAM (старые установки, миграции с bind-конфигураций) — --single-transaction не сработает, там нужен --lock-tables, и это уже короткая пауза записи.

Сразу сжимайте дамп — файл с полным набором зон при тысячах записей может быть заметным:

mysqldump --single-transaction -u pdns -p pdns | gzip > /var/backups/pdns/pdns_db_$(date +%F).sql.gz

Если база PowerDNS небольшая и крутится на том же сервере, где вы настраивали и другие сервисы MySQL, общие принципы бэкапа MySQL и его частые проблемы разобраны в статье про бэкап MySQL на сервере — там же про восстановление из повреждённого дампа.

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

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

Арендовать сервер

Бэкап PostgreSQL-бэкенда PowerDNS

Для gpgsql-бэкенда конфигурация похожа:

launch=gpgsql
gpgsql-host=127.0.0.1
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-password=пароль_из_секретов

Дамп через pg_dump в custom-формате — он компактнее текстового SQL и позволяет восстанавливать отдельные таблицы, а не всю базу целиком:

pg_dump -U pdns -h 127.0.0.1 -Fc pdns > /var/backups/pdns/pdns_db_$(date +%F).dump

Если PowerDNS и другие сервисы на сервере используют один и тот же PostgreSQL-кластер, обычно проще бэкапить через pg_dumpall для ролей и глобальных объектов плюс pg_dump -Fc для самой базы pdns:

pg_dumpall -U postgres --roles-only > /var/backups/pdns/roles_$(date +%F).sql
pg_dump -U pdns -Fc pdns > /var/backups/pdns/pdns_db_$(date +%F).dump

Базовая установка и настройка PostgreSQL под такие сценарии подробно описана в статье как установить и настроить PostgreSQL на VPS, если разворачиваете стек с нуля.

Отдельный нюанс: если зон много (сотни-тысячи) и записи меняются часто (например, через API от внешнего биллинга), имеет смысл включить WAL-архивирование PostgreSQL и делать PITR (point-in-time recovery) вместо ежедневного полного дампа — это позволяет откатиться на конкретную минуту перед сбойным изменением зоны, а не только на состояние вчерашней ночи.

DNSSEC-ключи и конфигурация: отдельный бэкап

Даже если у вас есть полный дамп БД, стоит держать отдельную «страховочную» копию именно ключей — на случай, если понадобится быстро поднять записи на другом сервере без полного восстановления базы. Экспорт ключей делается через pdnsutil:

for zone in $(pdnsutil list-all-zones); do
  pdnsutil export-zone-key $zone active > /var/backups/pdns/keys/${zone}.key 2>/dev/null
done

Это выгружает приватные ключи в формате BIND, которые можно импортировать обратно командой pdnsutil import-zone-key. Храните этот каталог с ограниченными правами (chmod 700) — это приватные ключи, компрометация которых позволяет подделывать подписи для ваших зон.

Также заберите конфигурационные файлы, которые не лежат в базе:

tar czf /var/backups/pdns/config_$(date +%F).tar.gz \
  /etc/powerdns/pdns.conf \
  /etc/powerdns/pdns.d/ \
  /etc/systemd/system/pdns.service.d/ 2>/dev/null

Если используете AXFR-репликацию между мастером и слейвами, TSIG-ключи для этого тоже хранятся в БД (таблица tsigkeys), так что при дампе базы они уже под защитой — отдельно выгружать не нужно, но проверьте это явно: SELECT * FROM tsigkeys; в дампе должна быть непустой, если репликация настроена.

Восстановление зон: пошагово и с проверкой

Восстановление — это не просто «залить дамп обратно», а последовательность с проверкой на каждом шаге, иначе легко получить сервер, который стартует, но отдаёт неправильные ответы.

1. Останавливаем PowerDNS, чтобы не было гонки между процессом восстановления и живыми запросами к БД:

systemctl stop pdns

2. Восстанавливаем базу. Для MySQL:

gunzip -c /var/backups/pdns/pdns_db_2026-08-30.sql.gz | mysql -u pdns -p pdns

Для PostgreSQL (custom-формат, -c очищает существующие объекты перед восстановлением):

pg_restore -U pdns -h 127.0.0.1 -d pdns -c /var/backups/pdns/pdns_db_2026-08-30.dump

3. Проверяем целостность зон до запуска сервиса наружу:

pdnsutil check-all-zones

Команда пройдётся по всем зонам в базе и покажет ошибки — отсутствующие SOA-записи, некорректные серийные номера, разорванные DNSSEC-цепочки. Если зона помечена DNSSEC, но cryptokeys пустая (например, вы восстановили только таблицу records отдельным дампом, а не всю базу), check-all-zones укажет на это явно.

4. Запускаем сервис и проверяем резолвинг сначала локально, потом снаружи:

systemctl start pdns
dig @127.0.0.1 ваш-домен.ru SOA +short
dig @127.0.0.1 ваш-домен.ru A +short

Серийный номер SOA — первое, что стоит сверить с тем, что было до сбоя (если он есть в мониторинге или в логах). Если это слейв с AXFR от мастера, дайте ему время на pdns_control notify или дождитесь планового AXFR-опроса, прежде чем считать восстановление завершённым.

Общий процесс восстановления БД из дампа с типичными граблями (несовпадение версий сервера, кодировки, права доступа) разобран в статье восстановление базы данных из бэкапа на практике — рекомендации оттуда применимы и к базе PowerDNS.

Автоматизация бэкапов и хранение вне сервера

Ручной бэкап полезен один раз — как учебное упражнение. В проде нужен cron-скрипт с ротацией и выгрузкой копии за пределы сервера, иначе бэкап на том же диске, что и оригинал, не спасёт при отказе диска или компрометации сервера целиком.

Простой скрипт для ежедневного запуска (пример для PostgreSQL-бэкенда):

#!/bin/bash
set -euo pipefail

BACKUP_DIR=/var/backups/pdns
DATE=$(date +%F)
KEEP_DAYS=14

mkdir -p "$BACKUP_DIR"/{db,keys,config}

pg_dump -U pdns -Fc pdns > "$BACKUP_DIR/db/pdns_db_$DATE.dump"

for zone in $(pdnsutil list-all-zones); do
  pdnsutil export-zone-key "$zone" active \
    > "$BACKUP_DIR/keys/${zone}.key" 2>/dev/null || true
done

tar czf "$BACKUP_DIR/config/config_$DATE.tar.gz" \
  /etc/powerdns/pdns.conf /etc/powerdns/pdns.d/

find "$BACKUP_DIR/db" -name "*.dump" -mtime +"$KEEP_DAYS" -delete

Добавьте в cron:

15 3 * * * /usr/local/bin/pdns-backup.sh >> /var/log/pdns-backup.log 2>&1

Для выгрузки за пределы сервера — на S3-совместимое хранилище, другой VPS или объектное хранилище — удобно использовать rclone, настройка которого под такие сценарии разобрана в статье бэкап и восстановление через rclone. Добавьте в тот же скрипт финальный шаг:

rclone copy "$BACKUP_DIR/db/pdns_db_$DATE.dump" remote:pdns-backups/db/
rclone copy "$BACKUP_DIR/keys/" remote:pdns-backups/keys/ --update

Мониторинг стоит настроить минимум по двум точкам: что бэкап-скрипт вообще отработал без ошибок (через set -euo pipefail и алерт на ненулевой код выхода) и что размер последнего дампа не упал аномально по сравнению со средним за неделю — резкое уменьшение файла обычно означает, что дамп снят с пустой или недоступной базы, а не что зон стало меньше.

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

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

Арендовать сервер

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

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

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

Обязательно ли бэкапить всю БД, если PowerDNS — не единственный сервис в этом кластере MySQL/PostgreSQL?

Нет, можно бэкапить только базу pdns отдельным mysqldump/pg_dump с указанием конкретной базы — не обязательно снимать дамп всего инстанса. Это и быстрее, и восстанавливать проще, не задевая другие базы на том же сервере.

Что делать, если после восстановления зона с DNSSEC не резолвится?

Первым делом проверьте pdnsutil check-zone имя_зоны — если ключи не восстановились (например, дамп был неполным), придётся либо импортировать ключи из отдельного бэкапа через pdnsutil import-zone-key, либо пересоздавать подпись через pdnsutil secure-zone и обновлять DS-запись у регистратора, что означает временный простой DNSSEC-валидации для этого домена.

Как часто нужно делать полный бэкап, если зоны меняются редко?

Даже при редких изменениях зон делайте ежедневный дамп — он маленький по объёму и стоит копейки места, а без него вы рискуете потерять историю изменений при инциденте, случившемся между «редкими» правками. Дневная ротация на 14 дней покрывает большинство сценариев отката.

Можно ли восстанавливать PowerDNS из бэкапа на сервере с другой версией PowerDNS?

В пределах одной мажорной версии — как правило, да, схема БД стабильна. При переходе через мажорные версии (например, с 4.7 на 4.9) сверьтесь с release notes: иногда добавляются новые колонки или меняются индексы, и потребуется прогнать миграционные SQL-скрипты из комплекта PowerDNS перед восстановлением дампа старого формата.

Нужно ли останавливать PowerDNS на слейв-серверах при восстановлении мастера?

Нет, слейвы продолжают отвечать на запросы из своей локальной копии (полученной по AXFR) и подхватят актуальные данные после следующего успешного трансфера с восстановленного мастера — это и есть смысл держать слейвы отдельно от единой точки отказа.

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

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

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