Теория и настройка DNS сервера (bind) на FreeBSD


Автор: Николаев Дмитрий (virus [at] subnets.ru) http://subnets.ru/blog/

Демон BIND (процесс named) позволяет поднять на FreeBSD свой DNS сервер.

Теория

DNS (Domain Name System — система доменных имён) — распределённая система (распределённая база данных), способная по запросу, содержащему доменное имя хоста (компьютера или другого сетевого устройства), сообщить IP адрес или (в зависимости от запроса) другую информацию. DNS работает в сетях TCP/IP. Как частный случай, DNS может хранить и обрабатывать и обратные запросы, определения имени хоста по его IP адресу: IP адрес по определённому правилу преобразуется в доменное имя, и посылается запрос на информацию типа “PTR“.

Вы зарегистрировали/купили свой домен в зоне ru (net, com, org, su, и т.д.), что дальше ? Теперь Вам нужен DNS сервер который будет отвечать за зону Вашего домена.


У Вас два варианта:
использовать чужой DNS сервер, например: nic.ru предоставляет услугу поддержки DNS или разместить зону Вашего домена на DNS серверах Вашего провайдера
Поднять собственный DNS сервер (при условии наличия статического внешнего IP-адреса)

Зона - файл в котором описано соответствие хостов домена и их IP-адресов.

В файле зоны могут быть описаны следущие типы:
SOA
NS
MX
A
PTR

В SOA входит:

Origin - первичный сервер зоны, т.е. сервер на котором размещается зона (авторизованый)
mail addr - Тут записан email адрес ответственного за зону.
Serial - Серийный номер версии; должен увеличиваться при каждом изменении в зоне - по нему вторичный сервер обнаруживает, что надо обновить информацию. Обычно пишется в виде <год><месяц><число><номер изменения>.
Refresh - Временной интервал в секундах, через который вторичный сервер будет проверять необходимость обновления информации.
Retry - Временной интервал в секундах, через который вторичный сервер будет повторять обращения при неудаче.
Expire - Временной интервал в секундах, через который вторичный сервер будет считать имеющуюся у него информацию устаревшей.
Minimum - Значение времени жизни информации на кэширующих серверах ((ttl) в последующих записях ресурсов).

Пример SOA:
$TTL 3600
@ IN SOA ns.subnets.ru. root.subnets.ru. (
2008071001; Serial
3600 ; Refresh
900 ; Retry
3600000 ; Expire
3600 ) ; Minimum

Где ns.subnets.ru - это Origin.

root.subnets.ru - mail address человека отвечающего за зону (символ “@” в файле зоны опускается).

Далее идут:

NS - Сервер Имен Описывает DNS-сервера содержащие (отвечающие за) зону.
A - Адрес, содержит адрес указанного имени.
CNAME (Canonical Name) - Каноническое имя, указывает псевдоним для официального имени хоста
MX (Mail Exchange) - Почтовый Сервер, такие записи используются для обозначения списка хостов, которые сконфигурированы для приема почты посланной на это доменное имя. Помимо адреса почтового сервера содержат числовое значение обозначающее приоритет, т.е. более низкие числа показывают более высокий приоритет, а приоритеты одинаковые отправители должны использовать в произвольном порядке хосты MX для равномерного распределения нагрузки.
TXT - Текст, содержит текстовые данные любого вида. Применяется редко и специфичным образом.
HINFO - Информация о Хосте, содержит некоторую информацию о машине, обычно - тип процессора и операционной системы, крайне редко используется.
PTR - Pointer - указатель, служит для выполнения обратного преобразования IP-адресов в имена хостов.

Пример:
IN NS ns.subnets.ru.
IN NS ns2.subnets.ru.
IN MX 10 mail

localhost IN A 127.0.0.1
subnets.ru. IN A 217.172.16.77
HINFO “INTEL P4? “FreeBSD”
ns IN A 217.172.16.77
ns2 IN A 217.172.16.1
mail IN A 217.172.16.77
www IN A 217.172.16.77

Вы можете заметить, что у некоторых записей в конце стоит символ “.” (точка). Точка в конце имени означает, что к этому имени не будет дописываться имя домена указанного в этой зоне.

Например:

Запись ns.subnets.ru (без точки) будет и интерпретироваться DNS сервером как ns.subnets.ru.subnets.ru, но если в конце поставить точку (ns.subnets.ru.), то сервер уже не будет дописывать имя домена subnets.ru в конец имени. Таким образом запись www (в примере выше) “превращается” в www.subnets.ru, т.к. символа точки после www нет.

Важное замечание:

Любой файл зоны должен оканчиваться пустой строкой ! Иначе в логах вы будете видеть подобное:

master/zone-name.ru:30: file does not end with newline

И данная зона обслуживаться DNS сервером не будет.

Так же отметим два понятия:
Зоны прямого просмотра
Зоны обратного просмотра

Зона прямого просмотра - когда на основе имени выдается IP-адрес. (subnets.ru -> 217.172.16.77)

Зона обратного - когда на основе IP-адреса выдается имя. (77.16.172.217.in-addr.arpa name = mega-net.ru.)

DNS работает на порту udp 53 - обслуживает запросы и на порту tcp 53 - обменивается зонами с другими DNS серверами.

DNS сервера (применительно к зонам) бывают двух типов:
master
slave

master - первичный DNS сервер отвечающий за зону. Именно на нем располагается файл зоны и на нам же делаются все изменения. Сначала все обращаются к первичному, но если он не отвечает (недоступен), то вступает slave.

slave - вторичный DNS сервер отвечающий за зону. Зону скачивает с первичного DNS сервера.

Резолв (resolve) - преобразование из имени в IP-адрес и наборот.

Практика

Поднимаем не кеширующий DNS сервер.

И опять два варианта:
Вопользоваться уже имеющимся в системе демоном (/usr/sbin/named)
Установить из портов более свежую версию

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

/usr/sbin/named -v

Для тех кто все же решил установить bind из портов:

cd /usr/ports/dns/bind9
make rmconfig
make install clean

При установке ставим галочку “REPLACE_BASE Replace base BIND with this version“, что бы заменить уже имеющимся в системе версию той, что мы устанавливаем.

Если вылезла ошибка:

make: don’t know how to make /usr/ports/dns/bind9/work/.build_done.bind9._usr_local. Stop
*** Error code 2

Не пугайтесь, просто запускайте make install clean ещё раз.

Текущая, на момент написания статьи, версия в портах bind-9.3.5-P1, в которой исправлена ошибка о которой говорится тут. Её же можно взять тут.

Приступаем к настройке.

По умолчанию директория bind это /var/named/etc/namedb/ или /etc/namedb/ которая является симлинком (символической ссылкой) на первую (далее я буду использовать /etc/namedb/).

Итак, переходим в директорию /etc/namedb/. Основной конфигурационный файл это named.conf.

Простейший пример файла named.conf:
options {
directory “/etc/namedb”;
pid-file “/var/run/named/pid”;
dump-file “/var/dump/named_dump.db”;
statistics-file “/var/stats/named.stats”;
listen-on {
127.0.0.1;
194.87.0.50;
};
allow-recursion{
127.0.0.1;
192.168.0.0/16;
};
recursive-clients 30000;
};

acl “trusted-dns”{
127.0.0.1;
194.58.241.26;
};

logging {
category lame-servers { null; };
};

zone “.” {
type hint;
file “named.root”;
};

zone “0.0.127.IN-ADDR.ARPA” {
type master;
file “master/localhost.rev”;
};

// RFC 3152
zone “1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA” {
type master;
file “master/localhost-v6.rev”;
};

zone “mydomain.ru” {
type master;
file “master/madomain.ru.zone”;
allow-transfer { trusted-dns;};
};

Как мы видим файл состоит из блоков/секций. Блоки:
options
listen-on
allow-recursion
acl
logging
zone

Разберем некоторые:

listen-on - IP-адреса интерфейсов сервера на котором будет запущена служба named.

allow-recursion - список IP-адресов и/или подсетей которым разрешена рекурсия. По умолчанию DNS сервер обслуживает запросы любых клиентов для любых доменов, но если вы не хотите, чтобы кто то использовал Ваш DNS сервер (бережете трафик или ресурсы машины) необходимо использовать эту директиву, которая “скажет” DNS серверу о том, что для IP-адресов которых нет в списке allow-recursion отвечать только на запросы касаемые зон которые прописаны на данном DNS сервере.

Пример поведения без allow-recursion:

Клиент “А” (IP-адрес 192.168.15.9) запрашивает IP-адрес для имени www.ya.ru. Сервер ему ответит:

www.ya.ru canonical name = ya.ru.
Name: ya.ru
Address: 213.180.204.8

Что означает что www.ya.ru ссылается на имя ya.ru, а оно уже имеет IP-адрес 213.180.204.8

Клиент “Б” (IP-адрес 10.4.15.45) запрашивает IP-адрес для имени www.ya.ru. Сервер ему ответит то же самое, что ответил клиенту “А” с IP-адресом 192.168.15.9

Пример поведения с allow-recursion:

Как мы видим из примера файла named.conf в секции allow-recursion описан хост 127.0.0.1 (localhost) и подсеть 192.168.0.0/16 (которая означает диапазон адресов)

Итак опять же берем двух клиентов “А” и “Б”. Для клиента “А” нечего не изменится, т.к. его IP-адрес входит в подсеть 192.168.0.0/16 которая описана в секции allow-recursion, а вот для клиента “Б” возникнет ситуация когда сервер на его запрос ответит:

*** Can’t find www.ru: No answer

потому что рекурсия для хоста 10.4.15.45 (или подсети 10.0.0.0/8) не разрешена. Но при этом если клиент “Б” обратится с запросом о имени mydomain.ru он получит ответ об IP-адресе данного имени, т.к. DNS сервер всегда будет отвечать на запросы о тех доменах которые прописаны в его конфигурации.

recursive-clients - максимальное кол-во одновременно обслуживаемых рекурсивных запросов от клиентов

acl - секция позволяющая создать access control list из IP-адресов, дабы потом не перечеслять их каждый раз в других секциях. acl “trusted-dns” в данном случае описывает IP-адреса доверительных DNS серверов которым позволено скачивать зоны полностью с нашего DNS сервера.

zone - собственно секция отвечающая за поддержку нашего тестового домена mydomain.ru данный сервер является мастером (master) для данной зоны. Внутри секции zone идет “ссылка” на “trusted-dns”, это, как вы должны помнить, acl смысл которого описан чуть выше. Секция zone обязательно должна описывать: тип (type) зоны (master или slave), путь до файла (file) зоны. В случаее если это тип slave доавляется обязательный параметр masters:

masters { IP-ADDRESS; };

где IP-ADDRESS это адрес первичного DNS сервера для данной зоны.

зона “0.0.127.IN-ADDR.ARPA” это зона обратного просмотра для localhost. Если в папке master у вас нет файлов localhost.rev и localhost-v6.rev, то в /etc/namedb есть файл make-localhost и выполнив команду:

sh make-localhost

эти два файла будут созданы автоматически.

Для начала с named.conf закончили. Теперь создадим файл зоны для нашего домена.


Переходим в папку /etc/namedb/master. Создаем файл madomain.ru.zone следущего содержания:
$TTL 3600
@ IN SOA ns.mydomain.ru. root.mydomain.ru. (
2008071001; Serial
3600 ; Refresh
900 ; Retry
3600000 ; Expire
3600 ) ; Minimum

IN NS ns.mydomain.ru.
IN NS ns2.mydomain.ru.
IN MX 10 mail

localhost IN A 127.0.0.1
mydomain.ru. IN A 194.87.0.51
HINFO “INTEL P4? “FreeBSD”
ns IN A 194.87.0.50
ns2 IN A 194.58.241.26
mail IN A 194.87.0.51
www IN A 194.87.0.51

Сохраняем файл зоны. Получили:
Первичный DNS сервер зоны mydomain.ru это ns.mydomain.ru и он имеет IP-адрес 194.87.0.50
Вторичный DNS сервер ns2.mydomain.ru имеет IP-адрес 194.58.241.26
Mail сервер домена располагается по имени mail.mydomain.ru и имеет IP-адрес 194.87.0.51
WWW сервер по имени www.mydomain.ru имеет IP-адрес 194.87.0.51
“Корень домена” - имя mydomain.ru располагается за адресом 194.87.0.51

На первый взгяд все. Named мы настроили, файл зоны создали, но давайте позаботимся о собственном удобстве.

RNDC

Утилита позволяющая управлять демоном named. Проста в установке. Запустим команду

rndc-confgen

На экран будет выведен текст (который будет нужен для двух файлов):
# Start of rndc.conf
key “rndc-key” {
algorithm hmac-md5;
secret “328Sa3UFyO+MbLriage+Cw==”;
};

options {
default-key “rndc-key”;
default-server 127.0.0.1;
default-port 953;
};
# End of rndc.conf

# Use with the following in named.conf, adjusting the allow list as needed:
# key “rndc-key” {
# algorithm hmac-md5;
# secret “328Sa3UFyO+MbLriage+Cw==”;
# };
#
# controls {
# inet 127.0.0.1 port 953
# allow { 127.0.0.1; } keys { “rndc-key”; };
# };
# End of named.conf

То что между # Start of rndc.conf и # End of rndc.conf кладем в созданный файл rndc.conf (он располагается в той же директории, что и named.conf)

То что между # Use with the following in named.conf… и # End of named.conf дописываем в наш файл named.conf, но символ комментария “#” убираем, вот что в итоге дописываем в самый конец файла named.conf:
key “rndc-key” {
algorithm hmac-md5;
secret “328Sa3UFyO+MbLriage+Cw==”;
};

controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { “rndc-key”; };
};

Благодаря этому нам станут доступны команды (но только с этого сервера, т.к. прописан 127.0.0.1 в кач-ве IP адреса, секция controls):
rndc
Usage: rndc [-c config] [-s server] [-p port]
[-k key-file ] [-y key] [-V] command

command is one of the following:

reload Reload configuration file and zones.
reload zone [class [view]]
Reload a single zone.
refresh zone [class [view]]
Schedule immediate maintenance for a zone.
retransfer zone [class [view]]
Retransfer a single zone without checking serial number.
freeze zone [class [view]]
Suspend updates to a dynamic zone.
thaw zone [class [view]]
Enable updates to a frozen dynamic zone and reload it.
reconfig Reload configuration file and new zones only.
stats Write server statistics to the statistics file.
querylog Toggle query logging.
dumpdb [-all|-cache|-zones] [view …]
Dump cache(s) to the dump file (named_dump.db).
stop Save pending updates to master files and stop the server.
stop -p Save pending updates to master files and stop the server
reporting process id.
halt Stop the server without saving pending updates.
halt -p Stop the server without saving pending updates reporting
process id.
trace Increment debugging level by one.
trace level Change the debugging level.
notrace Set debugging level to 0.
flush Flushes all of the server’s caches.
flush [view] Flushes the server’s cache for a view.
flushname name [view]
Flush the given name from the server’s cache(s)
status Display status of the server.
recursing Dump the queries that are currently recursing (named.recursing)
*restart Restart the server.

* == not yet implemented
Version: 9.3.4-P1

Т.е. перезапуск named можно произвести легким

rndc reload

или получить статистику

rndc status

number of zones: 3
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is OFF
recursive clients: 0/30000
tcp clients: 0/100
server is up and running

Подготовка к запуску

Открываем файл /etc/rc.conf (для автозапуска после ребута) и дописываем в него:

named_enable=”YES”
named_program=”/usr/sbin/named”
named_flags=”-u bind -c /etc/namedb/named.conf”

Откроем файл /etc/syslog.conf (логи, куда же без них) и допишем в него:

!named
*.* /var/log/named.log

Создадим пустой файл /var/log/named.log

touch /var/log/named.log

выставим на этот файл права

chown bind:bind /var/log/named.log

Перезапустим процесс syslogd для того чтобы он перечитал конфиг

/etc/rc.d/syslogd restart

Запускаемся

Выполняем команду
/usr/sbin/named -t /var/named -u bind -c /etc/namedb/named.conf

смотрим, что у нас в логах

tail -F /var/log/named.log

Если мы видим сообщение:

loading configuration from ‘/etc/namedb/named.conf’
zone mydomain.ru/IN: loaded serial 2008071001
zone mydomain.ru/IN: sending notifies (serial 2008071001)

То значит вы нигде не ошиблись и named успешно запущен и зона mydomain.ru загружена.

Если вы видите сообщение:

config: none:0: open: /etc/namedb/named.conf: permission denied
general: reloading configuration failed: permission denied

Это означает что named (из-за отсутствия прав) не может прочесть конфиг. Исправим это:

cd /var
chown -R bind:bind named

тем самым изменили права на папку named установив владельца (owner) bind, группу (group) bind

Проверить наличие владельца с именем bind можно

команда
результат

Проверяем наличие в системе пользователя bind:

id -P bind
bind:*:53:53::0:0:Bind Sandbox:/:/usr/sbin/nologin

Проверяем наличе в системе группы bind:

cat /etc/group | grep bind
bind:*:53:

Или узнаем и то и то одной командой:

id bind
uid=53(bind) gid=53(bind) groups=53(bind)

Точно убедиться что named запущен:

ps -ax | grep named
/usr/sbin/named -t /var/named -u bind -c /etc/namedb/named.conf

sockstat | grep :53
bind named 67664 20 udp4 194.87.0.50:53 *:*
bind named 67664 21 tcp4 194.87.0.50:53 *:*
bind named 67664 22 udp4 127.0.0.1:53 *:*
bind named 67664 23 tcp4 127.0.0.1:53 *:*

Проверить наличие резолва можно командой:

nslookup mydomain.ru
Server: 127.0.0.1
Address: 127.0.0.1#53

Name: mydomain.ru
Address: 194.87.0.51

Если IP-адрес выдается, то вы все сделали правильно.

Командой nslookup можно проверять любые домены, эта команда есть даже в Windows

Прочтите man nslookup

Иерархия DNS:

Практически повсеместно корневой домен (root) обозначают символом “.”, на самом деле точка - разделитель компонентов доменного имени, а т. к. у корневого домена нет обозначения, то полное доменное имя кончается точкой. Тем не менее, это обозначение достаточно прочно закрепилось в литературе в качестве обозначения корневого домена. Далее по иерархии идут домены верхнего уровня (TLD, Top Level Domain), за ними домены второго уровня, далее третьего и т. д., друг от друга они отделяются точками.

Обновлено: 12.03.2015