Настройка кластера PowerDNS на Rocky Linux
Опубликовано:
Используемые термины: DNS, PowerDNS, Rocky Linux, MariaDB.
В данной инструкции мы по пунктам рассмотрим настройку отказоустойчивой DNS с возможностью управления через веб-интерфейс. Команды будут выполняться на операционной системе Rocky Linux (протестировано на версии 9).
После настройки мы получим:
- Серверы DNS для хранения информации о собственных доменах.
- Хранение данных о зонах в СУБД.
- Веб-интерфейс для управления зонами и записями.
- Репликацию базы данных для обеспечения отказоустойчивости.
Процесс разобьем на несколько этапов.
Установка PowerDNS и его компонентов, запуск сервиса
Настройка репозитория и установка DNS сервера
Установка СУБД MySQL
Настройка и запуск PowerDNS
Настройка панели управления
Загрузка и установка PowerDNS-Admin
Создание systemd юнита для автозапуска
Настройка API на сервере DNS и привязка к панели
Обратное проксирование с помощью NGINX
Настройка https для шифрования запросов к панели управления
Кластеризация базы данных MySQL / MariaDB
Проверка отправки запросов к DNS и репликации данных
Дополнительные материалы
Установка и запуск сервера DNS
Сразу начнем с развертывания PowerDNS на узлах кластера. Процесс разделим на несколько подпунктов.
Установка PowerDNS
Переходим на официальный сайт разработчика и находим стабильную версию для PowerDNS Authoritative Server. На момент обновления инструкции это была 5.0.x. Для удобства создадим переменную с указанием версии:
PD_VER=50
* обратите внимание, что нужно указать первые два числа, разделенные точкой, но без самой точки. Например, для версии 5.0 укажите 50, для 4.7 — 47 и так далее.
Устанавливаем EPEL-репозиторий:
dnf install epel-release
Копируем файл с настройками репозитория для PowerDNS:
curl -sL https://repo.powerdns.com/repo-files/el-auth-${PD_VER}.repo -o /etc/yum.repos.d/powerdns-auth-${PD_VER}.repo
Выполняем установку сервера DNS и компонента для работы с mysql:
dnf install pdns pdns-backend-mysql
Меняем права созданных файлов (возможно, ошибку исправят, но в моей установке если не поправить права, сервис стартовал с ошибкой):
chown root:pdns /etc/pdns/pdns.conf
chmod 640 /etc/pdns/pdns.conf
Разрешаем автозапуск сервера DNS:
systemctl enable pdns
Переходим к установке СУБД.
Установка и настройка MariaDB
Устанавливаем базу данных командой:
dnf install mariadb-server
Разрешаем автозапуск и стартуем сервис:
systemctl enable mariadb --now
При желании усилить безопасность доступа к СУБД, запускаем скрипт:
mysql_secure_installation
Вам будет предложено ответить на часть вопросов, касательных безопасности. Но большинство из них отвечаем простым нажатием Enter, оставляя значения по умолчанию.
Заходим в SQL-оболочку:
mysql
Следующими командами создаем базу данных и пользователя:
> CREATE DATABASE pdns DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
> CREATE USER 'pdns'@'localhost' IDENTIFIED BY 'password';
* в данном примере будет создана база с названием pdns, а также пользователь с таким же именем. Пароль для пользователя password меняем на что-то посложнее.
А также даем полные права созданному пользователю на созданную базу:
> GRANT ALL PRIVILEGES ON pdns.* TO pdns@localhost;
Выходим из командной строки SQL:
> quit
Загружаем начальные данные в базу pdns:
mysql pdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql
Настройка и запуск PowerDNS
Открываем конфигурационный файл:
vi /etc/pdns/pdns.conf
Добавляем в самый низ файла:
launch=gmysql
gmysql-host=localhost
gmysql-user=pdns
gmysql-password=password
gmysql-dbname=pdns
* где password — пароль, который мы указали при создании пользователя в MySQL.
Запускаем сервер DNS:
systemctl start pdns
Проверяем статус:
systemctl status pdns
Сервер PowerDNS готов к работе.
Настройка веб-приложения PowerDNS-Admin
Веб-интерфейс достаточно установить только на одном сервере, но для резервирования возможности управления лучше это сделать на всех серверах.
Рассмотрим пошагово, как запустить приложение, настроить API PowerDNS, а также настроить systemd для автозапуска PowerDNS-Admin.
Установка и запуск
Включаем модуль репозитория mysql:
dnf module enable mysql
Устанавливаем пакеты:
dnf install wget gcc pkg-config python3-devel mysql-devel postgresql-devel openldap-devel
* где:
- wget — утилита для скачивания файлов по сети.
- gcc — набор компиляторов, понадобится для сборки приложения.
- pkg-config — утилита, которая помогает компилировать и линковать программы с библиотеками.
- python3-devel — средства для разработки Python. Библиотеки и инструменты для создания модулей. Нам нужно для установки расширений Python.
- mysql-devel / postgresql-devel / openldap-devel — содержат файлы, необходимые для компиляции программ, которые используют mysql / postgresql / openldap. Нужны для сборки Pyton расширений.
Переходим на страницу проекта в GitHub. Смотрим последнюю версию релиза. На момент обновления инструкции, это была версия 0.4.2. Для удобства создаем переменную:
PDA_VER=0.4.2
Скачиваем архив проекта для управления записями в PowerDNS:
wget https://github.com/PowerDNS-Admin/PowerDNS-Admin/archive/refs/tags/v${PDA_VER}.tar.gz
Распаковываем архив:
tar -zxf v${PDA_VER}.tar.gz
Переносим полученную папку в каталог opt:
mv PowerDNS-Admin-${PDA_VER} /opt/powerdns-admin
Переходим в каталог приложения:
cd /opt/powerdns-admin/
Создаем виртуальное окружение Python:
python -m venv venv
Активируем его:
source venv/bin/activate
Обновляем менеджер пакетов pip:
pip install --upgrade pip
Устанавливаем все расширения, от которых зависит приложение PowerDNS-Admin:
pip install -r requirements.txt
Экспортируем 2 системные переменные:
export FLASK_CONF=../configs/development.py
export FLASK_APP=powerdnsadmin/__init__.py
* где:
- FLASK_CONF — указывает путь до конфигурационного файла FLASK.
- FLASK_APP — путь до главного модуля приложения python.
Обновляем схему для базы данных приложения:
flask db upgrade
Разрешаем модуль установки nodejs версии 20:
dnf module enable nodejs:20
Устанавливаем nodejs:
dnf install nodejs
Устанавливаем пакетный менеджер yarn:
npm -g install yarn
Устанавливаем зависимые расширения для nodejs:
/usr/local/bin/yarn install --pure-lockfile
* опция --pure-lockfile не меняет существующий файл yarn.lock, в котором находится список устанавливаемых разработчиком модулей и их версий.
Выполняем сборку и оптимизацию статических файлов проекта:
flask assets build
В фаерволе разрешаем порт 9191:
firewall-cmd --permanent --add-port=9191/tcp
firewall-cmd --reload
Запускаем приложение:
./run.py
Мы должны увидеть что-то на подобие:
* Serving Flask app 'powerdnsadmin'
* Debug mode: on
[2025-06-29 14:53:43,259] [_internal.py:187] INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:9191
* Running on http://192.168.1.15:9191
Сервис запущен. Можно протестировать работу веб-интерфейса.
Переходим в браузере по пути http://<IP-адрес сервера>:9191 — создаем нового пользователя (Create an account):

Заполняем все поля:

Входим в панель. Мы должны увидеть ошибку подключения к API сервера PowerDNS. Это правильно, так как мы его еще не добавляли и будем это делать позже.
Рекомендуется сразу отключить возможность самостоятельной регистрации нового пользователя. Для этого переходим в раздел

Allow users to sign up

Автозапуск веб-панели через systemd
Мы запустили приложение в интерактивном режиме. Прерываем его работу комбинацией Ctrl + C. После деактивируем виртуальную среду python:
deactivate
Создаем systemd-юнит для powerdns-admin:
vi /etc/systemd/system/powerdns-admin.service
[Unit]
Description=Powerdns Admin Service
Wants=network.target
After=syslog.target network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/powerdns-admin
Environment=FLASK_CONF=../configs/development.py
Environment=FLASK_APP=powerdnsadmin/__init__.py
ExecStart=/opt/powerdns-admin/venv/bin/gunicorn --bind 0.0.0.0:9191 'powerdnsadmin:create_app()'
Restart=on-failure
RestartSec=10
KillMode=process
[Install]
WantedBy=multi-user.target
Если нам нужно будет отредактировать файл, перечитываем systemd:
systemctl daemon-reload
* обратите внимание на опцию bind, в которой мы указали, что приложение должно слушать на всех сетевых интерфейсах (0.0.0.0) и порту 9191. При необходимости, измените данные значения.
Можно разрешить и запустить приложение:
systemctl enable --now powerdns-admin
Посмотреть состояние службы можно командой:
systemctl status powerdns-admin
Теперь приложение с веб-интерфейсом управления PowerDNS будет запускаться автоматически при старте сервера.
Проверяем его работу в браузере по пути http://<IP-адрес сервера>:9191.
API и подключение к серверу
Для того, чтобы админ панель могла подключиться к PowerDNS, включаем на последнем API:
vi /etc/pdns/pdns.conf
Добавляем в самый низ файла:
api=yes
api-key=secret_api_key
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
webserver-allow-from=127.0.0.1
* задайте свой api-key, который служит как токен безопасности для подключения к API.
Перезапускаем PowerDNS:
systemctl restart pdns
Возвращаемся на веб-интерфейс админ панели и вводим данные для подключения к API:

* где:
- PowerDNS API URL —
- PowerDNS API Key —
http://127.0.0.1:9191
Обратное проксирование с NGINX
Если мы хотим красивый URL для адреса, по которому будет запускаться админ панель, рекомендуется настроить обратный прокси nginx. Также с его помощью легче настроить SSL.
Предположим, мы хотим управлять записями DNS по адресу http://dnsadmin.dmosk.ru. Устанавливаем веб-сервер:
dnf install nginx
Создаем конфигурационный файл в nginx с описанием виртуального домена:
vi /etc/nginx/conf.d/powerdns-admin.conf
server {
listen 80;
server_name dnsadmin.dmosk.ru;
access_log off;
gzip on;
gzip_disable "msie6";
gzip_min_length 1000;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
location / {
proxy_pass http://127.0.0.1:9191;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
* обратите внимание на значения двух опций:
- server_name — dns-имя, по которому будем заходить, чтобы открыть панель управления.
- proxy_pass — сервер, где установлен PowerDNS. В нашем случае админ-панель установлена на тот же сервер, но если вы установили ее на отдельный сервер, необходимо указать адрес сервера DNS.
Разрешаем автозапуск nginx и стартуем его:
systemctl enable --now nginx
В фаерволе разрешаем порт для веб-сервера:
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
Административная панель готова к работе.
Настройка SSL
Если мы планируем подключаться к панели управления из вне, стоит настроить HTTPS для шифрования всего трафика. Для этого необходимо получить сертификат и отредактировать обратный прокси nginx.
В нашем примере рассмотрим получение бесплатного сертификата от Let's Encrypt с помощью утилиты certbot. Открываем конфигурацию веб-сервера:
vi /etc/nginx/conf.d/powerdns-admin.conf
Добавляем:
server {
listen 80;
...
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
location ~ /.well-known/acme-challenge {
root /usr/share/nginx/html;
allow all;
}
location / {
proxy_pass http://127.0.0.1:9191;
proxy_redirect off;
...
Установим certbot:
dnf install certbot
Запрашиваем сертификат:
certbot certonly --webroot --agree-tos --email postmaster@dmosk.ru --webroot-path /usr/share/nginx/html/ -d dnsadmin.dmosk.ru
* для успешной отработки команды необходимо, чтобы домен (в нашем случае dnsadmin.dmosk.ru) вел по 80 порту на наш сервер.
После успешного получения сертификата, необходимые файлы будет находиться по пути /etc/letsencrypt/live/<домен>. Открываем файл конфигурации nginx:
vi /etc/nginx/conf.d/powerdns-admin.conf
Вносим некоторые изменения:
server {
listen 80;
server_name dnsadmin.dmosk.ru;
return 301 https://$host$request_uri;
}
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/dnsadmin.dmosk.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dnsadmin.dmosk.ru/privkey.pem;
...
Перезапускаем nginx:
nginx -t && nginx -s reload
Портал управления записями должен быть доступен по https.
Кластер баз данных
Мы подняли независимые серверы DNS. Каждый по отдельности может хранить информацию о доменах и их записях в базе данных. Кластером данные серверы делает репликация базы данных. Таким образом, внеся изменения на любом из серверов, информация из базы должна попасть на другой сервер баз данных.
Репликация данных в базе MySQL/MariaDB выполняется встроенными методами. План настройки следующий:
- На обоих серверах настраиваем конфигурацию MySQL для возможности работы в режиме репликации (настройка server_id, создание пользователя для репликации и так далее).
- Выбираем сервер, который будет первым мастером. Создаем дамп базы PowerDNS.
- Переносим созданный дамп на второй сервер СУБД и восстанавливаем из него базу.
- Настраиваем репликацию на втором сервере, указывая первый сервер как источник данных.
- Теперь на первом сервере настраиваем репликацию, выбирая в качестве источника второй сервер.
Таким образом у нас будут настроен кластер базы данных по типу мастер-мастер.
Подробнее процесс конфигурирования описан в отдельной инструкции на этом сайте — Как настроить кластер MariaDB / MySQL.
Проверка работы кластера и DNS
После настройки всех нод кластера, а также репликации базы данных, выполним диагностику. Для начала установим на все серверы утилиту nslookup, которая предоставляется пакетом bind-utils:
dnf install bind-utils
Создаем запись на любом из серверов, предположим, А-запись с именем api и IP-адресом 192.168.11.11.
Проверяем, что наш сервер ее возвращает:
nslookup api.dmosk.localnet 127.0.0.1
Мы должны получить что-то на подобие:
Server: 127.0.0.1
Address: 127.0.0.1#53
Name: api.dmosk.localnet
Address: 192.168.11.11
Нас сервер работает корректно. Теперь переходим на второй сервер DNS и делаем аналогичный запрос. Мы должны получить такой же ответ. Это будет признаком, что сервер работает, а также выполнилась репликация записи в базе данных.
Читайте также
1. Получение бесплатного SSL сертификата Let's Encrypt.