Новинка Виртуальный VDS сервер в Нидерландах от 490р
Выберите продукт

PowerDNS Authoritative с PostgreSQL: DNS-сервер на VDS

Пошагово поднимаем авторитативный DNS на PowerDNS и PostgreSQL: ставим пакеты, создаём базу, подключаем gpgsql, добавляем зону, открываем порт 53 и проверяем делегирование домена у регистратора.
PowerDNS Authoritative с PostgreSQL: DNS-сервер на VDS

PowerDNS Authoritative — удобный вариант, когда нужен собственный авторитативный DNS-сервер на VDS: для доменов проектов, SaaS-платформы, лаборатории, делегированных поддоменов или DNS-инфраструктуры с API и хранением зон в базе данных. В этой инструкции разберём связку PowerDNS + PostgreSQL: установим сервис, подготовим схему БД, создадим первую DNS-зону, добавим NS-записи, проверим ответы через dig и посмотрим, где чаще всего ломается делегирование.

Сразу уточню важный момент: authoritative DNS — это не кеширующий резолвер для клиентов. Он отвечает только за зоны, которыми вы управляете. PowerDNS Authoritative не должен использоваться как публичный рекурсивный DNS для всего интернета. Для рекурсии нужны отдельные решения и отдельная модель безопасности.

Если коротко: авторитативный сервер хранит «истину» о вашей зоне, а рекурсивный резолвер ищет ответ по цепочке от корневых серверов до авторитативных.

В статье я буду использовать домен example.net, имена серверов ns1.example.net и ns2.example.net, IPv4 203.0.113.10 и IPv6 2001:db8::10. Это документационные адреса: замените их на реальные IP вашего VDS и вашего домена.

Архитектура: что именно мы поднимаем

Минимальная схема выглядит так: на VDS работает PostgreSQL, в нём лежат таблицы зон PowerDNS, рядом запущен процесс pdns_server, который слушает порт 53/udp и 53/tcp. Когда приходит DNS-запрос, PowerDNS берёт данные из PostgreSQL через backend gpgsql и отдаёт ответ.

Почему PostgreSQL, а не обычные zone-файлы? У такого подхода есть несколько практичных плюсов. Во-первых, зоны проще менять программно: через SQL, API или административную панель. Во-вторых, данные удобно бэкапить штатными инструментами PostgreSQL. В-третьих, можно строить автоматизацию: выдавать поддомены клиентам, генерировать TXT-записи для проверок, синхронизировать зоны между сервисами.

Есть и цена: вы добавляете зависимость от базы данных. Если PostgreSQL недоступен, DNS-сервер не сможет нормально обслуживать зоны, особенно после очистки кэша. Поэтому для продакшена желательно иметь хотя бы два независимых NS-сервера на разных узлах, а не один единственный VDS. Но для первого узла и понимания принципов эта инструкция подходит отлично.

Предварительные требования

Перед установкой проверьте несколько вещей. У вас должен быть VDS с публичным IPv4 или IPv6, доступ по SSH с правами root или через sudo, корректное время на сервере и открытая возможность слушать порт 53. Если на сервере уже работает systemd-resolved, dnsmasq, BIND, Unbound или другой сервис на 53 порту, его нужно будет отключить либо перенести на другой адрес.

Также продумайте имена NS-серверов заранее. Если вы хотите использовать ns1.example.net для самого домена example.net, потребуется glue-запись у регистратора: иначе получится замкнутый круг, когда для поиска NS нужно сначала узнать адрес NS внутри той же зоны.

  • ns1.example.net указывает на IP первого DNS-сервера;
  • ns2.example.net желательно указывает на другой сервер;
  • у регистратора домена должны быть прописаны эти NS;
  • если NS находятся внутри той же зоны, нужны glue A/AAAA-записи.

В демонстрации мы поднимем один сервер ns1. Для настоящей отказоустойчивости второй сервер лучше поднять отдельно и настроить репликацию PostgreSQL, AXFR/IXFR, PowerDNS secondary или периодическую синхронизацию зоны. Если отдельно делегируете поддомен на свои NS, пригодится разбор про делегирование поддомена через NS-записи.

Схема авторитативного DNS-сервера PowerDNS с PostgreSQL на VDS

Установка PostgreSQL и PowerDNS

Названия пакетов отличаются в семействах дистрибутивов, но общий набор один: PostgreSQL, PowerDNS Authoritative Server и PostgreSQL backend для PowerDNS. Ниже команды для Debian/Ubuntu и RHEL-based систем. Fedora обычно ближе к RHEL-блоку, но версии пакетов там могут быть свежее.

Debian и Ubuntu

sudo apt update
sudo apt install postgresql postgresql-contrib pdns-server pdns-backend-pgsql dnsutils
sudo systemctl enable postgresql
sudo systemctl start postgresql

На Debian/Ubuntu пакет dnsutils даст нам утилиту dig для проверки ответов DNS. Сервис PowerDNS запустим позже, после настройки backend и базы.

AlmaLinux, Rocky Linux, CentOS Stream, Oracle Linux

sudo dnf install postgresql-server postgresql-contrib pdns pdns-backend-postgresql bind-utils
sudo postgresql-setup --initdb
sudo systemctl enable postgresql
sudo systemctl start postgresql

В RHEL-based дистрибутивах утилита dig обычно находится в пакете bind-utils. Если в вашем репозитории нет пакетов PowerDNS, подключите официальный репозиторий PowerDNS или EPEL, но не смешивайте случайные сторонние сборки: несовпадение версий сервера и backend может привести к ошибкам при старте.

Создаём базу данных и пользователя PostgreSQL

Для PowerDNS лучше создать отдельную базу и отдельного пользователя. Не используйте суперпользователя PostgreSQL в конфигурации DNS-сервера: сервису достаточно прав на чтение и изменение своих таблиц. В примере база называется powerdns, пользователь — pdns.

sudo -u postgres psql
CREATE DATABASE powerdns;
CREATE USER pdns WITH ENCRYPTED PASSWORD 'change_this_strong_password';
GRANT ALL PRIVILEGES ON DATABASE powerdns TO pdns;
\q

Теперь подключимся к новой базе и создадим схему. В разных версиях PowerDNS схема может немного меняться, поэтому лучший источник — SQL-файл из установленного пакета. Обычно он лежит в документации пакета. Если файл есть, используйте его: это безопаснее ручного копирования схемы из случайных источников.

Найти SQL-схему в системе

dpkg -L pdns-backend-pgsql | grep -E 'schema.*pgsql|pgsql.*schema|schema.*sql'
rpm -ql pdns-backend-postgresql | grep -E 'schema.*pgsql|pgsql.*schema|schema.*sql'

Если команда нашла файл, импортируйте его в базу. Путь ниже примерный: замените его на найденный в вашей системе.

sudo -u postgres psql powerdns < /usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql

Если файл сжат, можно использовать zcat.

zcat /usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql.gz | sudo -u postgres psql powerdns

После импорта выдайте пользователю права на таблицы и последовательности. Это особенно важно, потому что таблицы могли быть созданы владельцем postgres.

sudo -u postgres psql powerdns
GRANT USAGE ON SCHEMA public TO pdns;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO pdns;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO pdns;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO pdns;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO pdns;
\q

Проверим, что пользователь может подключиться. Если PostgreSQL слушает только локальный сокет, а PowerDNS будет ходить по 127.0.0.1, убедитесь, что в pg_hba.conf разрешена локальная аутентификация по паролю для IPv4 loopback.

psql -h 127.0.0.1 -U pdns -d powerdns -c 'SELECT 1;'

Если получили SELECT 1 и строку с единицей — база готова. Если видите password authentication failed, проверьте пароль. Если no pg_hba.conf entry — нужно поправить правила доступа PostgreSQL и перезагрузить сервис.

FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды

Настраиваем PowerDNS backend gpgsql

Основной конфиг PowerDNS обычно находится в /etc/powerdns/pdns.conf. Для PostgreSQL backend нужны параметры launch, gpgsql-host, gpgsql-port, gpgsql-dbname, gpgsql-user и gpgsql-password. На некоторых системах backend-конфиги лежат отдельно в каталоге /etc/powerdns/pdns.d/. Логика одна: PowerDNS должен запускать gpgsql backend и знать, как подключиться к базе.

sudo install -m 0750 -d /etc/powerdns/pdns.d
sudo nano /etc/powerdns/pdns.d/pdns-gpgsql.conf
launch=gpgsql
gpgsql-host=127.0.0.1
gpgsql-port=5432
gpgsql-dbname=powerdns
gpgsql-user=pdns
gpgsql-password=change_this_strong_password
gpgsql-dnssec=yes

Проверьте, не задан ли launch в нескольких местах одновременно. Дубли часто приводят к неожиданному поведению: PowerDNS может попытаться загрузить лишний backend или вообще не стартовать. Если в pdns.conf уже есть launch=, приведите настройку к одному понятному варианту.

Файл с паролем должен быть недоступен обычным пользователям. На Debian/Ubuntu сервис часто работает от пользователя pdns, на RHEL-based системах имя пользователя может отличаться, но права всё равно нужно держать строгими.

sudo chown root:pdns /etc/powerdns/pdns.d/pdns-gpgsql.conf
sudo chmod 0640 /etc/powerdns/pdns.d/pdns-gpgsql.conf

Если группа pdns отсутствует, посмотрите фактического пользователя сервиса:

systemctl cat pdns | grep -E 'User=|Group='

Теперь можно проверить конфигурацию и запустить PowerDNS.

sudo pdns_server --daemon=no --guardian=no --loglevel=9

Команда выше запускает сервер в foreground и удобна для первичной диагностики. Если ошибок подключения к PostgreSQL нет, остановите её через Ctrl+C и включите системный сервис.

sudo systemctl enable pdns
sudo systemctl restart pdns
sudo systemctl status pdns --no-pager

На некоторых сборках юнит может называться иначе. Если команда не нашла сервис, проверьте список:

systemctl list-unit-files | grep pdns

Создаём первую DNS-зону через pdnsutil

PowerDNS можно наполнять через SQL напрямую, но для администратора удобнее начать с pdnsutil. Утилита сама создаёт корректные записи в таблицах и снижает риск ошибиться в структуре. Создадим native-зону example.net.

sudo pdnsutil create-zone example.net ns1.example.net

Команда создаст SOA и NS-запись. Теперь добавим адреса для NS и несколько типовых записей. В реальной зоне замените IP и имена.

sudo pdnsutil add-record example.net ns1 A 203.0.113.10
sudo pdnsutil add-record example.net ns1 AAAA 2001:db8::10
sudo pdnsutil add-record example.net @ A 203.0.113.20
sudo pdnsutil add-record example.net www CNAME example.net
sudo pdnsutil add-record example.net @ MX '10 mail.example.net'
sudo pdnsutil add-record example.net mail A 203.0.113.30
sudo pdnsutil add-record example.net @ TXT 'v=spf1 mx -all'

Проверим содержимое зоны:

sudo pdnsutil list-zone example.net

Обратите внимание на точку в конце FQDN. В выводе DNS-записи часто отображаются как example.net., ns1.example.net.. Это нормально: точка означает абсолютное доменное имя. В командах pdnsutil можно использовать относительные имена вроде www внутри зоны, но при диагностике всегда полезно понимать, где имя относительное, а где полное.

sudo pdnsutil show-zone example.net

Открываем порт 53 в firewall

DNS использует UDP 53 для большинства запросов и TCP 53 для крупных ответов, DNSSEC, zone transfer и случаев, когда ответ не помещается в UDP. Открывать нужно оба протокола. Ошибка «открыл UDP, забыл TCP» встречается очень часто и потом проявляется таймаутами или SERVFAIL при проверках.

nftables

Если у вас уже есть собственный набор правил nftables, добавьте разрешения в существующую цепочку input. Пример ниже показывает смысл правил, а не полную политику firewall.

sudo nft add rule inet filter input udp dport 53 accept
sudo nft add rule inet filter input tcp dport 53 accept
sudo nft list ruleset

firewalld

sudo firewall-cmd --add-service=dns --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-services

ufw

sudo ufw allow 53/udp
sudo ufw allow 53/tcp
sudo ufw status verbose

После изменения firewall проверьте, что PowerDNS действительно слушает нужные адреса. Если он слушает только 127.0.0.1:53, внешние клиенты не смогут получить ответ.

sudo ss -lntup | grep ':53'
sudo ss -lnuap | grep ':53'

Если видите конфликт с другим сервисом на 53 порту, сначала разберитесь, кто занял порт:

sudo lsof -iTCP:53 -iUDP:53 -P -n

Проверяем ответы PowerDNS

Начинайте диагностику локально с явным указанием сервера. Так вы исключите кеши провайдера, локальный резолвер ноутбука и ошибки делегирования у регистратора.

dig @127.0.0.1 example.net SOA +short
dig @127.0.0.1 example.net NS +short
dig @127.0.0.1 www.example.net A +short

Затем проверьте публичный IP VDS с другой машины или хотя бы с самого сервера через внешний адрес:

dig @203.0.113.10 example.net SOA +norecurse
dig @203.0.113.10 ns1.example.net A +norecurse
dig @203.0.113.10 example.net MX +norecurse

Флаг +norecurse полезен: он показывает, что вы ожидаете authoritative-ответ, а не рекурсивный поиск. В ответе для вашей зоны должен быть флаг aa — authoritative answer. Если флага нет, вы, возможно, спрашиваете не тот сервер или зона не загружена.

sudo pdns_control status
sudo pdns_control list | head
journalctl -u pdns -n 100 --no-pager

Если сервис запущен, но зона не отвечает, проверьте, видит ли PowerDNS домен:

sudo pdnsutil list-all-zones
sudo pdnsutil check-zone example.net

pdnsutil check-zone помогает поймать синтаксические и логические ошибки: некорректные записи, проблемы с SOA, странные значения TTL. Не игнорируйте предупреждения — DNS может работать «почти всегда», а потом внезапно ломаться на DNSSEC, почте или у отдельных резолверов.

Делегирование домена и NS-записи

Когда локальные проверки прошли, наступает момент делегирования. В панели регистратора укажите NS-серверы домена: например, ns1.example.net и ns2.example.net. Если домен ещё не куплен или нужен отдельный технический домен для инфраструктуры, используйте регистрацию доменов и сразу продумайте имена NS. Если имена NS находятся внутри самого домена, добавьте glue-записи — соответствие имени NS и его IP-адреса.

Типичная путаница: NS-записи внутри вашей зоны и NS, указанные у регистратора, — не одно и то же действие. Внутри зоны вы объявляете, какие серверы авторитативны. У регистратора вы сообщаете родительской зоне, куда отправлять клиентов. Для рабочей делегации нужно и то, и другое.

dig example.net NS +trace

Команда +trace показывает путь от корневых серверов к TLD и дальше к вашим NS. Если на этапе TLD видны старые NS — изменения у регистратора ещё не применились или вы изменили не тот домен. Если TLD отдаёт новые NS, но они не отвечают — проблема уже на вашем DNS-сервере, firewall или адресах glue.

TTL тоже имеет значение. Перед миграцией зоны обычно снижают TTL старых записей заранее: например, до 300 секунд. Если сделать это за пять минут до переключения NS, старые кеши всё равно будут жить по прежнему TTL. Для аккуратной миграции планируйте окно за сутки или хотя бы за несколько часов. А если параллельно переносите домен между регистраторами, полезно заранее проверить нюансы трансфера домена и DNS.

Проверка делегирования домена, NS-записей и glue-записей через dig

Минимальная безопасность PowerDNS на VDS

Для authoritative DNS базовая безопасность состоит не в «секретности» записей, а в правильном ограничении поверхностей атаки. Порт 53 должен быть открыт всему интернету, иначе DNS не имеет смысла. Но административные интерфейсы, PostgreSQL и служебные API не должны торчать наружу.

  • PostgreSQL слушает только 127.0.0.1 или приватный адрес между вашими NS-серверами.
  • Пользователь pdns не является суперпользователем PostgreSQL.
  • Файл с gpgsql-password доступен только root и пользователю или группе сервиса.
  • Рекурсия не включена на authoritative-сервере.
  • TCP 53 открыт, но AXFR разрешён только доверенным secondary-серверам, если он нужен.
  • Журналы PowerDNS и PostgreSQL включены в регулярный мониторинг.

Если вы включаете встроенный webserver или API PowerDNS, привязывайте его к localhost или приватному адресу. Не публикуйте административный API без аутентификации, TLS-терминации и сетевого ограничения. Для автоматизации лучше использовать отдельный reverse proxy с доступом только из VPN или CI-сети.

webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
api=yes
api-key=change_this_long_random_key

Эти параметры приведены как пример фрагмента конфигурации. Если API не нужен — не включайте его. Чем меньше включённых интерфейсов, тем проще сопровождение.

Бэкапы PostgreSQL-зон

DNS-зона кажется небольшой, пока в ней десяток записей. Но в реальности там могут жить клиентские поддомены, TXT для верификаций, MX, CAA, DKIM, SPF, сервисные SRV-записи и настройки DNSSEC. Потеря базы PowerDNS может стать полноценным инцидентом: сайты не открываются, почта не ходит, сертификаты не выпускаются.

Минимальный бэкап — регулярный pg_dump базы powerdns с хранением вне сервера. Для маленьких зон этого обычно достаточно.

sudo -u postgres pg_dump -Fc powerdns -f /var/backups/powerdns.dump

Проверка восстановления не менее важна, чем сам бэкап. Периодически поднимайте тестовую базу и пробуйте восстановить дамп:

sudo -u postgres createdb powerdns_restore_test
sudo -u postgres pg_restore -d powerdns_restore_test /var/backups/powerdns.dump
sudo -u postgres dropdb powerdns_restore_test

Для production-инфраструктуры добавьте расписание через systemd timer или cron, шифрование архива и отправку в удалённое хранилище. Но даже простой дамп уже лучше, чем надежда «DNS-записи я примерно помню».

Частые проблемы и быстрая диагностика

PowerDNS не стартует после настройки PostgreSQL

Сначала смотрите журнал. Чаще всего причина в неправильном пароле, отсутствующей схеме, неверном имени backend или правах на таблицы.

journalctl -u pdns -n 200 --no-pager
sudo -u postgres psql powerdns -c '\dt'
psql -h 127.0.0.1 -U pdns -d powerdns -c 'SELECT count(*) FROM domains;'

Если таблицы есть, но пользователь pdns не может читать domains, вернитесь к выдаче прав. Если таблиц нет — импорт схемы не выполнился или был выполнен в другую базу.

dig отвечает локально, но снаружи таймаут

Проверьте bind-адрес PowerDNS, firewall на VDS и сетевой фильтр у провайдера. DNS требует UDP и TCP. Локальный ответ через 127.0.0.1 доказывает только работоспособность приложения, но не доступность из интернета.

sudo ss -lntup | grep ':53'
sudo nft list ruleset | grep 53
sudo tcpdump -ni any port 53

tcpdump покажет, приходят ли пакеты на сервер. Если запросы не приходят вообще, проблема выше: в сетевых правилах, маршрутизации, cloud firewall или адресе, указанном у регистратора.

После смены NS часть пользователей видит старые записи

Это нормальное поведение DNS-кешей, если старые TTL ещё не истекли. Проверьте, какие NS отдаёт родительская зона, и сравните ответы разных резолверов. Не пытайтесь «ускорить интернет» постоянными изменениями туда-сюда: так легко получить ещё больше рассинхронизации.

dig example.net NS +trace
dig @203.0.113.10 example.net SOA +norecurse

NS у регистратора указан, но домен не делегируется

Если NS находится внутри той же зоны, почти всегда виноват отсутствующий или неправильный glue. Например, для example.net NS ns1.example.net должен иметь адрес в родительской зоне .net. Это настраивается не в PowerDNS, а в панели регистратора как host object, glue record или «собственный DNS-сервер» — название зависит от интерфейса.

Что улучшить после базового запуска

Когда первый сервер отвечает стабильно, не останавливайтесь на минимальной схеме. DNS — инфраструктурный сервис, и к нему стоит относиться как к базе данных или почтовому серверу: мониторинг, бэкапы, контроль изменений, план восстановления.

  • Поднимите второй NS на отдельном VDS или в другой локации.
  • Настройте мониторинг UDP/TCP 53 и проверку SOA serial.
  • Храните изменения зон в Git или хотя бы логируйте административные операции.
  • Добавьте CAA-записи для контроля центров сертификации.
  • Оцените DNSSEC, но включайте его только после понимания DS-записей и процедуры rollover.
  • Ограничьте AXFR списком trusted IP, если используете secondary.

PowerDNS хорош тем, что позволяет начать просто, а затем наращивать функциональность: API, DNSSEC, hidden primary, secondary-серверы, интеграцию с биллингом или панелью управления. PostgreSQL в этой схеме даёт предсказуемое хранение данных и привычные инструменты администрирования.

Итог

Связка PowerDNS Authoritative и PostgreSQL — практичный способ поднять собственный DNS-сервер на VDS без ручного редактирования zone-файлов. Мы установили необходимые пакеты, создали базу и пользователя, подключили backend gpgsql, добавили зону через pdnsutil, открыли UDP/TCP 53 и проверили authoritative-ответы через dig.

Главное — не путать локальную работоспособность зоны с полноценным делегированием. Пока у регистратора не указаны правильные NS, а для внутренних NS не созданы glue-записи, внешний мир может не найти ваш сервер. И наоборот: даже идеально прописанное делегирование не спасёт, если PowerDNS не слушает публичный адрес или firewall режет TCP 53.

Для тестовой зоны достаточно одного узла, но для production используйте минимум два NS-сервера, регулярные бэкапы PostgreSQL и мониторинг. DNS обычно вспоминают только тогда, когда он сломался; лучше сделать так, чтобы вспоминать о нём приходилось только при плановых изменениях.

Поделиться статьей

Вам будет интересно

OpenLiteSpeed на VDS: PHP LSAPI, virtual hosts и HTTPS OpenAI Статья написана AI (GPT 5)

OpenLiteSpeed на VDS: PHP LSAPI, virtual hosts и HTTPS

Показываем, как развернуть OpenLiteSpeed на Linux VDS: подготовить сервер и DNS, подключить PHP LSAPI, создать virtual host, выпус ...
AlmaLinux и Rocky Linux: upgrade с EL8 на EL9 через Leapp на VDS OpenAI Статья написана AI (GPT 5)

AlmaLinux и Rocky Linux: upgrade с EL8 на EL9 через Leapp на VDS

Разбираем безопасный upgrade AlmaLinux и Rocky Linux 8 до 9 на VDS через Leapp/ELevate: что проверить до старта, как читать отчёт ...
AlmaLinux и Rocky Linux: dnf history, rollback и snapshots OpenAI Статья написана AI (GPT 5)

AlmaLinux и Rocky Linux: dnf history, rollback и snapshots

Обновление пакетов на сервере редко ломает всё сразу, но к нему лучше готовиться. Разберём, чем полезен dnf history, когда нужен r ...