DNS

17.9. DNS

Текст предоставилChern Lee.

17.9.1. Обзор

По умолчанию во FreeBSD используется одна из версий программы BIND (Berkeley Internet Name Domain), являющейся самой распространенной реализацией протокола DNS. DNS - это протокол, при помощи которого имена преобразуются в IP-адреса и наоборот. Например, в ответ на запрос о www.FreeBSD.org будет получен IP-адрес веб-сервера Проекта FreeBSD, а запрос о ftp.FreeBSD.org возвратит IP-адрес соответствующей машины с FTP-сервером. Точно также происходит и обратный процесс. Запрос, содержащий IP-адрес машины, возвратит имя хоста. Для выполнения запросов к DNS вовсе не обязательно иметь в системе работающий сервер имён.

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

В этом документа рассматривается BIND 8.x, так как это стабильная версия, используемая во FreeBSD. BIND 9.x может быть установлен как порт net/bind9.

Протокол DNS стандартизован в RFC1034 и RFC1035.

На данный момент пакет BIND поддерживается Internet Software Consortium (www.isc.org)

17.9.2. Используемая терминология

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

ТерминОпределение
прямой запрос к DNS (forward DNS)преобразование имён хостов в адреса IP
ориджин (origin)обозначает домен, покрываемый конкретным файлом зоны
named, bind, сервер имёнобщеупотребительные названия для обозначения пакета BIND, обеспечивающего работу сервера имён во FreeBSD.
ресолверсистемный процесс, посредством которого машина обращается к серверу имён для получения информации о зоне
обратный DNS (reverse DNS)операция, обратная прямому запросу к DNS, преобразование адресов IP в имена хостов
корневая зонаболее точно, ".", служит для обозначения корня, или начала зоны. Все зоны находятся под ней, так же, как все файлы располагаются ниже корневого каталога. Это начало иерархии зон Интернет.
зоналюбой отдельный домен, поддомен или область, контролируемые в DNS.

Примеры зон:

  • . является корневой зоной

  • org. является зоной ниже корневой зоны

  • example.org является зоной под зоной org.

  • foo.example.org. является поддоменом, зоной под зоной example.org.

  • 1.2.3.in-addr.arpa является зоной, в которую включены все IP-адреса, формирующие пространство адресов 3.2.1.*.

Как можно видеть, уточняющая часть имени хоста появляеся слева. Например, example.org. более точен, чем org., также, как org. более точен, чем корневая зона. Расположение каждой части имени хоста сильно похоже на файловую систему: каталог /dev расположен в корневой файловой системе, и так далее.

17.9.3. Причины, по которым вам может понадобиться сервер имён

Сервера имён обычно используются в двух видах: авторитетный сервер имён и кэширующий сервер имён.

Авторитетный сервер имён нужен, когда:

  • нужно предоставлять информацию о DNS остальному миру, отвечая на запросы авторизированно.

  • зарегистрирован домен, такой, как example.org и в этом домене требуется поставить имена машин в соответствие с их адресами IP.

  • блоку адресов IP требуется обратные записи DNS (IP в имена хостов).

  • резервный (slave) сервер имён должен отвечать на запросы о домене, когда основной не работает или не доступен.

Кэширующий сервер имён нужен, когда:

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

  • требуется уменьшение общего сетевого трафика (DNS составляет около 5% всего трафика Интернет, или чуть больше).

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

17.9.4. Как это работает

Во FreeBSD даемон BIND, по очевидным причинам, называется named.

ФайлОписание
namedдаемон BIND
ndcпрограмма управления даемоном сервера имён
/etc/namedbкаталог, в котором располагается вся информация о зонах BIND
/etc/namedb/named.confконфигурационный файл для даемона

Файлы зон обычно располагаются в каталоге /etc/namedb и содержат информацию о зоне DNS, за которую отвечает сервер имён.

17.9.5. Запуск BIND

Так как сервер имён BIND устанавливается по умолчанию, его настройка сравнительно проста.

Чтобы даемон named запускался во время загрузки, сделайте следующие изменения в файле /etc/rc.conf

    named_enable="YES"

Для запуска даемона вручную (после его настройки)

    # ndc start

17.9.6. Конфигурационные файлы

17.9.6.1. make-localhost

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

    # cd /etc/namedb
# sh make-localhost

для того, чтобы правильно создать файл /etc/namedb/localhost.rev локальной обратной зоны для loopback-интерфейса.

17.9.6.2. /etc/namedb/named.conf

    // $FreeBSD$
    //
    // Refer to the named(8) manual page for details.  If you are ever going
    // to setup a primary server, make sure you've understood the hairy
    // details of how DNS is working.  Even with simple mistakes, you can
    // break connectivity for affected parties, or cause huge amount of
    // useless Internet traffic.
    
    options {
            directory "/etc/namedb";
    
    // In addition to the "forwarders" clause, you can force your name
    // server to never initiate queries of its own, but always ask its
    // forwarders only, by enabling the following line:
    //
    //      forward only;
    
    // If you've got a DNS server around at your upstream provider, enter
    // its IP address here, and enable the line below.  This will make you
    // benefit from its cache, thus reduce overall DNS traffic in the
    Internet.
    /*
            forwarders {
                    127.0.0.1;
            };
    */

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

Warning127.0.0.1 здесь работать не будет. Измените его на IP-адрес сервера имён провайдера.

    /*
             * If there is a firewall between you and name servers you want
             * to talk to, you might need to uncomment the query-source
             * directive below.  Previous versions of BIND always asked
             * questions using port 53, but BIND 8.1 uses an unprivileged
             * port by default.
             */
            // query-source address * port 53;
    
            /*
             * If running in a sandbox, you may have to specify a different
             * location for the dumpfile.
             */
            // dump-file "s/named_dump.db";
    };
    
    // Note: the following will be supported in a future release.
    /*
    host { any; } {
            topology {
                    127.0.0.0/8;
            };
    };
    */
    
    // Setting up secondaries is way easier and the rough picture for this
    // is explained below.
    //
    // If you enable a local name server, don't forget to enter 127.0.0.1
    // into your /etc/resolv.conf so this server will be queried first.
    // Also, make sure to enable it in /etc/rc.conf.
    
    zone "." {
            type hint;
            file "named.root";
    };
    
    zone "0.0.127.IN-ADDR.ARPA" {
            type master;
            file "localhost.rev";
    };
    
    zone
    "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.INT" {
            type master;
            file "localhost.rev";
    };
    
    // NB: Do not use the IP addresses below, they are faked, and only
    // serve demonstration/documentation purposes!
    //
    // Example secondary config entries.  It can be convenient to become
    // a secondary at least for the zone where your own domain is in.  Ask
    // your network administrator for the IP address of the responsible
    // primary.
    //
    // Never forget to include the reverse lookup (IN-ADDR.ARPA) zone!
    // (This is the first bytes of the respective IP address, in reverse
    // order, with ".IN-ADDR.ARPA" appended.)
    //
    // Before starting to setup a primary zone, better make sure you fully
    // understand how DNS and BIND works, however.  There are sometimes
    // unobvious pitfalls.  Setting up a secondary is comparably simpler.
    //
    // NB: Don't blindly enable the examples below. :-)  Use actual names
    // and addresses instead.
    //
    // NOTE!!! FreeBSD runs bind in a sandbox (see named_flags in rc.conf).
    // The directory containing the secondary zones must be write accessible
    // to bind.  The following sequence is suggested:
    //
    //      mkdir /etc/namedb/s
    //      chown bind:bind /etc/namedb/s
    //      chmod 750 /etc/namedb/s

Дополнительная информация о запуске BIND в ограниченном окружении находится в соответствующем разделе.

    /*
    zone "example.com" {
            type slave;
            file "s/example.com.bak";
            masters {
                    192.168.1.1;
            };
    };
    
    zone "0.168.192.in-addr.arpa" {
            type slave;
            file "s/0.168.192.in-addr.arpa.bak";
            masters {
                    192.168.1.1;
            };
    };
    */

Это примеры описаний прямой и обратной зон из файла named.conf для вторичных серверов.

Для каждого новой зоны, которую будет обслуживать сервер имён, в файл named.conf должна быть добавлена запись

К примеру, самая простая запись для домена example.org может выглядеть вот так:

    zone "example.org" {
    	type master;
    	file "example.org";
    };

Зона является первичной, что отражается в поле type, и информация о зоне хранится в файле /etc/namedb/example.org, что указывается в поле file.

    zone "example.org" {
    	type slave;
    	file "example.org";
    };

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

17.9.6.3. Файлы зон

Пример файла зоны example.org для основного сервера (располагающийся в файле /etc/namedb/example.org) имеет такой вид:

    $TTL 3600
    
    example.org. IN SOA ns1.example.org. admin.example.org. (
                            5               ; Serial
                            10800           ; Refresh
                            3600            ; Retry
                            604800          ; Expire
                            86400 )         ; Minimum TTL
    
    ; DNS Servers
    @       IN NS           ns1.example.org.
    @       IN NS           ns2.example.org.
    
    ; Machine Names
    localhost       IN A    127.0.0.1
    ns1             IN A    3.2.1.2
    ns2             IN A    3.2.1.3
    mail            IN A    3.2.1.10
    @               IN A    3.2.1.30
    
    ; Aliases
    www             IN CNAME        @
    
    ; MX Record
    @               IN MX   10      mail.example.org.

Заметьте, что все имена хостов, оканчивающиеся на ".", задают полное имя, тогда как все имена без символа "." на конце считаются заданными относительно ориджина. Например, www преобразуется в www + origin. В нашем воображаемом файле ориджином является example.org., так что www преобразуется в www.example.org.

Файл зоны имеет следующий формат:

    recordname      IN recordtype  value

Наиболее часто используемые записи DNS:

SOA

начало зоны ответственности

NS

авторитативный сервер имен

A

адрес хоста

CNAME

каноническое имя для алиаса

MX

обмен почтой

PTR

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

    example.org. IN SOA ns1.example.org. admin.example.org. (
                            5               ; Serial
                            10800           ; Refresh after 3 hours
                            3600            ; Retry after 1 hour
                            604800          ; Expire after 1 week
                            86400 )         ; Minimum TTL of 1 day

example.org.

имя домена, а также ориджин для этого файла зоны.

ns1.example.org.

основной/авторитативный сервер имён для этой зоны

admin.example.org.

человек, отвечающий за эту зону, адрес электронной почты с подменённым символом @. ( становится admin.example.org)

5

последовательный номер файла. При каждом изменении файла зоны это число должно увеличиваться. В настоящее время для нумерации многие администраторы предпочитают формат ггггммддвв. 2001041002 будет означать, что файл последний раз изменялся 10.04.2001, а последнее число 02 означает, что это была вторая модификация файла за день. Последовательный номер важен, так как он служит для того, чтобы вторичные серверы узнавали об обновлении зоны.

    @       IN NS           ns1.example.org.

Это NS-запись. Такие записи должны иметься для всех серверов имён, которые будут отвечать за зону. Символ @, используемый здесь, преобразуется в example.org.. Этот символ @ соответствует ориджину.

    localhost       IN A    127.0.0.1
    ns1             IN A    3.2.1.2
    ns2             IN A    3.2.1.3
    mail            IN A    3.2.1.10
    @               IN A    3.2.1.30

Записи типа A служат для обозначения имён машин. Как это видно выше, имя ns1.example.org будет преобразовано в 3.2.1.2. И снова здесь используется символ ориджина @, обозначая, что example.org будет преобразовано в 3.2.1.30.

    www             IN CNAME        @

Записи с каноническими именами обычно используются для присвоения машинам псевдонимов. В этом примере www является псевдонимом для машины, соответствующей ориджину, то есть example.org (3.2.1.30). Записи CNAME могут использоваться для присвоения псевдонимов именам хостов или для использования одного имени несколькими машинами по очереди.

    @               IN MX   10      mail.example.org.

MX-запись указывает, какие почтовые серверы отвечают за обработку входящей электронной почты для зоны. mail.example.org является именем почтового сервера, а 10 обозначает приоритет этого почтового сервера.

Можно иметь несколько почтовых серверов с приоритетами 3, 2 и 1. Почтовый сервер, пытающийся доставить почту для example.org, сначала попробует связаться с машиной, имеющий MX-запись с самым большим приоритетом, затем с приоритетом поменьше и так далее, до тех пор, пока почта не будет отправлена.

Для файлов зон in-addr.arpa (обратные записи DNS) используется тот же самый формат, отличающийся только использованием записей PTR вместо A или CNAME.

    $TTL 3600
    
    1.2.3.in-addr.arpa. IN SOA ns1.example.org. admin.example.org. (
                            5               ; Serial
                            10800           ; Refresh
                            3600            ; Retry
                            604800          ; Expire
                            3600 )          ; Minimum
    
    @       IN NS   ns1.example.org.
    @       IN NS   ns2.example.org.
    
    2       IN PTR  ns1.example.org.
    3       IN PTR  ns2.example.org.
    10      IN PTR  mail.example.org.
    30      IN PTR  example.org.

В этом файле дается полное соответствие имён хостов IP-адресам в нашем описанном ранее вымышленном домене.

17.9.7. Кэширующий сервер имён

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

17.9.8. Запуск named в песочнице

Текст предоставилCeri Davies.

Для дополнительной безопасности вам может потребоваться запускать named(8) с правами непривилегированного пользователя и настроить его на выполнение chroot(8) в каталог-песочницу. Это позволит сделать недоступным для даемона named все, что расположено вне песочницы. Если named будет взломан, то это поможет уменьшить возможный ущерб. По умолчанию во FreeBSD имеются пользователь и группа с именами bind, которые предназначены именно для такого использования.

Note: Многие рекомендуют вместо настройки named на использование chroot, запускать named внутри jail(8). В этом разделе такой подход не рассматривается.

Так как named не сможет обратиться ни к чему вне песочницы (например, совместно используемым библиотекам, сокетам протоколов и так далее), то нужно выполнить несколько шагов, чтобы named смог работать нормально. В следующем списке предполагается, что каталогом песочницы является /etc/namedb и что вы не делали никаких изменений в содержимом этого каталога. Выполните следующие шаги, работая как пользователь root.

  • Создайте все каталоги, которые ожидает увидеть named:

        # cd /etc/namedb
        # mkdir -p bin dev etc var/tmp var/run master slave
        # chown bind:bind slave var/*(1)
    (1)
    Программе named нужен доступ с правом записи в эти каталоги, так что это все, что мы ей предоставим.
  • Измените и создайте базовые файлы зоны и настроек:

        # cp /etc/localtime etc(1)
        # mv named.conf etc && ln -sf etc/named.conf
        # mv named.root master
        # sh make-localhost && mv localhost.rev localhost-v6.rev master
        # cat > master/named.localhost
    $ORIGIN localhost.
    $TTL 6h
    @	IN	SOA	localhost. postmaster.localhost. (
    			1	; serial
    			3600	; refresh
    			1800	; retry
    			604800	; expiration
    			3600 )	; minimum
    	IN	NS	localhost.
    	IN	A		127.0.0.1
    ^D
    (1)
    Это позволит программе named протоколировать правильное время в syslogd(8)
  • Постройте статистически скомпонованную копию named-xfer и скопируйте ее в песочницу:

        # cd /usr/src/lib/libisc && make clean all
        # cd /usr/src/lib/libbind && make clean all
        # cd /usr/src/libexec/named-xfer && make NOSHARED=yes all
        # cp named-xfer /etc/namedb/bin && chmod 555 /etc/namedb/bin/named-xfer(1)
    (1)
    Иногда при выполнении этого шага возникают ошибки. Если это случилось, выполните такую команду:
        # cd /usr/src && make cleandir && make cleandir

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

  • Создайте файл устройства dev/null, который named может видеть и писать в него:

        # cd /etc/namedb/dev && mknod null c 2 2
        # chmod 666 null
  • Создайте символическую ссылку /var/run/ndc на /etc/namedb/var/run/ndc:

        # ln -sf /etc/namedb/var/run/ndc /var/run/ndc

    Note: Это просто для того, чтобы не задавать опцию -c при каждом запуске ndc(8). Так как содержимое каталога /var/run удаляется при загрузке, и если это показалось вам полезным, то вы можете добавить эту команду в cron-таблицу для root с использованием параметра @reboot. Обратитесь к справочной странице по crontab(5) для получения более полной информации относительно этого.

  • Настройте syslogd(8) на создание дополнительного протоколирующего сокета log, в который может писать named. Для этого добавьте -l /etc/namedb/dev/log к переменной syslogd_flags из файла /etc/rc.conf.

  • Задайте запуск named и выполнение chroot в песочницу, добавив следующее в /etc/rc.conf:

        named_enable="YES"
        named_flags="-u bind -g bind -t /etc/namedb /etc/named.conf"

    Note: Заметьте, что конфигурационный файл /etc/named.conf именуется по полному имени относительно песочницы, то есть в вышеприведённой строке указывается файл, который на самом деле является файлом /etc/namedb/etc/named.conf.

Следующим шагом является редактирование файла /etc/namedb/etc/named.conf так, чтобы named знал, какую зону загружать и где найти их на диске. Далее следует прокомментированный пример (все, что специально не прокомментировано, ничем не отличается от настройки сервера DNS, работающего не в песочнице):

    options {
            directory "/";(1)
            named-xfer "/bin/named-xfer";(2)
            version "";		// Не выдавайте версию BIND
            query-source address * port 53;
    };
    // управляющий сокет ndc
    controls {
            unix "/var/run/ndc" perm 0600 owner 0 group 0;
    };
    // Далее следуют зоны:
    zone "localhost" IN {
            type master;
            file "master/named.localhost";(3)
            allow-transfer { localhost; };
            notify no;
    };
    zone "0.0.127.in-addr.arpa" IN {
            type master;
            file "master/localhost.rev";
            allow-transfer { localhost; };
            notify no;
    };
    zone "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.int" {
           type master;
           file "master/localhost-v6.rev";
           allow-transfer { localhost; };
           notify no;
    };
    zone "." IN {
            type hint;
            file "master/named.root";
    };
    zone "private.example.net" in {
            type master;
            file "master/private.example.net.db";
    	allow-transfer { 192.168.10.0/24; };
    };
    zone "10.168.192.in-addr.arpa" in {
            type slave;
            masters { 192.168.10.2; };
            file "slave/192.168.10.db";(4)
    };
(1)
В директиве directory указан каталог /, так как все файлы, которые нужны для named, находятся внутри этого каталога (вспомните, что это равнозначно "обычному" пользовательскому /etc/namedb.
(2)
Задает полный путь к двоичному выполнимому файлу named-xfer (внутри границ видимости named). Это необходимо, так как named компилируется с тем, чтобы брать named-xfer по умолчанию из /usr/libexec.
(3)
Задает имя файла (относительно директивы directory выше), в котором named может найти файл зоны для этой зоны.
(4)
Задает имя файла (относительно директивы directory выше), в котором named должен записывать копию файла зоны для этой зоны после успешной передачи ее с основного сервера. Вот почему нам нужно изменить владельца каталога slave на bind на этапах настроек выше.

После выполнения шагов выше либо перезагрузите ваш сервер, либо перезапустите syslogd(8) и запустите named(8), не забыв использовать новые опции, заданные в syslogd_flags и named_flags. Теперь named должен заработать в песочнице!

17.9.9. Безопасность

Хотя BIND является самой распространенной реализацией DNS, всегда стоит вопрос об обеспечении безопасности. Время от времени обнаруживаются возможные и реальные бреши в безопасности.

Весьма полезно подписаться на списки рассылки CERT и freebsd-security-notifications для того, чтобы быть в курсе текущих проблем с обеспечением безопасности Internet и FreeBSD.

Tip: Если возникают проблемы, то наличие последних исходных текстов и свежеоткомпилированного named не помешает.