Настройка DNS-сервера PowerDNS в Debian

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

Однако же хотелось бы мне написать вторую версию этого мануала, теперь уже для Debian.

Чем PowerDNS лучше BIND?
Во-первых, PowerDNS на порядок менее популярен, а значит – в нем найдено существенно меньше багов. Актуально, если учесть, что большинство bind-демонов с момента ввода “в бой” ни разу не обновлялись.
Во-вторых, PDNS может работать с различными бэкендам (mysql, pgsql, sqlite), в которых может хранить свои зоны. Это, на мой взгляд, существенно улучшает прозрачность системы.

Такие специфические вещи, как кэширование запросов, скорость работы и т.д. я здесь обсуждать не буду – не тот формат.

Перейдем к установке.
PowerDNS присутствует в stable-ветке, так что ставим смело, не боясь что-нибудь сломать:

apt-get install mysql-server mysql-client
apt-get install pdns-server pdns-backend-mysql

Теперь создадим базу данных для нашего сервера:

mysql -u root -p
CREATE DATABASE powerdns;
GRANT ALL ON powerdns.* TO 'power_admin'@'localhost' IDENTIFIED BY 'power_admin_password';
GRANT ALL ON powerdns.* TO 'power_admin'@'localhost.localdomain' IDENTIFIED BY 'power_admin_password';
FLUSH PRIVILEGES;
quit;

А затем скопируем таблицы из шаблона:

mysql -u root -p powerdns < /usr/share/doc/pdns-backend-mysql/mysql.sql

update: если файлика с примером базы у вас нет, то пользуем вот это:

USE powerdns;
CREATE TABLE domains (
id INT auto_increment,
name VARCHAR(255) NOT NULL,
master VARCHAR(128) DEFAULT NULL,
last_check INT DEFAULT NULL,
type VARCHAR(6) NOT NULL,
notified_serial INT DEFAULT NULL,
account VARCHAR(40) DEFAULT NULL,
primary key (id)
);

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
id INT auto_increment,
domain_id INT DEFAULT NULL,
name VARCHAR(255) DEFAULT NULL,
type VARCHAR(6) DEFAULT NULL,
content VARCHAR(255) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
primary key(id)
);

CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

CREATE TABLE supermasters (
ip VARCHAR(25) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) DEFAULT NULL
);

Обратите внимание, в пароле не должен встречаться символ '#', иначе pdns не сможет его адекватно воспринять, выдав, к примеру, что-то вроде этого:

Sep  6 23:42:03 217-79-13-120 pdns[4521]: gmysql Connection failed: Unable to connect to database: Access denied for user 'power_admin'@'localhost' (using password: YES)
Sep  6 23:42:03 217-79-13-120 pdns[4521]: Caught an exception instantiating a backend, cleaning up

Что касается конфигурирования, то позволю себе обратиться к своему же руководству:
/etc/powerdns/pdns.conf

Нам важны следующие строки:

# Разрешить трансфер зон для: (тут указываем, кому мы можем отдавать зоны, которые есть на нашем сервере)
allow-axfr-ips=0.0.0.0/0

# Разрешить запросы с: (добавляем сюда адреса нашей локалки, если не хотим запросов из мира)
allow-recursion=0.0.0.0/0

# Директория с конфигурационными файлами
config-dir=/etc/powerdns

# Включить guardian, подробности: http://doc.powerdns.com/guardian.html
guardian=yes


# Количество тредов, которые будут обращаться к бэкенду
distributor-threads=3

# Тип используемой базы данных и параметры для подключения
launch=gmysql
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-user=power_admin
gmysql-dbname=powerdns
gmysql-password=power_admin_password

# Интерфейс, на котором будет висеть сервер.
local-address= 127.0.0.1 (или любой другой, который есть на сервере)

# Порт, на котором будет висеть сервер.
local-port=53

#Настройки логирования:
# Расширенное логирование.
log-dns-details=/var/log/pdns/pdns-details.log
# Логировать неудачные апдейты зон.
log-failed-updates=/var/log/pdns/pdns-fail.log
# Файл, куда писать лог
logfile=/var/log/pdns/pdns.log
# log-facility для логирования через syslog (я
# logging-facility=
# Уровень логирования от 0 до 9 (0 - не логировать ничего, 9 - логировать всё).
loglevel=9
# Логировать все приходящие запросы (только для отладки! иначе логи будут расти катастрофическими темпами)
query-logging=no
# Логировать в лог файл, указанный в директиве logfile (только для Windows систем)
use-logfile=yes

# Если включено - рекурсивные запросы будут передваться на обработку рекурсору.
recursor=127.0.0.1:5353
# В качестве рекурсора можно указать сервера провайдера, тогда рекурсивные запросы поуйдут через них

/etc/powerdns/recursor.conf

allow-from=127.0.0.0/8, 10.0.0.0/8 (только своя локальная сеть)

# Hint файл, его можно взять из BIND /var/named/etc/namedb/named.root,
# или ftp://ftp.rs.internic.net/domain/root.zone.gz
hint-file=/etc/powerdns/root.zone

# Адрес который надо слушать указываем только 127.0.0.1, и ничего лишнего
local-address=127.0.0.1

# Порт который надо слушать, по умолчанию 53
local-port=5353

Периодически в конфиге появляются новые опции, поэтому советую не полениться, и заглянуть в официальное руководство.

Для того, чтобы админить зоны через удобный веб-интерфейс, нужно поставить админку. Например, PowerAdmin:

#Устанавливаем Web-сервер, интерпретатор php и необходимые модули
aptitude install apache2 libapache2-mod-php5 php5 php5-common php5-curl php5-dev php5-gd php-pear php5-imap php5-mcrypt php5-mhash php5-ming php5-mysql php5-xmlrpc gettext

#Устанавливаем PEAR
pear install DB
pear install pear/MDB2#mysql

#Скачиваем скрипты панели
cd /tmp
wget https://github.com/downloads/poweradmin/poweradmin/poweradmin-2.1.6.tgz
tar xvfz poweradmin-2.1.6.tgz
mv poweradmin-2.1.6 /var/www/poweradmin
touch /var/www/poweradmin/inc/config.inc.php
chown -R www-data:www-data /var/www/poweradmin/

Установщик админки будет доступен по адресу: http:///poweradmin/install.

После установки не забываем убрать за собой:

rm -fr /var/www/poweradmin/install/

Теперь нужно перезапустить демон и рекурсор:

sudo service pdns-recursor restart
sudo service pdns start

Вот теперь все 🙂

13 Comments

  1. /usr/share/doc/pdns-backend-mysql/mysql.sql

    А где взять этот файл. Ubuntu 12.04.1 такого после установки PDNS там нет.

    1. Дополнил статью шаблоном базы. Просто скопируйте описание таблиц в текстовый файл, сохраните его как powerdns.sql и выполните команду:
      mysql -u root -p powerdns < ./powerdns.sql

  2. Здравствуйте,
    а не сталкивались ли с нюансом пере направления запросов на другие ns-сервера.
    Вот в Bind был домен test.com в нем есть субдомены и если один из них перенаправить на другой ns-сервер, ns записи будут браться для этого субдомена на тех ns-серверах
    так, для субдомена sdf.test.com ns записи ведутся на ns1.testdomain.com, ns2.testdomain.com

    sdf IN NS ns1.testdomain.com
    IN NS ns2.testdomain.com

    В PowerDNS (mysql) если прописывать другие NS сервера, он у них не спрашивает, а ищет у себя и соответственно не выдает никаких A, MX, TXT, … записей по нем, так как они на ns1.testdomain.com

    1. Насколько я помню, в PowerDNS можно назначать зонам master-servers. Но это было давно, надо будет собрать стенд и проверить.

      1. Тип зоны можно выбрать: master, slave, native. Или master-servers реализуется по другому, или это другой параметр?

        1. Настраиваю тут PowerDNS, вспоминаю что и как.
          Собственно, если вам нужно трансферить запросы определенной зоны на другой NS, то логичней это делать рекурсором? У него и опция для этого есть соответствующая. Если хотите, могу расписать подробней.

          1. Да, было бы очень любезно изложить подробней Ваш вариант.
            Я было предположил, что запрос не отрабатывался дальше, по причине если ограничить рекурсию только довереным сетям. Но если рекурсию разрешить всем, ситуацию это не меняет.

          2. А в настройках рекурсора прописано, что эту зону следует искать за другим DNS?

  3. Имеется ввиду lazy-recursion=yes в pdns.conf
    Сначала проверять запрос в локальной базе, а если не найдет – выполнять рекурсивный запрос на другой ДНС сервер?

    1. Я о другом.
      # forward-zones Zones for which we forward queries, comma separated domain=ip pairs
      #
      # forward-zones=
      Можно принудительно указать, какие зоны нужно форвардить на другие dns-сервера (например, аплинку)

      1. В forward-zones привязка зоны к IP, а надобно к хостнейму (прим. ns.dom.net) так как хостеры периодически меняют IP и в данном параметре его предается менять. До и к тому же, пользователь через “poweradmin” просто укажет ns-сервера и к конфигу не причастен.

        1. в forward-zones привязка зоны (прим. server.dom.net) к ip-адресу dns-сервера (например, провайдеровского), на который нужно запросы об этой зоне перенапрвлять.
          Вы задачу обрисуйте во всей полноте, а там и решение можно поискать 🙂

          1. forward-zones, это как в bind-е forwarders, но нужно реализовать следующее.
            Покажу на bind зоне для наглядности.
            Есть ДНС сервер ns1.serv.net, для большинства зон мастер, для нескольких слейв, рекурсивные запросы только для определенных под сетей.
            Домен site.net в нем

            $TTL 3600
            @ IN SOA ns1.serv.net. hostmaster.serv.net. (
            2012090200 ; Serial
            10800 ; Refresh
            1800 ; Retry
            604800 ; Expire
            86400 ) ; Minimum

            IN NS ns1.serv.net.
            IN NS ns2.serv.net.

            IN MX 10 relay

            oblako IN A 77.88.8.7

            gate IN A 8.8.4.4

            prim IN A 77.88.8.1

            relay IN A 74.125.143.26

            pirogi IN NS ns.nex.com.
            IN NS ns2.nex.com.

            roza IN NS ns.host.net.
            IN NS ns2.host.net.

            elki IN NS ns.hosting.ru.
            IN NS nss.hosting.ru.

            При разрешении рекурсивных запросов для некоторых под сетей, не известным сетям сервер будет отдавать запросы только по тем зонам которые он ведет.
            Так на запрос dig @ns1.serv.net prim.site.net он выдаст 77.88.8.1, а вот на запрос к субдоменам с ns-записями, pirogi.site.net, roza.site.net, elki.site.net выдаст только записи “NS” записи, а про “А”, “MX” и др., нет.
            dig any @ns1.serv.net pirogi.site.net
            pirogi.site.net nameserver = ns.nex.com.
            pirogi.site.net nameserver = ns2.nex.com.

            А надобно, что бы при запросе о домене pirogi.site.net к серверу ns1.serv.net по субдомену pirogi он спросил у ns.nex.com и выдал записи “А”, “MX” и др.
            Вот именно в субдоменном перенаправлении на другие NS и вся загвоздка.

Leave a Reply