Связка BIND и PowerDNS: корпоративный DNS, который переживёт любой сбой
Семёнов Евгений Сергеевич, директор АйТи Фреш. DNS — невидимая основа всей сетевой инфраструктуры. Когда он падает или отдаёт неправильные ответы, ломается всё сразу: почта, сайты, VPN, сервисы. У нас на практике я всегда разношу DNS на два разных движка — BIND и PowerDNS — именно ради защиты от уязвимостей: когда выйдет очередной CVE на одну реализацию, вторая продолжит работать. Разберём, как собрать такую архитектуру из коробки за два рабочих дня.
Зачем мешать два движка
Стандартная схема — master + два slave — уязвима к багам в самом софте. BIND и PowerDNS — разные кодовые базы, написанные разными командами, на разных языках. Совмещая, вы получаете:
- Страховку от CVE: критическая уязвимость в BIND не затронет PowerDNS, и наоборот.
- Гибкость управления: BIND — текстовые файлы и notify/xfer, PowerDNS — база данных и REST API.
- Разные профили производительности: BIND выигрывает на кэш-рекурсии, PowerDNS — на авторитативных запросах с БД.
- Поддержку разных сценариев: PowerDNS Recursor + BIND Authoritative или наоборот.
Целевая схема
Типовая инфраструктура, которую я разворачиваю:
| Роль | Движок | Где стоит |
|---|---|---|
| Master авторитативный | BIND9 | Офис HQ, за файрволом |
| Slave авторитативный | PowerDNS | DMZ, открытый в интернет |
| Slave авторитативный #2 | BIND9 | Второй офис |
| Рекурсор для офиса | Unbound или BIND | Внутри корпоративной сети |
Установка BIND9 как master
apt update
apt install -y bind9 bind9utils dnsutils
# /etc/bind/named.conf.options
options {
directory "/var/cache/bind";
recursion no;
allow-query { any; };
allow-transfer { key "powerdns-tsig"; };
also-notify { 192.0.2.20; }; # PowerDNS slave
notify yes;
listen-on { 192.0.2.10; 127.0.0.1; };
listen-on-v6 { none; };
};
# TSIG-ключ для безопасной репликации
key "powerdns-tsig" {
algorithm hmac-sha256;
secret "сгенерированный_base64_ключ";
};
Генерация TSIG-ключа:
tsig-keygen -a hmac-sha256 powerdns-tsig
Описание зоны в BIND
# /etc/bind/named.conf.local
zone "corp.example.ru" {
type master;
file "/etc/bind/zones/db.corp.example.ru";
allow-transfer { key "powerdns-tsig"; };
also-notify { 192.0.2.20 key "powerdns-tsig"; };
};
# /etc/bind/zones/db.corp.example.ru
$TTL 3600
@ IN SOA ns1.corp.example.ru. hostmaster.corp.example.ru. (
2025080801 ; serial
3600 ; refresh
900 ; retry
1209600 ; expire
300 ; minimum
)
IN NS ns1.corp.example.ru.
IN NS ns2.corp.example.ru.
ns1 IN A 192.0.2.10
ns2 IN A 192.0.2.20
www IN A 192.0.2.100
mx01 IN A 192.0.2.50
@ IN MX 10 mx01.corp.example.ru.
named-checkconf
named-checkzone corp.example.ru /etc/bind/zones/db.corp.example.ru
systemctl restart bind9
Установка PowerDNS как slave
apt install -y pdns-server pdns-backend-mysql mariadb-server
# Инициализация схемы БД
mysql -e "CREATE DATABASE pdns CHARACTER SET utf8mb4"
mysql -e "CREATE USER 'pdns'@'localhost' IDENTIFIED BY 'strongpass'"
mysql -e "GRANT ALL ON pdns.* TO 'pdns'@'localhost'"
mysql pdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql
# /etc/powerdns/pdns.conf
launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=pdns
gmysql-password=strongpass
gmysql-dbname=pdns
slave=yes
master=no
allow-notify-from=192.0.2.10/32
local-address=192.0.2.20
api=yes
api-key=REST_API_KEY
webserver=yes
webserver-port=8081
systemctl restart pdns
Регистрация зоны-slave в PowerDNS
# Через pdnsutil
pdnsutil create-slave-zone corp.example.ru 192.0.2.10
# Добавление TSIG-ключа
pdnsutil import-tsig-key powerdns-tsig hmac-sha256 'сгенерированный_base64_ключ'
pdnsutil activate-tsig-key corp.example.ru powerdns-tsig slave
# Принудительный AXFR
pdns_control retrieve corp.example.ru
Через 30 секунд проверяем:
dig @192.0.2.20 corp.example.ru SOA
dig @192.0.2.20 www.corp.example.ru A
DNSSEC на авторитативных
DNSSEC включаем на master и slaves с одним набором ключей. В BIND9:
# Добавляем в zone-блок
zone "corp.example.ru" {
...
inline-signing yes;
auto-dnssec maintain;
key-directory "/etc/bind/keys";
};
# Генерация ключей
cd /etc/bind/keys
dnssec-keygen -K . -a RSASHA256 -b 2048 -n ZONE corp.example.ru
dnssec-keygen -K . -a RSASHA256 -b 4096 -f KSK -n ZONE corp.example.ru
chown -R bind:bind /etc/bind/keys
chmod 600 /etc/bind/keys/*
rndc reload corp.example.ru
PowerDNS получает подписанную зону через AXFR и отдаёт клиентам уже с RRSIG-записями. Отдельная настройка подписи на slave не нужна.
Split-horizon (views) для внутренних и внешних клиентов
# BIND с двумя views
acl "internal" { 10.0.0.0/8; 192.168.0.0/16; };
acl "external" { any; };
view "internal" {
match-clients { internal; };
recursion yes;
zone "corp.example.ru" {
type master;
file "/etc/bind/zones/corp.example.ru-internal";
};
};
view "external" {
match-clients { external; };
recursion no;
zone "corp.example.ru" {
type master;
file "/etc/bind/zones/corp.example.ru-external";
};
};
В internal-зоне пишем внутренние IP (10.x), в external — публичные. Для PowerDNS аналогичную схему даёт Lua-бэкенд с geoip или простым if/else по адресу клиента.
Реальный кейс: DNS на 5 площадок
В январе 2025 пришёл клиент — холдинг с 5 площадками в ЦФО (Москва HQ, производство в Подольске, 3 филиала в регионах). Старый DNS — два BIND на одной площадке, при падении канала в HQ падал весь холдинг. Задача — географически распределённый DNS с репликацией, защита от CVE, split-horizon для внутренних и публичных зон.
Что внедрили за 4 рабочих дня:
- Master BIND9 в HQ на нашем Dell Xeon Platinum 8280, изолированный от интернета.
- Slave PowerDNS в DMZ HQ, открытый 53/udp и 53/tcp.
- Slave BIND9 в дата-центре МТС Москва (наша инфраструктура).
- По одному slave PowerDNS в каждом из 3 филиалов (Linux-виртуалки 2 vCPU / 2 ГБ RAM).
- TSIG-аутентификация для всех AXFR/IXFR, DNSSEC на публичных зонах.
- Split-horizon: внутренние зоны отдаются с внутренних IP, публичные — с внешних.
- Мониторинг здоровья всех 7 серверов через Prometheus blackbox-exporter, алерты в Telegram.
Стоимость проекта 148 000 руб. Через месяц в Подольске упал интернет на 6 часов — внутренние сервисы продолжали работать на локальном slave, внешние резолвы получали ответы от PowerDNS в DMZ HQ. Клиент не заметил.
Мониторинг и эксплуатация
# Проверка зоны с разных серверов
for ns in 192.0.2.10 192.0.2.20 10.1.1.53 10.2.1.53 10.3.1.53; do
echo "=== $ns ==="
dig @$ns corp.example.ru SOA +short
done
# Serial должен совпадать везде — иначе репликация сломана
# Prometheus-метрики PowerDNS
pdns_control get-all | head -30
# BIND stats-channels на порту 8053
curl http://127.0.0.1:8053/xml/v3/server | xmllint --format -
Практические советы
- TTL на важные записи (MX, NS) — 3600 и больше; на записи для failover — 60-300 секунд.
- Serial в SOA — строго по формату YYYYMMDDNN, никогда не уменьшайте.
- Notify-to-slave должен работать, иначе slaves синхронятся только по refresh.
- Логи BIND включите в отдельный файл:
channelс уровнем info — обычно хватает 30-дневной ротации. - Бэкап зон PowerDNS:
pdnsutil list-zone corp.example.ru > backup.txtили mysqldump всей БД. - Раз в квартал учения: отключайте master, проверяйте, что slaves отвечают, записи актуальны.
Поднимем отказоустойчивый DNS для вашей инфраструктуры
Проектирую и внедряю корпоративный DNS на BIND+PowerDNS: master-slave, DNSSEC, split-horizon, мониторинг. В АйТи Фреш 15+ лет в сетевой инфраструктуре, свои 8 серверов в дата-центре МТС Москва с 40G Mellanox. Базовая схема на 3 сервера — 1 рабочая неделя, стоимость от 75 000 руб.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — частые вопросы о BIND и PowerDNS
- Зачем использовать два разных движка DNS?
- Страховка от уязвимостей: когда выходит CVE на BIND, атакованными оказываются только серверы на BIND, PowerDNS продолжает работать.
- BIND и PowerDNS совместимы по протоколу?
- Да, оба поддерживают стандартный AXFR/IXFR. BIND может быть master для PowerDNS-slave и наоборот с использованием TSIG.
- Как управлять зонами PowerDNS?
- Через REST API (порт 8081) или PowerDNS-Admin. Зоны хранятся в БД, управление удобнее чем в файлах BIND.
- DNSSEC — нужен ли в корпоративной сети?
- Для публичных зон обязателен. Для внутренних — по желанию: в крупных компаниях включают для защиты от spoofing внутри сети.
- Как сделать failover между площадками?
- DNS round-robin с короткими TTL и скриптом обновления, или GeoDNS через PowerDNS Lua-бэкенд.