Связка BIND и PowerDNS: корпоративный DNS, который переживёт любой сбой
Привет! Я, Семёнов Евгений Сергеевич, директор АйТи Фреш. Знаете, DNS — это не просто запись в сети. Это невидимый фундамент, критически важный для всей нашей IT-инфраструктуры. Стоит ему только «заболеть» или начать выдавать странные ответы, и что? Почта встала, сайты не грузятся, VPN отвалился – словом, весь бизнес парализован. Неприятно, правда? Именно поэтому мы на своей практике всегда разделяем DNS на два совершенно разных движка: BIND и PowerDNS. Почему? Чтобы защититься от уязвимостей. Представьте: выходит новый критический CVE для BIND, а PowerDNS у нас продолжает работать как ни в чём не бывало, и наоборот. Вот почему мы покажем вам, как такую надёжную архитектуру реально собрать всего за пару рабочих дней, буквально «из коробки».
Зачем мешать два движка
Стандартная схема — master плюс два slave — очень уязвима к багам в самом софте. Но BIND и PowerDNS — это совсем другое дело. Их писали разные команды, на разных языках программирования. У них абсолютно разные кодовые базы. Когда мы их совмещаем, получаем сразу несколько преимуществ:
- Это настоящая страховка от CVE. Представьте: если в BIND обнаружится какая-то критическая уязвимость, PowerDNS продолжит спокойно работать, и наоборот. Ваша инфраструктура останется целой.
- Управление? Абсолютная гибкость! BIND работает с обычными текстовыми файлами и использует notify/xfer для синхронизации. А вот PowerDNS — это уже база данных и современный REST API. Выбирайте, что вам удобнее.
- В чем их сила? Разные профили производительности! BIND, например, просто незаменим на кэш-рекурсии. А PowerDNS? Он блестяще справляется с авторитативными запросами, работая через базу данных.
- Вы можете гибко подстраивать их под свои нужды, поддерживая самые разные сценарии. Хотите PowerDNS Recursor плюс BIND Authoritative? Пожалуйста! Или, наоборот, BIND как рекурсор, а PowerDNS как авторитативный? Легко!
Целевая схема
Вот как обычно выглядит типовая инфраструктура, которую мы разворачиваем:
| Роль | Движок | Где стоит |
|---|---|---|
| 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, и на slave-серверах. При этом используем единый набор ключей. Что касается 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";
};
};
Для split-horizon мы делаем так: в internal-зоне прописываем внутренние IP-адреса (например, из диапазона 10.x), а в external — разумеется, публичные. А для PowerDNS такую же схему можно реализовать с помощью гибкого Lua-бэкенда. Он умеет использовать geoip или простые if/else конструкции, чтобы определить адрес клиента и выдать ему правильный ответ.
Реальный кейс: DNS на 5 площадок
Помните, как в январе 2025 года к нам обратился крупный клиент? Это был холдинг с пятью площадками по всему ЦФО: головной офис в Москве, производство в Подольске и ещё три филиала в разных регионах. Их старая 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. Это лёгкие Linux-виртуалки: всего 2 vCPU и 2 ГБ оперативки, но этого вполне хватает для стабильной работы.
- Для безопасной передачи данных мы используем TSIG-аутентификацию абсолютно для всех запросов AXFR и IXFR. А для публичных зон, разумеется, включён DNSSEC — это наша гарантия целостности и подлинности данных.
- Применяем принцип Split-horizon: это значит, что внутренние зоны отдаются только с внутренних IP-адресов, обеспечивая приватность. А вот публичные зоны, наоборот, доступны с внешних IP. Всё чётко разделено!
- Мы постоянно следим за 'здоровьем' всех семи наших серверов. Для этого используем 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, мы ставим значительно меньший TTL: от 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-сервер, затем тщательно проверяем, что все slave-серверы корректно отвечают на запросы и что все записи актуальны. Это наша проверка боеготовности!
Поднимем отказоустойчивый 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-бэкенд.
