MAATRIX / Блог / PowerDNS на сервере: частые ошибки и решения

PowerDNS на сервере: частые ошибки и решения

MAATRIX

PowerDNS выбирают, когда нужны не зонные файлы, а полноценная база под доменами — с веб-панелью, API и записями, которые меняются программно. И почти сразу натыкаются на грабли: сервис не стартует, порт 53 занят, слейв не подхватывает зону, DNSSEC не подписывается. Разберём частые ошибки PowerDNS по симптому, причине и решению — с командами и путями конфигов.

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

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

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

Сервис не стартует: "Unable to launch backend"

Классика после первой установки: systemctl start pdns отваливается, а в журнале — Unable to launch backend или Trying to load module с указанием бэкенда, который не найден. Причина почти всегда одна: в pdns.conf (или в отдельном файле /etc/powerdns/pdns.d/) указан бэкенд launch=gmysql или launch=gpgsql, а модуль-коннектор не установлен — пакет pdns-backend-mysql / pdns-backend-pgsql ставится отдельно от ядра pdns-server.

Проверьте, что реально загружено и что говорит журнал.

systemctl status pdns
journalctl -u pdns -n 50 --no-pager
dpkg -l | grep pdns-backend

Если бэкенда в списке пакетов нет — доустановите его и перезапустите сервис.

apt install pdns-backend-mysql
# или
apt install pdns-backend-pgsql
systemctl restart pdns

Вторая частая причина той же ошибки — в конфиге прописаны сразу два конфликтующих бэкенда (например, остался launch=bind от установки по умолчанию, а ниже дописан launch=gmysql), а PowerDNS требует явного списка через запятую: launch=gmysql или launch=gmysql,bind. Проверьте, нет ли дублирующих директив launch= в разных файлах pdns.d/*.conf — они читаются все разом, и более поздний файл может тихо переопределить бэкенд.

Путаница бэкендов: bind, gmysql, gpgsql

PowerDNS умеет работать и с классическими zone-файлами (launch=bind), и с базой данных (gmysql, gpgsql, sqlite3). Ошибка новичков — начать с bind-бэкенда «для простоты», а потом пытаться на лету переключиться на БД и обнаружить, что записи из зонных файлов никуда не мигрировали: это два независимых хранилища, PowerDNS их не синхронизирует сам.

Если вы решили перейти на БД-бэкенд (а именно ради него обычно и берут PowerDNS — для управления зонами через SQL и веб-панель), создайте схему заранее, до первого запуска с этим бэкендом. Для MySQL/MariaDB:

mysql -u root -p -e "CREATE DATABASE pdns CHARACTER SET utf8mb4;"
mysql -u root -p pdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql

Для PostgreSQL путь к схеме и порядок команд аналогичны, только через psql и файл schema.pgsql.sql из пакета бэкенда. Если база и таблицы уже развёрнуты, а сервис всё равно ругается на отсутствующие таблицы — почти наверняка схему накатили не в ту базу или под другим пользователем, чем указан в gmysql-user/gmysql-dbname в конфиге. Если под другие задачи на сервере уже крутится MySQL или PostgreSQL, полезно свериться с частыми ошибками PostgreSQL или частыми ошибками MySQL — права доступа, кодировки и лимиты соединений всплывают и здесь.

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

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

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

Не подключается к MySQL или PostgreSQL

Сервис стартует, но в журнале — Unable to connect to database: Access denied или could not connect to server: Connection refused. Смотрите на связку из трёх параметров в блоке бэкенда:

gmysql-host=127.0.0.1
gmysql-dbname=pdns
gmysql-user=pdns
gmysql-password=ваш_пароль

Для PostgreSQL — те же поля с префиксом gpgsql-. Частые причины отказа:

  • Access denied / password authentication failed — пользователь БД создан, но у него нет прав на нужную базу, либо пароль в pdns.conf разъехался с реальным (например, после ручной смены пароля в БД). Пересоздайте пользователя или обновите GRANT явно под хост подключения.
  • Connection refused на PostgreSQL — сервер слушает только Unix-сокет или localhost, а PowerDNS пытается подключиться через TCP с другим host, либо pg_hba.conf не разрешает подключение по паролю для этого пользователя/базы. Проверьте listen_addresses в postgresql.conf и строку host pdns pdns 127.0.0.1/32 scram-sha-256 в pg_hba.conf.
  • Too many connections — если PowerDNS обслуживает много зон и держит пул соединений, а max_connections в БД занижен, старт может проходить, но под нагрузкой начнутся таймауты. Держите в уме, что бэкенд PowerDNS — не единственный потребитель соединений, если на том же сервере крутятся и другие приложения с БД.

Проверить подключение вручную, теми же учётными данными, что в конфиге:

mysql -u pdns -p -h 127.0.0.1 pdns -e "SELECT COUNT(*) FROM domains;"

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

Порт 53 занят: systemd-resolved, bind9 и recursor

Одна из самых частых ошибок на свежем сервере с Ubuntu: Unable to bind UDP socket to 0.0.0.0:53: Address already in use. Причина в 9 случаях из 10 — systemd-resolved, который по умолчанию слушает 53-й порт на 127.0.0.53 и часто дополнительно занимает адрес, на который вы пытаетесь повесить PowerDNS.

Проверьте, кто реально держит порт.

ss -tulnp | grep :53
systemctl status systemd-resolved

Если это systemd-resolved и вам не нужен его локальный резолвер (а на сервере, где сам PowerDNS обслуживает зоны, он обычно не нужен), отключите его резолвинг-заглушку и переключите /etc/resolv.conf на реальный резолвер:

systemctl disable --now systemd-resolved
rm -f /etc/resolv.conf
echo "nameserver 1.1.1.1" > /etc/resolv.conf
systemctl restart pdns

Альтернатива, если systemd-resolved нужен системе для других целей — явно указать PowerDNS слушать конкретный внешний IP через local-address=203.0.113.10, оставив 53-й порт на 127.0.0.53 за resolved. Второй частый источник конфликта на этом же порту — уже установленный bind9 или unbound, оставшийся от прошлой настройки DNS: systemctl disable --now bind9 перед первым запуском PowerDNS снимает проблему. Если сервер до этого настраивался вручную по гайду по настройке домена и DNS, проверьте, не остался ли там старый резолвер в автозапуске.

Отдельно стоит не путать роли: PowerDNS распространяется как минимум двумя демонами — pdns-server (Authoritative, отдаёт ваши собственные зоны) и pdns-recursor (рекурсивный резолвер, ходит в интернет за чужими доменами). Если нужен именно авторитативный сервер под собственные зоны, pdns-recursor скорее всего вообще не нужен — не ставьте его на тот же сервер без явной необходимости в рекурсии, это лишний источник конфликтов за 53-й порт. Если оба демона всё же нужны на одной машине, разведите их по портам явно:

# в pdns.conf (authoritative)
local-port=5300

# в recursor.conf
local-port=53
forward-zones=example.com=127.0.0.1:5300

Такая связка позволяет recursor слушать стандартный 53-й порт для клиентов, а authoritative — отдавать свои зоны через forward-zones на внутреннем порту. Без этого разделения оба демона будут конкурировать за один и тот же сокет.

AXFR обрывается: мастер не отдаёт зону слейву

Настроили master/slave между двумя PowerDNS, а на слейве в журнале — AXFR of domain 'example.com' failed: Remote nameserver not authoritative или зона просто не появляется. Разбирайте по шагам.

Во-первых, на мастере домен должен быть явно помечен как MASTER, а не NATIVE — тип задаётся в таблице domains при БД-бэкенде: pdnsutil list-all-zones и pdnsutil check-zone example.com быстро это подтвердят.

Во-вторых, мастер должен разрешать AXFR-запросы именно с IP слейва — многие ставят allow-axfr-ips и забывают вписать туда актуальный адрес слейва, особенно после смены сервера или добавления IPv6.

# в pdns.conf мастера
allow-axfr-ips=203.0.113.20,2001:db8::20

В-третьих, на слейве домен должен быть создан как SLAVE с указанием мастера, и slave=yes должен стоять в общем конфиге слейва. Точную ошибку синхронизации покажет журнал: journalctl -u pdns -n 100 --no-pager | grep -i axfr. Если ошибка про NOTIFY, а не сам AXFR — проверьте, что мастер шлёт NOTIFY при изменении зоны и что между серверами не режется UDP/TCP на 53-м порту фаерволом. Быстрая проверка руками с любого из серверов:

dig axfr example.com @IP_МАСТЕРА

Если эта команда с мастера возвращает полную зону, а автоматический AXFR слейва — нет, дело почти наверняка в списке allow-axfr-ips или в фаерволе между серверами, а не в самой логике PowerDNS.

DNSSEC: зона не подписывается или резолверы её не принимают

DNSSEC в PowerDNS завязан на pdnsutil, и типичная ошибка — включить подпись зоны, но забыть, что после этого нужно опубликовать DS-запись у регистратора, иначе валидирующие резолверы будут получать зону с подписью, которую некому проверить, и часть клиентов начнёт получать SERVFAIL.

Порядок действий для включения DNSSEC на существующей зоне:

pdnsutil secure-zone example.com
pdnsutil show-zone example.com

Вторая команда покажет ключи и, главное, DS-запись, которую нужно вручную добавить в панели регистратора домена для родительской зоны. Пока DS-запись не опубликована — зона фактически работает без валидации DNSSEC, и это нормальное промежуточное состояние, а не ошибка.

Если после публикации DS-записи резолверы стали отдавать SERVFAIL на ваш домен — почти всегда это рассинхрон: DS-запись у регистратора не совпадает с текущим набором ключей зоны (например, ключи были пересозданы при ротации, а старая DS-запись осталась в реестре). Сверьте текущий DS через show-zone с тем, что прописано у регистратора, и учтите, что изменения DS-записи распространяются не мгновенно — TTL родительской зоны и кэши резолверов дают задержку от нескольких часов до суток.

Отдельная частая ошибка — забыть выполнить pdnsutil rectify-zone example.com после ручных правок записей в БД-бэкенде: PowerDNS не пересчитывает NSEC/NSEC3-цепочку автоматически при прямых INSERT/UPDATE в таблицы, только через pdnsutil или API. Без rectify подпись остаётся, но становится некорректной для части запросов.

Веб-панель и API: 401 и обрыв соединения

Если поверх PowerDNS стоит панель управления зонами (например, PowerDNS-Admin) через встроенный REST API, частая ошибка — панель не может подключиться и показывает 401 Unauthorized или таймаут соединения. Сам API в PowerDNS выключен по умолчанию и включается явно:

# в pdns.conf
api=yes
api-key=длинный_случайный_ключ
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1,10.0.0.0/8

401 почти всегда означает, что ключ в настройках панели не совпадает с api-key в конфиге сервера, либо ключ вписан с лишним пробелом или переносом строки при копировании. Проверить API можно напрямую curl'ом, без панели, чтобы исключить её из уравнения:

curl -H "X-API-Key: длинный_случайный_ключ" http://127.0.0.1:8081/api/v1/servers/localhost

Если curl отвечает JSON с данными сервера — API рабочий, и проблема в конфигурации панели. Если получаете отказ в соединении — веб-сервер PowerDNS не слушает на этом адресе/порту, или webserver-allow-from не включает адрес, с которого вы стучитесь. По умолчанию API слушает только 127.0.0.1 — если панель на другом сервере, придётся расширять webserver-address и webserver-allow-from, и здесь же стоит закрыть порт API снаружи фаерволом и рассмотреть ограничение по IP через fail2ban — REST API с ключом в заголовке при открытом доступе снаружи является частой мишенью перебора.

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

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

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

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

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

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

PowerDNS не стартует с ошибкой про бэкенд — с чего начать?

С journalctl -u pdns -n 50 — там всегда указано, какой именно бэкенд не загрузился. В большинстве случаев не хватает пакета pdns-backend-mysql или pdns-backend-pgsql, который ставится отдельно от pdns-server.

Порт 53 занят при первом запуске — это точно PowerDNS виноват?

Нет, чаще всего это systemd-resolved, который слушает 53-й порт по умолчанию на свежих Ubuntu. Проверьте ss -tulnp | grep :53 и при необходимости отключите systemd-resolved.

Нужен ли мне pdns-recursor вместе с authoritative-сервером?

Только если серверу нужно ещё и резолвить чужие домены для клиентов. Для обслуживания собственных зон достаточно pdns-server (Authoritative) без recursor.

Зона не синхронизируется на слейве — что проверить первым?

Список allow-axfr-ips на мастере и командой dig axfr example.com @IP_мастера вручную проверить, отдаёт ли мастер зону вообще, независимо от логики slave-синхронизации.

DNSSEC включён, но резолверы дают SERVFAIL — почему?

Обычно DS-запись у регистратора не опубликована или не совпадает с текущими ключами зоны. Сверьте вывод pdnsutil show-zone с записью у регистратора и учтите задержку распространения из-за TTL и кэшей.

API PowerDNS отвечает 401 — где искать причину?

Проверьте API напрямую через curl с заголовком X-API-Key, минуя веб-панель. Если curl тоже получает 401 — ключ в pdns.conf не совпадает с тем, что указан в панели.

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

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

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