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

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

MAATRIX

Если у вас упал сервер с BIND9, а бэкапа зон нет — вы теряете не файлы, а домен: пока не восстановите авторитетные записи, сайты и почта клиентов не резолвятся. BIND9 — стандарт де-факто среди DNS-серверов, но именно из-за его гибкости (динамические зоны, DNSSEC, множество способов деплоя) наивный «скопировать /etc/bind» часто оставляет систему в нерабочем состоянии. Разберём, что именно нужно бэкапить, как делать это консистентно и как восстанавливаться так, чтобы новый сервер поднялся с первого раза.

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

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

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

Что на самом деле нужно бэкапить

BIND9 хранит состояние не в одном месте, и потеря любого из компонентов ломает картину по-разному.

  • Конфигурация: named.conf, named.conf.options, named.conf.local, named.conf.default-zones (Debian/Ubuntu) или /etc/named.conf и /etc/named/ (AlmaLinux/RHEL). Без этого сервер не знает, какие зоны обслуживать и с какими ACL.
  • Файлы зон — обычно /etc/bind/zones/ или /var/named/. Здесь лежит собственно содержимое DNS.
  • Journal-файлы (*.jnl) — для зон с динамическим обновлением (DDNS, ISC DHCP, nsupdate) актуальные данные могут быть только в journal, а не в текстовом файле зоны, пока не выполнен rndc sync. Забыть про них — самая частая причина «восстановили бэкап, а половина записей старая».
  • Ключи rndc.key и TSIG-ключи для zone transfer между мастером и слейвами.
  • DNSSEC-ключи (Kexample.com.+008+12345.key/.private) и файл состояния dnssec-policy при использовании inline-signing.
  • /var/cache/bind бэкапить не нужно — это кэш резолвера, он пересоберётся сам.

Права доступа критичны: приватные DNSSEC-ключи и rndc.key должны оставаться 600, владелец bind:bind (Debian) или named:named (RHEL-семейство). Обычный tar с последующим chmod -R на восстановлении — типичная ошибка, из-за которой сервер стартует, но не может подписывать зоны.

Ручной бэкап: делаем снимок консистентным

Прежде чем архивировать зону с динамическими обновлениями, нужно «заморозить» её, чтобы файл на диске совпадал с тем, что реально отдаётся в ответах:

# синхронизировать все динамические зоны из памяти на диск
sudo rndc sync -clean

# либо для конкретной зоны
sudo rndc sync example.com IN

# заморозить зону перед бэкапом (опционально, для зон с частыми апдейтами)
sudo rndc freeze example.com
sudo rndc thaw example.com

rndc sync -clean дописывает данные из journal в файл зоны и подчищает journal — именно этот шаг чаще всего пропускают. После синхронизации архивируем:

sudo mkdir -p /root/bind9-backup
sudo tar czf /root/bind9-backup/bind9-$(date +%F).tar.gz \
  /etc/bind \
  /var/lib/bind \
  --exclude='/etc/bind/zones/*.jnl'

Journal-файлы после rndc sync -clean можно исключить — они пусты или неактуальны сразу после синка. Если синхронизацию сделать не удалось (например, зона занята), лучше включить .jnl в архив, чем потерять данные.

Отдельно сохраните вывод текущей конфигурации на случай, если распакованный named.conf ссылается на include-файлы вне архива:

sudo named-checkconf -p > /root/bind9-backup/named-conf-dump-$(date +%F).txt

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

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

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

Автоматизация: cron-скрипт и ротация

Ручной бэкап забывается, поэтому нужен скрипт по расписанию. Вот рабочий вариант для Ubuntu/Debian:

#!/bin/bash
# /usr/local/sbin/bind9-backup.sh
set -euo pipefail

DEST=/var/backups/bind9
DATE=$(date +%F-%H%M)
RETAIN_DAYS=14

mkdir -p "$DEST"

# синхронизируем динамические зоны перед снимком
rndc sync -clean

tar czf "$DEST/bind9-$DATE.tar.gz" \
  /etc/bind \
  /var/lib/bind \
  --exclude='*.jnl'

# ротация: удаляем всё старше RETAIN_DAYS
find "$DEST" -name 'bind9-*.tar.gz' -mtime +"$RETAIN_DAYS" -delete

echo "$(date -Iseconds) backup ok: bind9-$DATE.tar.gz" >> /var/log/bind9-backup.log
sudo chmod 750 /usr/local/sbin/bind9-backup.sh
sudo crontab -e
# добавить строку:
0 3 * * * /usr/local/sbin/bind9-backup.sh

Локальная копия на том же диске не спасёт при потере сервера целиком — архивы нужно выгружать за пределы машины. Для этого удобно взять restic или borgbackup: оба умеют дедупликацию, шифрование и удалённые бэкенды (S3, SFTP, Backblaze). Если ещё не выбрали инструмент, сравнение подходов есть в статье restic или borgbackup: что выгоднее и когда. Минимальный вариант с restic:

export RESTIC_REPOSITORY=sftp:backup-user@backup-host:/backups/bind9
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic backup /var/backups/bind9/bind9-$(date +%F)*.tar.gz
restic forget --keep-daily 14 --keep-weekly 8 --prune

Если сервер с BIND9 — часть более крупной системы (DNS + другие сервисы на одной машине), может быть проще снимать образ всего диска, а не собирать точечные скрипты под каждый сервис — подход разобран в статье бэкап всего сервера целиком.

DNSSEC: отдельная головная боль

Если зоны подписаны DNSSEC, бэкап без приватных ключей делает восстановление зоны бессмысленным — придётся заново генерировать KSK/ZSK и заново проходить процедуру обновления DS-записи у регистратора, а это часы или дни простоя валидации (пока TTL старых DS не истечёт у резолверов).

Ключи лежат там же, где named.conf их ищет — обычно /etc/bind/keys/ или отдельная директория, заданная в dnssec-policy. Проверить, что реально используется:

sudo named-checkconf -p | grep -A3 dnssec-policy
sudo rndc dnssec -status example.com

Обязательно включайте в бэкап:

  • все .key и .private файлы для зоны;
  • файл состояния KASP (dnssec-policy), если используется автоматическая ротация ключей;
  • временные метки последней подписи — при восстановлении «старого» состояния ключей проверьте, не истекли ли RRSIG-подписи (dnssec-verify).

После восстановления обязательно прогоните:

sudo named-checkzone example.com /etc/bind/zones/db.example.com
sudo dnssec-verify -o example.com /etc/bind/zones/db.example.com

Если подписи протухли (это происходит, если сервер простоял без пересоздания подписей дольше sig-validity-interval), проще пересоздать подпись зоны, чем гадать — rndc sign example.com при inline-signing или dnssec-signzone вручную.

Восстановление: пошагово на новом сервере

Сценарий: старый сервер недоступен, поднимаем BIND9 с нуля на новой VPS.

  1. Установить BIND9 той же мажорной версии (или новее — обратная совместимость обычно держится, но для DNSSEC-политик лучше не понижать версию):
sudo apt update && sudo apt install -y bind9 bind9utils dnsutils
  1. Остановить службу, чтобы не конфликтовать с распаковкой:
sudo systemctl stop bind9
  1. Распаковать архив, сохранив владельца и права:
sudo tar xzpf bind9-2026-08-20.tar.gz -C /

Флаг p (preserve permissions) обязателен — иначе приватные ключи получат права по умолчанию, и named откажется их читать (в логах будет permission denied при старте).

  1. Проверить владельца — если восстанавливаете на новый сервер, где UID/GID bind могли не совпасть с исходным:
sudo chown -R bind:bind /etc/bind /var/lib/bind
sudo chmod 600 /etc/bind/rndc.key /etc/bind/keys/*.private
  1. Проверить конфигурацию и зоны до старта службы:
sudo named-checkconf /etc/bind/named.conf
for zone in /etc/bind/zones/db.*; do
  sudo named-checkzone "$(basename "$zone" | sed 's/^db\.//')" "$zone"
done

named-checkconf без ошибок не гарантирует, что зоны валидны — обязательно проверяйте каждую отдельно, named-checkzone ловит битые серийные номера и синтаксические ошибки, которые не всплывут при простом старте службы.

  1. Запустить и проверить статус:
sudo systemctl start bind9
sudo systemctl status bind9
sudo journalctl -u bind9 -n 50 --no-pager
  1. Проверить резолвинг снаружи, а не только локально — вопрос к своему же серверу может отвечать из кэша:
dig @<IP-нового-сервера> example.com SOA +short
dig @<IP-нового-сервера> example.com AXFR   # если разрешён transfer

Если сервер выполнял и рекурсивные, и авторитетные функции — не забудьте перепроверить ACL (allow-recursion, allow-query-cache), их часто теряют при частичном восстановлении конфигов.

Тестирование бэкапов и мониторинг актуальности

Бэкап, который никто не пробовал развернуть, — это не бэкап, а надежда. Минимальная практика:

  • раз в квартал разворачивайте последний архив на тестовой VPS с закрытым от внешнего мира портом 53 (или в изолированной сети) и прогоняйте named-checkconf + named-checkzone по всем зонам;
  • сверяйте serial номер в бэкапе с текущим serial на проде — если они совпадают дольше ожидаемого TTL обновлений, значит бэкап-скрипт либо не запускается, либо архивирует старую копию:
dig example.com SOA +short | awk '{print $3}'
  • если используете слейв-серверы, проверяйте, что зона реплицируется (rndc retransfer example.com на слейве) — рабочий слейв с актуальной копией зоны фактически второй бэкап «в горячем виде», хотя конфиг и ключи он не хранит.

Если DNS для домена настраивался «с нуля» и вы ещё не уверены в структуре зон, полезно свериться со статьёй настройка домена и DNS с нуля на Debian 12 — там описано, какие записи обязательны для рабочего домена, и это ровно тот набор, который должен пережить восстановление без потерь.

Частые ошибки при бэкапе и восстановлении

ОшибкаПоследствиеКак избежать
Забыли rndc sync перед архивомДинамические записи (DDNS/DHCP) в бэкапе устаревшиеВсегда синхронизировать journal перед tar
tar без флага p при восстановленииПрава на приватные ключи слетают, named не стартуетИспользовать tar xzpf, затем явно chown/chmod
Бэкапится только named.conf, без include-файловВосстановленный конфиг не находит зоныАрхивировать всю директорию /etc/bind, а не отдельные файлы
DNSSEC-ключи не входят в архивЗону приходится переподписывать заново, простой на смену DSЯвно проверить путь к ключам через named-checkconf -p
Бэкап только локально на том же дискеПри потере сервера бэкап теряется вместе с нимВыгружать архив на внешний сервер/S3 через restic/borg
Не проверяется serial после восстановленияСлейвы или резолверы держат устаревшую версию зоныСверять dig SOA на проде и в бэкапе перед закрытием инцидента

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

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

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

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

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

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

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

Нужно ли останавливать BIND9 перед бэкапом?

Нет, если сначала выполнить rndc sync -clean — это безопасно снимет снимок без остановки службы. Останавливать нужно только на этапе восстановления, перед распаковкой архива поверх существующих файлов.

Как часто делать бэкап DNS-сервера?

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

Что делать, если потерян только rndc.key, а зоны целы?

Сгенерировать новый ключ (rndc-confgen -a), прописать его на всех слейвах и в утилитах управления. Домены при этом продолжают резолвиться — rndc.key нужен только для административных команд и zone transfer с TSIG, а не для ответа на DNS-запросы.

Можно ли восстановить BIND9 на сервере с другой ОС (например, с Ubuntu на AlmaLinux)?

Да, но пути отличаются (/etc/bind vs /etc/named, пользователь bind vs named) — переносите не директории целиком, а содержимое: конфиг, зоны, ключи, — и адаптируйте named.conf под новые пути.

Как понять, что DNSSEC-подписи в восстановленном бэкапе ещё валидны?

Прогнать dnssec-verify -o <zone> <файл-зоны> сразу после восстановления. Если подписи истекли, зона будет отдавать записи, но валидирующие резолверы (с включённым DNSSEC) начнут получать SERVFAIL.

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

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

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