18 Сентябрь 2016

Настройка первичного DNS-сервера на базе NSD

Setting master DNS server using NSD

Как известно, основной функцией DNS-сервера является преобразование текстовых имён узлов в сети Интернет (доменов) в числовые IP-адреса, с помощью которых и осуществляется маршрутизация данных. Помимо этого на базе той же технологии Domian Name System в настоящее время реализуются многие технологии, связанные с обеспечением безопасности, аутентификации и политики доступа, а также автоматизации настроек клиентского программного обеспечения.

В подавляющем большинстве случаев DNS-серверы, которые поддерживают информацию о том или ином доменном имени, размещаются у регистраторов доменов, провайдеров хостинга или услуг досупа в Интернет. Такой подход, с одной стороны, снимает вопросы базовой настройки, поддержания и обеспечения надёжности с владельца доменного имени, а, с другой, имеет ряд ограничений связанных с тонкой настройкой, оперативной актуализацией содержащихся в DNS-записях сведений и необходимой в ряде случаев автоматизацией этих процессов. Кроме того, далеко не все предоставляющие услуги DNS-хостинга организации поддерживают современные типы ресурсных записей.

Для решения этих проблем разумным решением представляется организация своего собственного первичного DNS на базе программного решения, которое будет поддерживать современные технологии. К числу подобных, безусловно, относится и DNS-сервер NSD.

1. Установка NSD

Рассмотрим пример настройки DNS-зоны для домена kostikov.co, который использует этот сайт.

Все настройки будут производиться на базе FreeBSD.

root@beta:~ # uname -v
FreeBSD 11.0-RC2 #0 r304729: Wed Aug 24 06:59:03 UTC 2016     root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC

Для начала необходимо установить сам пакет NSD. Ввиду того, что опции по умолчанию подобраны разумно, можно установить его из пакетов. Но я воспользуюсь традиционной сборкой из исходых текстов через систему портов Freebsd, добавив функционал сборки статистики и отключив не используемый в данной системе IPv6.

root@beta:~ # cd /usr/ports/dns/nsd/
root@beta:/usr/ports/dns/nsd # make config
...
root@beta:/usr/ports/dns/nsd # make showconfig
===> The following configuration options are available for nsd-4.1.12:
     BIND8_STATS=off: BIND8-like NSTATS & XSTATS
     CHECKING=off: Internal run-time checks
     DOCS=on: Build and/or install documentation
     IPV6=off: IPv6 protocol support
     LARGEFILE=on: Largefile support
     MINRESPSIZE=on: Minimial response sizing
     MMAP=off: Use mmap instead of malloc (experimental)
     MUNIN_PLUGIN=off: Install Munin plugin (requires BIND8_STATS)
     NSEC3=on: NSEC3 support
     ROOT_SERVER=off: Configure as a root server
     RRL=on: Response Rate Limiting
     ZONE_STATS=on: Separate statistics for each zone
===> Use 'make config' to modify these settings
root@beta:/usr/ports/dns/nsd # make install clean
===>  License BSD3CLAUSE accepted by the user
===>  Found saved configuration for nsd-4.1.12
===>   nsd-4.1.12 depends on file: /usr/local/sbin/pkg - found
===> Fetching all distfiles required by nsd-4.1.12 for building
===>  Extracting for nsd-4.1.12
=> SHA256 Checksum OK for nsd-4.1.12.tar.gz.
...

Не откладывая дело на потом, надо прописать запуск демона NSD в файл начальной инициализации системы rc.conf.

root@beta:/usr/ports/dns/nsd # cat /etc/rc.conf | grep nsd
nsd_enable="YES"

Теперь создадим структуру рабочих каталогов для нашего DNS-сервера в специально созданном в процессе установки каталоге /usr/local/etc/nsd/. Это делается для обеспечения дополнительной безопасности нашей системы через запуск NSD в chroot.

root@beta:/usr/ports/dns/nsd # cd /usr/local/etc/nsd/
root@beta:/usr/local/etc/nsd # ll
total 2
-rw-r--r--  1 root  wheel   1874 17 сент. 17:41 nsd.conf
-rw-r--r--  1 root  wheel  10299 17 сент. 17:41 nsd.conf.sample
root@beta:/usr/local/etc/nsd # mkdir -p var/db/nsd
root@beta:/usr/local/etc/nsd # mkdir -p var/run/nsd
root@beta:/usr/local/etc/nsd # mkdir var/log
root@beta:/usr/local/etc/nsd # mkdir tmp

Ввиду того, что демон NSD будет работать от имени nsd, следует дать ему права на только что созданные каталоги.

root@beta:/usr/local/etc/nsd # chown nsd:nsd /usr/local/etc/nsd
root@beta:/usr/local/etc/nsd # chown -R nsd:nsd var/
root@beta:/usr/local/etc/nsd # chown -R nsd:nsd tmp/

2. Базовая настройка NSD

Теперь следует создать базовую настройку для только что установленного DNS-сервера. Это делается на базе установленного в рабочий каталог образца конфигурационного файла nsd.conf. Однако, для начала, следует сгенерировать ключи для удалённого управления сервером с помощью утилиты nsd-control-setup, которая включена в состав пакета NSD.

root@beta:/usr/local/etc/nsd # nsd-control-setup
setup in directory /usr/local/etc/nsd
generating nsd_server.key
Generating RSA private key, 1536 bit long modulus
....++++
.++++
e is 65537 (0x10001)
generating nsd_control.key
Generating RSA private key, 1536 bit long modulus
.................++++
..............................................................++++
e is 65537 (0x10001)
create nsd_server.pem (self signed certificate)
create nsd_control.pem (signed client certificate)
Signature ok
subject=/CN=nsd-control
Getting CA Private Key
Setup success. Certificates created. Enable in nsd.conf file to use

Для данного сайта файл конфигурации приобретёт следующий вид.

root@beta:/usr/local/etc/nsd # cat nsd.conf
#
# nsd.conf -- the NSD(8) configuration file, nsd.conf(5).
#
# Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
#
# See LICENSE for the license.
#

# -- by Max Kostikov 2016-09-17

server:
        ip-address: 10.10.10.10
        debug-mode: no
        do-ip6: no
        verbosity: 3
        chroot: "/usr/local/etc/nsd"
        zonesdir: "/usr/local/etc/nsd/zones"
        zonelistfile: "/usr/local/etc/nsd/var/db/nsd/zone.list"
        database: "/usr/local/etc/nsd/var/db/nsd/nsd.db"
        logfile: "/usr/local/etc/nsd/var/log/nsd.log"
        pidfile: "/usr/local/etc/nsd/var/run/nsd/nsd.pid"
        xfrdfile: "/usr/local/etc/nsd/var/db/nsd/xfrd.state"
        xfrdir: "/usr/local/etc/nsd/tmp"

remote-control:
        control-enable: yes
        server-key-file: "/usr/local/etc/nsd/nsd_server.key"
        server-cert-file: "/usr/local/etc/nsd/nsd_server.pem"
        control-key-file: "/usr/local/etc/nsd/nsd_control.key"
        control-cert-file: "/usr/local/etc/nsd/nsd_control.pem"

# -- for secondary @ dns.he.net
pattern:
        name: "xfr-he"
        zonefile: "%s/%s.zone"
        notify: 216.218.130.2 NOKEY
        provide-xfr: 216.218.133.2 NOKEY

zone:
        name: "kostikov.co"
        include-pattern: "xfr-he"

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

  • server отвечает за базовые настройки сервера;
  • remote-control разрешает удалённое управление по ключам при помощи специальной утилиты nsd-control;
  • использование pattern позволяет использовать типовые настройки для любого количества доменных имён;
  • и, наконец, zone описывает мой домен с использованием ранее прописанного шаблона xfr-he.

Обратите внимание, что наш первичный DNS-сервер будет обслуживать домен kostikov.co, а вторичные DNS-серверы будут поддерживаться на базе популярного сервиса публичных DNS от американского провайдера Hurricane Electric. Для разрешения синхронизации зон на вторичные серверы в шаблоне xfr-he прописаны IP-адреса серверов - отдельный для запроса AXFR зоны в параметре xfr-he (IP соответствует имени сервера slave.dns.he.net), и отдельный для нотификации об обновлении зоны в параметре notify (соответствует серверу ns1.he.net). Параметр NOKEY указаывает на отсутствие дополнительной аутентификации для сихнронизации зон, поскольку публичный DNS от Hurricane Electric в настоящее время не поддерживает механизм TSIG.

Также следует учесть ещё один тонкий момент, который касается типовых инсталляций FreeBSD. Начиная с версии 10.0 в её состав включён рекурсивный кэширующий DNS-сервер Unbound, который написан тем же автором, что и NSD - компанией NLnet labs. В этой связи, если предполагается использование обоих этих серверов в рамках одной серверной инталляции, то следует позаботиться об разделении интефрейсов, на которых они будут слушать и отвечать на DNS-запросы. В моём случае Undound работает на интерфейсе локального хоста с IP 127.0.0.1, а NSD - на внешнем, адрес которого прописан в параметре конфигурации ip-address.

3. Настройка зоны для домена

Теперь остаётся лишь прописать файл зоны для домена kostikov.co. Формат его файла, который, как следует из базовой настройки, будет размещатся непосредственно в рабочем каталоге зон NSD zones в отдельном подкаталоге именованным так же как и домен kostikov.co под именем kostikov.co.zone.

root@beta:/usr/local/etc/nsd # cat zones/kostikov.co/kostikov.co.zone
$ORIGIN kostikov.co.
$TTL 86400
@       IN      SOA     my.server. hostmaster.my.server. (
                        2016091705      ; serial
                        10800           ; refresh
                        1800            ; retry
                        604800          ; expire
                        86400   )       ; minimum
; NS
        IN      NS      my.server.
        IN      NS      ns1.he.net.
        IN      NS      ns2.he.net.
        IN      NS      ns3.he.net.
        IN      NS      ns4.he.net.
        IN      NS      ns5.he.net.
; MX
        IN      MX      10 my.server.
        IN      SPF     "v=spf1 +mx -all"
        IN      TXT     "v=spf1 +mx -all"
dkim._domainkey.kostikov.co.    IN      TXT     "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJjSZ1Fd0ZbE8V0t6V+/7GZ+DNaj5qJT0fQcXVxWeo3uKJ85kpZ0AbLExu50tbZuz1AiPwhv9inqXltHWi5aqsSfiFODQH8McjWttFx0iM8cyBHw+DJ5CXAONUXFfSFPNOF7+J5BKpcx4hyu0j8z2HQIzQCHR9Q7Rky/C+uFxIxwIDAQAB"
_adsp._domainkey.kostikov.co.   IN      TXT     "dkim=all"
_dmarc.kostikov.co.             IN      TXT     "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc-rua@kostikov.co"
; WWW
@       IN      A       10.10.10.10
www     IN      CNAME   kostikov.co.

Формат его близок к стандартному формату BIND. Для удобства чтения блоки DNS-записей разделены на относящиемя к описанию DNS (; NS), почте (; MX) и веб-сервисам (; WWW). Обратите также внимание на первое число в записи SOA (; serial). При каждом измнении настроек DNS-зоны для домена его следует изменять в сторону увеличения. Это служит индикатором его обновления и вызывает начало процесса его передачи на вторичные серверы.

Теперь осталось запустить сам демон нашего DNS-сервера и убедиться в его работоспособности.

root@beta:/usr/local/etc/nsd # service nsd start
Starting nsd.
root@beta:/usr/local/etc/nsd # netstat -anfinet | grep '.53'
tcp4       0      0 10.10.10.10.53       *.*                    LISTEN
tcp4       0      0 127.0.0.1.53           *.*                    LISTEN
udp4       0      0 10.10.10.10.53       *.*
udp4       0      0 127.0.0.1.53           *.*

В выводе сетевой статистики видно, что в данной системе имеется два работающих DNS-сервера - первый, авторитативный NSD, слушает на внешнем интерфейсе с IP-адресом 10.10.10.10, а второй - кэширующий Unbound работает исключительно на localhost.

Теперь следует добавить вторичный сервер на сервисе от Hurricane Electric и убедиться, что произошла успешная синхронизация зон и вторичные серверы корректно отвечают на запрос нашего домена.

Add slave DNS

root@beta:/usr/local/etc/nsd # cat var/log/nsd.log
[2016-09-17 17:02:31.807] nsd[73485]: notice: nsd starting (NSD 4.1.12)
[2016-09-17 17:02:31.816] nsd[73485]: info: setup SSL certificates
[2016-09-17 17:02:31.897] nsd[73487]: info: zone kostikov.co read with success
[2016-09-17 17:02:31.900] nsd[73487]: info: zone kostikov.co written to db
[2016-09-17 17:06:04.557] nsd[73529]: info: axfr for kostikov.co. from 216.218.133.2
...
root@beta:/usr/local/etc/nsd # root@beta:/usr/local/etc/nsd # host -a kostikov.co ns1.he.net
Trying "kostikov.co"
Using domain server:
Name: ns1.he.net
Address: 216.218.130.2#53
Aliases:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28926
;; flags: qr aa rd; QUERY: 1, ANSWER: 11, AUTHORITY: 0, ADDITIONAL: 9

;; QUESTION SECTION:
;kostikov.co.                   IN      TYPE255

;; ANSWER SECTION:
kostikov.co.            86400   IN      NS      ns5.he.net.
kostikov.co.            86400   IN      NS      my.server.
kostikov.co.            86400   IN      SPF     "v=spf1 +mx -all"
kostikov.co.            86400   IN      NS      ns3.he.net.
kostikov.co.            86400   IN      SOA     my.server. hostmaster.my.server. 2016091705 10800 1800 604800 86400
kostikov.co.            86400   IN      TXT     "v=spf1 +mx -all"
kostikov.co.            86400   IN      NS      ns1.he.net.
kostikov.co.            86400   IN      MX      10 my.server.
kostikov.co.            86400   IN      NS      ns4.he.net.
kostikov.co.            86400   IN      A       10.10.10.10
kostikov.co.            86400   IN      NS      ns2.he.net.

;; ADDITIONAL SECTION:
ns3.he.net.             86400   IN      A       216.218.132.2
ns2.he.net.             86400   IN      A       216.218.131.2
my.server.              86400   IN      A       10.10.10.10
ns5.he.net.             86400   IN      A       216.66.80.18
ns1.he.net.             86400   IN      A       216.218.130.2
ns4.he.net.             86400   IN      A       216.66.1.2
ns3.he.net.             86400   IN      AAAA    2001:470:300::2
ns2.he.net.             86400   IN      AAAA    2001:470:200::2
ns5.he.net.             86400   IN      AAAA    2001:470:500::2

Received 466 bytes from 216.218.130.2#53 in 69 ms

Как видно, всё прошло удачно. NSD запущен без ошибок, зона синхронизировалась с вторичными серверами и они корректно отвечают на запросы.

И, наконец, следует сообщить регистратору нашего домена о смене DNS-серверов, которые его поддерживают - они указаны в типе DNS-записи NS в описании зоны.

4. PROFIT!

Статья была полезной? Тогда прошу не стесняться и поддерживать деньгами через PayPal или Яндекс.Деньги.


DNS  FreeBSD  security