Установка PowerDNS в CentOS 7

Установка PowerDNS в CentOS 7

Roman Bogachev VMware Specialist | Drone Pilot | Traveler

Разворачиваем высокопроизводительный бесплатный DNS-сервер

Возможно несколько сценариев установки.
В данном примере будет рассмотрен вариант установки авторитарного сервера с пользовательскими доменами, отдельным рекурсивным сервером и балансировщиком dnsdist

Шаг 1. Установка пакетов

Добавим репозиторий авторитарного сервера и установим его:

1
2
3
yum install epel-release yum-plugin-priorities -y &&
curl -o /etc/yum.repos.d/powerdns-auth-41.repo https://repo.powerdns.com/repo-files/centos-auth-41.repo &&
yum install pdns -y

Добавим репозиторий рекурсивного сервера и установим его:

1
2
3
yum install epel-release yum-plugin-priorities -y &&
curl -o /etc/yum.repos.d/powerdns-rec-41.repo https://repo.powerdns.com/repo-files/centos-rec-41.repo &&
yum install pdns-recursor -y

Обязательно установим backend, с которым будем работать, в примере это будет MySQL, выполним его установку:

1
yum install pdns-backend-mysql

Шаг 2. Создание БД

После установки MySQL приступим к созданию базы данных.
Обязательно создаем нового пользователя MySQL для работы с PowerDNS.

1
GRANT ALL PRIVILEGES ON `powerdns`.* TO 'powerdns'@'localhost' IDENTIFIED BY 'YOUR_PASSWORD' WITH GRANT OPTION;

Создаем базу данных для PowerDNS и выбираем её:

1
2
CREATE DATABASE powerdns;
USE powerdns;

Выполняем следующие команды для создания таблиц:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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 UNSIGNED DEFAULT NULL,
account VARCHAR(40) CHARACTER SET 'utf8' DEFAULT NULL,
PRIMARY KEY (id)
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE UNIQUE INDEX name_index ON domains(name);


CREATE TABLE records (
id BIGINT AUTO_INCREMENT,
domain_id INT DEFAULT NULL,
name VARCHAR(255) DEFAULT NULL,
type VARCHAR(10) DEFAULT NULL,
content VARCHAR(64000) DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
disabled TINYINT(1) DEFAULT 0,
ordername VARCHAR(255) BINARY DEFAULT NULL,
auth TINYINT(1) DEFAULT 1,
PRIMARY KEY (id)
) Engine=InnoDB CHARACTER SET 'latin1';

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


CREATE TABLE supermasters (
ip VARCHAR(64) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) CHARACTER SET 'utf8' NOT NULL,
PRIMARY KEY (ip, nameserver)
) Engine=InnoDB CHARACTER SET 'latin1';


CREATE TABLE comments (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(10) NOT NULL,
modified_at INT NOT NULL,
account VARCHAR(40) CHARACTER SET 'utf8' DEFAULT NULL,
comment TEXT CHARACTER SET 'utf8' NOT NULL,
PRIMARY KEY (id)
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);


CREATE TABLE domainmetadata (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
kind VARCHAR(32),
content TEXT,
PRIMARY KEY (id)
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);


CREATE TABLE cryptokeys (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
flags INT NOT NULL,
active BOOL,
content TEXT,
PRIMARY KEY(id)
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE INDEX domainidindex ON cryptokeys(domain_id);


CREATE TABLE tsigkeys (
id INT AUTO_INCREMENT,
name VARCHAR(255),
algorithm VARCHAR(50),
secret VARCHAR(255),
PRIMARY KEY (id)
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

Шаг 3. Настройка авторитарного сервера

Открываем конфигурационный файл /etc/pdns/pdns.conf и приводим к следующему виду:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
setuid=pdns
setgid=pdns
launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=powerdns
gmysql-dbname=powerdns
gmysql-password=YOUR_PASSWORD
allow-axfr-ips=127.0.0.1/32
cache-ttl=60
control-console=no
default-soa-name=dns1.owndns.ru
default-soa-mail=support@owndns.ru
default-ttl=3600
disable-axfr=no
local-port=5300
local-address=127.0.0.1
log-dns-queries=yes
logging-facility=0
loglevel=4
max-queue-length=5000
max-tcp-connections=20
master=yes

Добавляем сервис в автозагрузку и запускаем:

1
systemctl enable pdns && systemctl start pdns

Проверяем, что сервер запустился без ошибок и все в порядке:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# systemctl status pdns -l
● pdns.service - PowerDNS Authoritative Server
Loaded: loaded (/usr/lib/systemd/system/pdns.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2018-03-01 22:56:50 MSK; 29s ago
Docs: man:pdns_server(1)
man:pdns_control(1)
https://doc.powerdns.com
Main PID: 28456 (pdns_server)
CGroup: /system.slice/pdns.service
└─28456 /usr/sbin/pdns_server --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no

Mar 01 22:56:50 owndns.ru pdns_server[28456]: PowerDNS Authoritative Server 4.1.1 (C) 2001-2017 PowerDNS.COM BV
Mar 01 22:56:50 owndns.ru pdns_server[28456]: Using 64-bits mode. Built using gcc 4.8.5 20150623 (Red Hat 4.8.5-16) on Feb 16 2018 10:08:16 by buildbot@aa8d6590639b.
Mar 01 22:56:50 owndns.ru pdns_server[28456]: PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.
Mar 01 22:56:50 owndns.ru pdns_server[28456]: Polled security status of version 4.1.1 at startup, no known issues reported: OK
Mar 01 22:56:50 owndns.ru pdns_server[28456]: Creating backend connection for TCP
Mar 01 22:56:50 owndns.ru pdns_server[28456]: Master/slave communicator launching
Mar 01 22:56:50 owndns.ru systemd[1]: Started PowerDNS Authoritative Server.
Mar 01 22:56:50 owndns.ru pdns_server[28456]: About to create 3 backend threads for UDP
Mar 01 22:56:50 owndns.ru pdns_server[28456]: No master domains need notifications
Mar 01 22:56:50 owndns.ru pdns_server[28456]: Done launching threads, ready to distribute questions

Шаг 4. Настройка рекурсивного сервера

Открываем конфигурационный файл /etc/pdns-recursor/recursor.conf и приводим к следующему виду:

1
2
3
4
5
6
setuid=pdns-recursor
setgid=pdns-recursor
local-address=127.0.0.1
local-port=5301
hint-file=/etc/pdns-recursor/root.zone
allow-from=127.0.0.0/8

Для того, чтобы загрузить список корневых зон в директиву hint-file, используем команду:

1
wget ftp://ftp.rs.internic.net/domain/root.zone.gz && gunzip root.zone.gz

Если на авторитарном сервере размещены пользовательские домены, то выполняем форвард запросов через директиву forward-zones:

1
forward-zones=owndns.ru=127.0.0.1:5300, example.com=127.0.0.1:5300

Добавляем сервис в автозагрузку и запускаем:

1
systemctl enable pdns-recursor && systemctl start pdns-recursor

Проверяем, что сервер запустился без ошибок и все в порядке:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# systemctl status pdns-recursor
● pdns-recursor.service - PowerDNS Recursor
Loaded: loaded (/usr/lib/systemd/system/pdns-recursor.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2018-03-01 23:13:42 MSK; 2s ago
Docs: man:pdns_recursor(1)
man:rec_control(1)
https://doc.powerdns.com
Main PID: 28548 (pdns_recursor)
CGroup: /system.slice/pdns-recursor.service
└─28548 /usr/sbin/pdns_recursor --daemon=no --write-pid=no --disable-syslog --log-timestamp=no

Mar 01 23:13:42 owndns.ru pdns_recursor[28548]: Enabled TCP data-ready filter for (slight) DoS protection
Mar 01 23:13:42 owndns.ru pdns_recursor[28548]: Listening for TCP queries on 127.0.0.1:5301
Mar 01 23:13:42 owndns.ru pdns_recursor[28548]: Set effective group id to 995
Mar 01 23:13:42 owndns.ru pdns_recursor[28548]: Set effective user id to 997
Mar 01 23:13:42 owndns.ru pdns_recursor[28548]: Launching 3 threads
Mar 01 23:13:42 owndns.ru systemd[1]: Started PowerDNS Recursor.
Mar 01 23:13:43 owndns.ru pdns_recursor[28548]: Done priming cache with root hints
Mar 01 23:13:43 owndns.ru pdns_recursor[28548]: Done priming cache with root hints
Mar 01 23:13:43 owndns.ru pdns_recursor[28548]: Done priming cache with root hints
Mar 01 23:13:43 owndns.ru pdns_recursor[28548]: Enabled 'epoll' multiplexer

Шаг 5. Установка и настройка балансировщика dnsdist

Dnsdist - это высокопроизводительный DNS-, DoS- и abuse
балансировщик. Основная его задача заключается в маршрутизации трафика на
лучший сервер, обеспечивающий максимальную производительность для разрешенных
пользователей, в то время как происходит шунтирование или блокировка зловредного трафика.

Обладает огромным количество фичей:

• Фильтровать трафик (из ядра)
• Проверять прямой трафик с консоли
• Задерживать и ограничивать скорость плохих запросов
• Интеллектуальная балансировка нагрузки
• Ограничение QPS и пр.

Более подробно можно почитать в презентации

Установим пакет dnsdist.

1
yum install dnsdist

Открываем конфигурационный файл /etc/dnsdist/dnsdist.conf и приводим к следующему виду:

1
2
3
4
5
6
7
8
9
10
11
setLocal('127.0.0.1')
addLocal('ANOTHER_IP')
addLocal('ANOTHER_IPV6_IP')
setACL({'0.0.0.0/0'}) -- Allow all IPs access
newServer({address='127.0.0.1:5300', pool='auth'})
newServer({address='127.0.0.1:5301', pool='recursor'})
recursive_ips = newNMG()
recursive_ips:addMask('127.0.0.1/32')
recursive_ips:addMask('192.168.2.0/23')
addAction(NetmaskGroupRule(recursive_ips), PoolAction('recursor'))
addAction(AllRule(), PoolAction('auth'))

Если хотим открыть рекурсию для всех, то убираем все правила, и добавляем recursive_ips:addMask('0.0.0.0/0').
ВНИМАНИЕ! В таком режиме есть вероятность DDoS-атаки!

Добавляем сервис в автозагрузку и запускаем:

1
systemctl enable dnsdist && systemctl start dnsdist

Проверяем, что сервер запустился без ошибок и все в порядке:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# systemctl status dnsdist 
● dnsdist.service - DNS Loadbalancer
Loaded: loaded (/usr/lib/systemd/system/dnsdist.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2018-03-01 23:17:51 MSK; 3s ago
Docs: man:dnsdist(1)
http://dnsdist.org
Process: 28590 ExecStartPre=/usr/bin/dnsdist -u dnsdist -g dnsdist --check-config (code=exited, status=0/SUCCESS)
Main PID: 28592 (dnsdist)
Tasks: 16 (limit: 8192)
CGroup: /system.slice/dnsdist.service
└─28592 /usr/bin/dnsdist -u dnsdist -g dnsdist --supervised --disable-syslog

Mar 01 23:17:51 owndns.ru dnsdist[28592]: Added downstream server 127.0.0.1:5300
Mar 01 23:17:51 owndns.ru dnsdist[28592]: Added downstream server 127.0.0.1:5301
Mar 01 23:17:51 owndns.ru dnsdist[28592]: Listening on 127.0.0.1:53
Mar 01 23:17:51 owndns.ru dnsdist[28592]: Listening on 195.209.55.51:53
Mar 01 23:17:51 owndns.ru dnsdist[28592]: Listening on [2a05:4800:2:55::51]:53
Mar 01 23:17:51 owndns.ru dnsdist[28592]: dnsdist 1.2.0 comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistri...version 2
Mar 01 23:17:51 owndns.ru dnsdist[28592]: ACL allowing queries from: 0.0.0.0/0
Mar 01 23:17:51 owndns.ru dnsdist[28592]: Marking downstream 127.0.0.1:5300 as 'up'
Mar 01 23:17:51 owndns.ru systemd[1]: Started DNS Loadbalancer.
Mar 01 23:17:51 owndns.ru dnsdist[28592]: Marking downstream 127.0.0.1:5301 as 'up'
Hint: Some lines were ellipsized, use -l to show in full.

Проверяем:

1
2
3
4
5
6
7
8
$ dig ANY bogachev.biz @195.209.55.51 +short
dns2.yandex.net.
10 mx.yandex.net.
2a05:4800:2:55::55
dns1.yandex.net.
dns1.yandex.net. info.bogachev.biz. 2017070102 14400 900 1209600 14400
195.209.55.55
"v=spf1 redirect=_spf.yandex.net"

Проверяем ответ от авторитарного сервера, где размещены пользовательские домены:

1
2
3
$ dig ANY example.com @195.209.55.51 +short
127.0.0.1
dns1.owndns.ru

Все работает!
В следующих статьях данной тематики будет рассмотрен пример геораспределенного кластера DNS.