DNS

Если попытаться объяснить вкратце, то DNS1) - это простейший список, состоящий из нескольких столбцов. Этот список служит для превращения каноничного2) имени хоста/сайта в IP-адрес или иную информацию, которую запишет туда администратор домена.

Почитать теорию можно вот тут.

Выбор ПО

В данный момент на рынке DNS серверов существует достаточно большое разнообразие. В общем и целом обзоров на просторах интернета достаточно, поэтому пробежимся вкратце по основным:

  • BIND - самый каноничный из каноничных, в реализации протокола DNS подошёл, пожалуй, ближе всех к RFC. На него часто ровняются другие, однако первый имеет так же и недостатки. Например достаточно кривую работу с бэкендами, отличающимися от файловых3) Хорош для зон, меняющихся крайне редко.
  • PowerDNS - в противоположность BIND является new-wave решением, предоставляющим огромное множество способов хранения информации о зонах. Написан на C++, используется много где, имеет относительно удобный интерфейс для управления. Состоит из двух частей - авторитативный сервер и рекурсивный. Первый служит для обслуживания зон, второй исключительно для обслуживания пользователей.
  • dnsmasq - по хорошему даже DNS сервером не является. Скорее этот кэширующий рекурсор, который кроме работы с DNS умеет ещё работать с DHCP.
  • Knot, Yadifa, NSD - к сожалению не трогал ни один из них, знаю, что NSD используется на некоторых корневых серверах. На сколько плохо помню у них общая проблема с прогреванием кэша на старте и/или компиляцией зон, потом работают быстро.

Поскольку хостинг это в первую очередь удобный интерфейс для клиента с максимально широкими возможностями для внесения изменений без привлечения технических спецалистов системы - выбор пал на PowerDNS. В теории связка с PostgreSQL позволит достаточно оперативно вносить изменения в зоны и не придётся устраивать дополнительную разработку вокруг интерфейсов ПО.

Установка и настройка

В нашей лабе мы буем использовать Linux Debia, так что корректируйте комманды под себя. Для начала установим сервер и нужный бэкенд

# apt-get install pdns-backend-pgsql postgresql-11

После этого нужно в postgresql воздать пользователя и БД под PowerDNS.

psql> CREATE ROLE pdns WITH LOGIN;
psql> CREATE DATABASE pdns WITH OWNER pdns;

Создаём структуру БД

# su -s /bin/bash pdns
$ cat /usr/share/pdns-backend-pgsql/schema/schema.pgsql.sql | psql pdns

После того как всё успешно прокатится можно приступать к настройке самого ПО. Я решил отделить настройки бэкенда хранения от основных настроек сервера, поэтому у меня два файла.

/etc/powerdns/pdns.conf
8bit-dns=yes
allow-axfr-ips=10.21.0.0/16;10.20.34.0/24
api=yes
cache-ttl=1800
daemon=no
 
default-soa-name=ns1.owlhost.in
default-ttl=3600
 
disable-axfr=no
distributor-threads=2
do-ipv6-additional-processing=yes
include-dir=/etc/powerdns/pdns.d
local-address=10.21.5.8
local-ipv6=2a01:4f8:173:2298:1::10
log-dns-details=no
logging-facility=7
loglevel=3
master=yes
max-cache-entries=2000000
max-queue-length=6000000
max-tcp-connections=1000
negquery-cache-ttl=600
overload-queue-length=50000
query-cache-ttl=300
queue-limit=30000
receiver-threads=2
server-id=ns1.ow1.in
setgid=pdns
setuid=pdns
slave=no
socket-dir=/var/run
 
tcp-control-address=10.21.5.8
tcp-control-range=10.0.0.0/8
tcp-control-secret=controlSocketPassword
 
version-string=OwlDNSServer
/etc/powerdns/pdns.d/pgsql.conf
launch=gpgsql
 
gpgsql-host=/var/run/postgresql/
gpgsql-dbname=pdns
gpgsql-user=pdns

Правим адреса и остальные настроечки под себя и запускаемся

# systemctl restart pdns

Если всё хорошо - pdns запустится. Для второго сервера нужно поправить соответственно настройки master и slave наоборот.

Добавление первой зоны

Можно конечно использовать специальную морду для powerdns, через которую можно админить, но это не наш путь как минимум потому что оно ставится отдельно и требуется всякие дополнительные запчасти. Мы полезем в базу и натыкаем руками.

На данном этапе у нас есть два DNS сервера - один в master, второй в slave. Все действия будем производить на master'e и в конце добавим зону на slave сервере. Подключаемся к базе и начинаем создавать домен

postgres> INSERT INTO domains (name,type) VALUES ('example.com','MATER');
postgres> INSERT INTO records (domain_id,name,type,content,ttl) values (1,'example.com','SOA','ns1.owlhost.in ns.owlhost.in 1 10800 3600 604800 3600',3600);
postgres> INSERT INTO records (domain_id,name,type,content,ttl) (1,'example.com','NS','ns1.owlhost.in',3600);
postgres> INSERT INTO records (domain_id,name,type,content,ttl) (1,'example.com','NS','ns2.owlhost.in',3600);

Теперь добавляем домен на стороне slave сервера

postgres> insert into domains (name,master,type) values ('example.com','2a01:4f8:173:2298:1::10','SLAVE');

И через некоторое время, если всё настроено правильно - на slave доедут записи с мастера.

Работа с зонами

Поскольку у нас будет своя собственная система управления хостингом, то и работу с записями можно организовать более менее гибко. В моём случае это будет прямая работа с PostgreSQL через отдельного пользователя. А для обновления зон будет служить простейший скрипт, который будет запукаться по cron через равные промежутки времени, чистить кэш для обновлённых зон и отсылать нотифаи слейвам.

Для отдельно взятой зоны команды выглядят следующим образом

# pdns_control purge example.com
# pdns_control notify example.com

Первая очищает кэш для домена на мастере, а вторая рассылает всем слейвам уведомление об обновлении зоны.

1)
Domain names system
2)
написанного буквами, ow1.in, например
3)
К нему конечно можно прикрутить БД, но через такой мрак, что лучше нет