«Протокол Beanstalk» и «DNS сервер BIND с локальными зонами»: разница между страницами

Материал из support.qbpro.ru
(Различия между страницами)
imported>Supportadmin
 
imported>Vix
Нет описания правки
 
Строка 1: Строка 1:
Это перевод официального протокола [https://raw.githubusercontent.com/kr/beanstalkd/master/doc/protocol.txt Beanstalk] [[Beanstalk_Protocol|Резервная копия]]
Исходные данные


переводчик Андрей Климов.
Для корректной работы DNS нем необходимо иметь настроенную сеть. DNS в текущей статье будет настроен на дистрибутиве Debian, особенности других дистрибутивов тоже будут отмечены. Конфиг сети стенда следующий:


08-05-2014
dns:~# cat /etc/network/interfaces
==Протокол==
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
  address 10.0.0.152
  netmask 255.255.255.0
  gateway 10.0.0.254
auto eth1
iface eth1 inet static
  address 192.168.1.1
  netmask 255.255.255.0
где 10.0.0.152/24 - внешний интерфейс (подсеть, выделенная провайдером), 192.168.1.1/24 - внутренний (Локальная сеть). Настраиваемая зона будет иметь имя example.com. В примере со slave сервером, вторичный сервер будет расположен на IP 10.0.0.191.


Протокол  beanstalk работает поверх  TCP используя кодировку ASCII. Клиенты могут устанавливать соединение, посылать команды и данные, а так же закрывать соединение. Для каждого соединения, сервер обрабатывает команды последовательно в порядке, в котором они были получены и посылает ответы в том же порядке. Все целые числа в протоколе отформатированы в десятичной форме и (если не указано иное) неотрицательны.
Установка BIND9


Названия в протоколе — строки в кодировке  ASCII. Они могут содержать буквы (A-Z и a-z), цифры (0-9), знаки "-", "+", "/", ";", ".", "$", "_" и скобки "(" и ")", но не могут начинаться со знака "-". Названия разделяются символом пробел или символом конец строки.  Каждое название должно быть длинной не менее одного символа.
Для работы DNS сервера необходимо установить пакет bind9 (в некоторых дистрибутивах - bind). Как отмечено на схеме - основным конфигурационным файлом BIND является файл named.conf (данный файл может быть размещен в каталоге /etc, иногда в /etc/bind ).


Протокол содержит два вида данных: текстовые строки и неструктурированные куски данных. Текстовые строки используются для клиентских команд и ответов сервера. Части данных используются для передачи «тела» задачи и статистики. Каждое «тело» задачи является неразделенной последовательностью байтов. Сервер никогда не проверяет или изменяет «тело» задачи и всегда отправляет его обратно в его первоначальном виде. Это зависит только от клиентов, чтобы договориться о содержательной интерпретации «тел» задач.
Параметры (синтаксис) named.conf


Клиент может использовать команду «quit» или просто закрыть  TCP соединение когда он больше не будет использовать сервер. Тем не менее, beanstalkd очень хорошо работает с большим количеством открытых соединений, поэтому обычно лучше для клиента, чтобы тот сохранил своё соединение открытым и использовал его как можно дольше. Это позволяет избежать расходов, связанных на установление новых сессий TCP.
Синтаксис файла named.conf придерживается следующих правил:


Если клиент нарушает протокол (например, отправив не очень хорошо сформированный запрос или несуществующую команду) или в сервере произошла ошибка, сервер ответит одним из следующих сообщений об ошибке:
IP-адреса - список IP должен быть разделен символом ";" , возможно указывать подсеть в формате 192.168.1.1/24 или 192.168.1.1/255.255.255.0, (для исключения IP перед ним нужно поставить знак !), возможно указывать имена "any", "none", "localhost" в двойных кавычках.


*'''OUT_OF_MEMORY\r\n''' - Сервер не может выделить память для задачи. Клиенту нужно попробовать еще раз позже.
Комментарии - строки начинающиеся на #, // и заключенные в /* и */ считаются комментариями.
*'''INTERNAL_ERROR\r\n''' - Эта ошибка сигнализирует о критической ошибке сервера. Такого не должно случиться никогда. Если такое произойдет, пожалуйста сообщите по адресу http://groups.google.com/group/beanstalk-talk.
*'''BAD_FORMAT\r\n''' - Клиент послал неверно сформированную команду. Это может случится в случаях, если команда не заканчивается символом \r\n,  если в позиции где ожидаются целое число, а  находится иное, если неправильное количество аргументов или если командная строка неправильно формируется любым другим способом.
*'''UNKNOWN_COMMAND\r\n''' - Клиент послал неизвестную для сервера команду


Эти ошибки не будут описаны в каждой команде индивидуально, но они неявно включены в описание всех команд. Клиенты должны быть готовы получать в ответ ошибку после любой команды.
В файлах описания зон - символ @ является "переменной" хранящей имя зоны, указанной в конфигурационном файле named.conf или в директиве @ $ORIGIN текущего описания зоны.


В крайнем случае, если в сервере случилась критическая ошибка, которая приводит к прекращению обслуживания текущего клиента, сервер закроет соединение.
Каждая завершенная строка параметров должна завершаться символом ; .
(Прим переводчика. Далее по тексту клиенты, которые создают (генерируют) задачу будут называться генераторами задач, клиенты которые исполняют задачу, исполнителями задач).


==Жизненный цикл задачи==
Раздел Acl
Acl (access control list) - позволяет задать именованный список сетей. Формат раздела: acl "имя_сети" {ip; ip; ip; };


Задачи в beanstalk создаются клиентами командой «'''put'''». На протяжении своей «жизни», задача может находится в одном из четырех состояний: «'''ready'''», «'''reserved'''», «'''delayed'''», или «'''buried'''». После создания командой «'''put'''», задача обычно переходит в состояние '''ready'''. Она ожидает в очереди '''ready''' до тех пор, пока не подключиться исполнитель и не даст команду «'''reserve'''» (прим переводчика: исполнитель может быть уже подключенным и просто дать команду «'''reserve'''» — зарезервировать за собой следующую в очереди задачу, находящуюся в состояние ready, как выполняемую. Можно перефразировать - зарезервировать следующую задачу в очереди '''ready'''. Состояние и очередь в данном случае одно и тоже). Если есть такая задача следующая в очереди, то она будет зарезервирована за исполнителем. Исполнитель выполняет задачу, после чего исполнитель посылает команду «'''delete'''», для её удаления.
Раздел Options
Раздел Options задает глобальные параметры конфигурационного файла, управляющие всеми зонами. Данный раздел имеет формат: options {операторы_раздела_Options};. Options может быть "вложен" в раздел Zone, при этом он переопределяет глобальные параметры. Часто используемые операторы options:


allow-query {список_ip} - Разрешает ответы на запросы только из список_ip. При отсутствии - сервер отвечает на все запросы.
allow-recursion {список_ip} - На запросы из список_ip будут выполняться рекурсивные запросы. Для остальных - итеративные. Если  не задан параметр, то сервер выполняет рекурсивные запросы для всех сетей.
allow-transfer {список_ip} - Указывает список серверов, которым разрешено брать зону с сервера (в основном тут указывают slave сервера)
directory /path/to/work/dir - указывает абсолютный путь к рабочему каталогу сервера. Этот оператор допустим только в разделе  options.
forwarders {ip порт, ip порт...} - указывает адреса хостов и если нужно порты, куда переадресовывать запросы (обычно тут указываются DNS провайдеров ISP).
forward ONLY или forward FIRST - параметр first указывает, DNS-серверу пытаться разрешать имена с помощью DNS-серверов, указанных в параметре forwarders, и лишь в случае, если разрешить имя с помощью данных серверов не удалось, то будет осуществлять попытки разрешения имени самостоятельно.
notify YES|NO - YES - уведомлять slave сервера об изменениях в зоне, NO - не уведомлять.
recursion YES|NO - YES - выполнять рекурсивные запросы, если просит клиент, NO - не выполнять (только итеративные запросы). Если ответ найден в кэше, то возвращается из кэша. (может использоваться только в разделе Options)
Раздел Zone
Определяет описание зон(ы). Формат раздела: zone {операторы_раздела_zone}; Операторы, которые наиболее часто используются:


На схеме типовой жизненный цикл задачи:
allow-update {список_ip} - указывает системы, которым разрешено динамически обновлять данную зону.
file "имя_файла" - указывает путь файла параметров зоны (должен быть расположен в каталоге, определенном в разделе options оператором directory)
masters {список_ip} -указывает список мастер-серверов. (допустим только в подчиненных зонах)
type "тип_зоны" - указывает тип зоны, описываемой в текущем разделе,тип_зоны может принимать следующие значения:
forward - указывает зону переадресации, которая переадресовывает запросы, пришедшие в эту зону.
hint - указывает вспомогательную зону (данный тип содержит информацию о корневых серверах, к которым сервер будет обращаться в случае невозможности найти ответ в кэше)
master - указывает работать в качестве мастер сервера для текущей зоны.
slave - указывает работать в качестве подчиненного сервера для текущей зоны.
Дополнительные параметры конфигурации
Значения времени в файлах зон по умолчанию указывается в секундах, если за ними не стоит одна из следующих букв: S - секунды, M - минуты, H- часы, D - дни, W - недели. Соответственно, запись 2h20m5s будет иметь значение 2 часа 20 минут 5 секунд и соответствовать 8405 секунд.


    put            reserve              delete
Любое имя хоста/записи, не оканчивающиеся точкой считается неFQDN именем и будет дополнено именем текущей зоны. Например, запись domen в файле зоны examle.com будет развернуто в FQDN-имя domen.examle.com. .
  -----> [READY] ---------> [RESERVED] --------> *poof*


На этой схеме приведены все возможные варианты:
В конфигурационных файлах BIND могут применяться следующие директивы:


    put with delay              release with delay
$TTL - определяет TTL по-умолчанию для всех записей в текущей зоне.
  ----------------> [DELAYED] <------------.
$ORIGIN - изменяет имя зоны с указанного в файле named.conf. При этом, область действия данной директивы не распространяется  "выше" (то есть если файл включен директивой $INCLUDE, то область действия$ORIGN не распространяется на родительский)
                        |                  |
  $INCLUDE - включает указанный файл как часть файла зоны.
                        | (time passes)     |
Для того чтобы локальный резолвер сервера тоже использовал локальный DNS, необходимо привести файл resolv.conf к следующему виду:
                        |                  |
    put                  v    reserve      |      delete
  -----------------> [READY] ---------> [RESERVED] --------> *poof*
                        ^  ^                | |
                        |  \  release      |  |
                        |    `-------------'  |
                        |                      |
                        | kick                |
                        |                      |
                        |      bury          |
                    [BURIED] <---------------'
                        |
                        |  delete
                        `--------> *poof*


dns:~# cat /etc/resolv.conf
nameserver 127.0.0.1
Если в имени ресурсной записи встречается символ "*", то это он означает что вместо него можно подразумевать любую разрешенную последовательность символов. Такую запись называют "wildcard запись". Однако, символ "*" не может быть использован где угодно. Это может быть только первый символ в поле Name текущего домена, отделенный от остальных символом "."


Система имеет один или более каналов. Каждый канал состоит из очередей '''ready''' и '''delay'''. Каждое задание проводит всю свою «жизнь» в одном канале. Клиенты могут подписаться на канал, отправив команду «'''watch'''»; они могут отписаться от канала, отправив команду «'''ignore'''». Этот набор каналов, на которых осуществлена подписка, является как говорят, «'''watch list'''» клиента. Когда клиент посылает команду «'''reserve'''», задача может поступить из любого канала в «'''watch list'''».
Настройка кэширующего DNS сервера


После установки bind, он полностью готов работать как кэширующий DNS сервер без дополнительной настройки. Единственный недостаток - он обрабатывает запросы на всех интерфейсах, что нам абсолютно не нужно, поэтому мы немного подредактируем настройки сервера.


Когда клиент подключается, его «'''watch list'''» он изначально подписан только на канал «'''default'''». Если он посылает команду «'''reserve'''» без предварительного использования команды «'''use'''», то все его задачи будут находится только в канале «'''default'''».
Для того, чтобы BIND работал в качестве кэширующего сервера, необходимо иметь конфигурационные файлы заполненные необходимой информацией:


named.conf;
описание серверов корневой зоны (зона типа hint);
описание зоны 127.in-addr.arpa.
dns:~# cat /etc/bind/named.conf
acl "lan" {
            192.168.1.1/24;
            127.0.0.1;
};
options {
            directory "/var/cache/bind";
          // If there is a firewall between you and nameservers you want
          // to talk to, you may need to fix the firewall to allow multiple
          // ports to talk.  See http://www.kb.cert.org/vuls/id/800113
          /*
          * Тут сказано, что если используется фаерволл, то необходимо
          *  нашему серверу создать соответствующие правила
          *  то есть открыть доступ по 53 TCP и UDP порту
          */
          forward first;              // задаем пересылку только первого запроса
          forwarders {                // указываем DNS сервера для пересылки
                      83.239.0.202;    // предоставленные провайдером
                      213.132.67.110;  // ибо до них ближе чем до корневых
          };
          listen-on { lan; };        // пусть слушает только нужные интерфейсы
          allow-query { lan; };      // разрешить запросы только из локальной сети
          allow-recursion { lan; };  // рекурсивные запросы тоже только из локальной
          allow-transfer { none; };  // трансфер зон нам не нужен
          version "unknown";        // не отображать версию DNS сервера при ответах
          auth-nxdomain no;    # для совместимости RFC1035
          listen-on-v6 { none; };    //IPv6 нам не нужен
          };
// описание настроек корневых серверов
zone "." {
          type hint;
          file "db.root";
};
// нижеописанные зоны определяют сервер авторитетным для петлевых
// интерфейсов, а так же для броадкаст-зон (согласно RFC 1912)
zone "localhost" {
          type master;
          file "localhost";
};
zone "127.in-addr.arpa" {
          type master;
          file "127.in-addr.arpa";
};
zone "0.in-addr.arpa" {
          type master;
          file "0.in-addr.arpa";
};
zone "255.in-addr.arpa" {
          type master;
          file "255.in-addr.arpa";
};


Каналы создаются по запросу, всякий раз когда на них ссылаются. Если канал пуст (это означает, что он не содержит задач со статусом «'''ready'''», «'''delayed'''» или «'''buried'''») и нет подписанных клиентов, канал будет удален.
В данном примере приведен кэширующий DNS сервер, обрабатывающий запросы из списка сетей lan, в которую входит только одна локальная сеть 192.168.1.1/24 и петлевой интерфейс. При необходимости можно включить туда и другие сети. После определения списка сетей в директиве acl, в любом месте конфига можно будет ссылаться на этот список по имени (в нашем примере имя - lan), что, собственно и сделано в разделе options. Большинство параметров я прокомментировал, но отдельного внимания требует раздел, описывающий зону корневых серверов. В параметре file задан относительный путь к файлу описания корневых серверов (путь, относительно рабочего каталога сервера). За обновлениями данного файла необходимо следить, хотя он обновляется довольно редко (откуда брать обновленный файл я писал в теории DNS). Как вы заметили, имеется так же две записи для зоны localhost и две записи обратных зон для бродкаст доменов. Назначение этих зон состоит в том, чтобы избежать трансляции случайных запросов имен соответствующих IP-адресов на серверы, обслуживающие корневую зону.


==Команды генераторов задач==
Чтобы не вносить неразбериху в куче конфигурационных файлов, в статье я привожу примеры на основе единого конфигурационного файла. На  самом деле, в последних версиях Debian (и других дистрибутивах Linux), файл named.conf выглядит следующим образом:
===put===
Команда «'''put'''» предназначена для любого клиента, который желает добавить задачу в очередь. Она включает в себя строку команды с последующей строкой «тела» задачи:


'''put <pri> <delay> <ttr> <bytes>\r\n'''
root@master:~# cat /etc/bind/named.conf
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local


'''<dаta>\r\n'''
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
То есть основной файл не содержит конфигураций, а включает в себя более узко специализированные файлы, которые отвечают за свои задачи, например named.conf.options - содержит глобальные параметры конфигурации, named.conf.default-zones - содержит описание localhost и broadcast зон, а named.conf.local содержит описания зон, за которые отвечает данный сервер.


Добавляет задачу в используемый клиентом в настоящее время канал (см. ниже команду «'''use'''»).


*'''<pri>''' приоритет - целое число < 2**32. Задачи с меньшим значением приоритета будут выполнены раньше задач с большим значение приоритета. Самая важная задача будет иметь приоритет 0; самая неважная задача будет иметь приоритет 4,294,967,295.
Далее, хочу обратить внимание на наличие файлов зон в каталоге, указанном в разделе options в параметре directory с именами, соответствующими параметрам file в разделах, описывающих зоны:
*'''<delay>''' отсрочка — целое число секунд ожидания до постановки задачи в очередь «ready». Все это время задача будет иметь статус «'''delayed'''».
*'''<ttr>''' время выполнения — целое число секунд, которые отводятся исполнителю на выполнение этой задачи. Это время отсчитывается с момента начала выполнения команды «'''reserve'''» для этой задачи. Если исполнитель не даст команду «delete», «release» или «bury» для этой задачи через <ttr> секунд, будет превышено время выполнения и сервер выполнит команду «'''release'''» для этой задачи. Минимальное значение 1. Если клиент устанавливает значение <ttr> равным 0, сервер без предупреждения увеличит его до 1.
*'''<bytes>''' размер тела задачи — целое число указывающее размер тела задачи, не включая граничные символы "\r\n". Это значение должно быть меньше чем max-job-size (по умолчанию: 2**16).
*'''<dаta> '''тело задачи — последовательность байтов длиной '''<bytes> '''указанной в строке команды.


После отправки строки команды и тела задачи, клиент должен ожидать один из возможных ответов:
dns:~# ls -l /var/cache/bind/
*'''INSERTED <id>\r\n''' - указывает на успешное добавление задачи.
итого 24
**<id> - целое число, идентификатор новой задачи
-rw-r--r-- 1 root root  237 Май 28 01:28 0.in-addr.arpa
*'''BURIED <id>\r\n''' - указывает на то, что серверу не хватило памяти при попытке разобрать структуру данных очереди приоритетов.
-rw-r--r-- 1 root root  271 Май 28 01:28 127.in-addr.arpa
**<id> - целое число, идентификатор новой задачи
-rw-r--r-- 1 root root  237 Май 28 01:28 255.in-addr.arpa
*'''EXPECTED_CRLF\r\n''' - тело задачи должно оканчиваться парой символов CR-LF, а именно, "\r\n". Эти два байта не учитываются в при расчете длины тела задачи в строке команды put.
-rw-r--r-- 1 root root 2994 Май 28 01:28 db.root
*'''JOB_TOO_BIG\r\n''' - клиент передает тело задачи больше чем max-job-size байт
-rw-r--r-- 1 root root  270 Май 28 01:28 localhost
*'''DRAINING\r\n''' - означает, что сервер находится в режиме "drain mode" и больше не принимает новые задачи. Клиент должен попробовать подключиться к другому серверу или повторить подключение позже.
dns:~# cat /var/cache/bind/127.in-addr.arpa
;
; BIND reverse data file for local loopback interface
;
$TTL    604800
@      IN      SOA    localhost. root.localhost. (
                              1        ; Serial
                              604800    ; Refresh
                              86400    ; Retry
                              2419200  ; Expire
                              604800 )  ; Negative Cache TTL
;
@      IN      NS      localhost.
1.0.0  IN      PTR    localhost.
Рассматривать файлы "петлевых" и бродкастовых зон не вижу смысла, т.к. после установки пакета bind настройки заданные по умолчанию в данных файлах вполне приемлемы. Далее, при организации мастер сервера мы рассмотрим пример описания файла зоны. Хочу обратить внимание, что мы настраиваем кэширующий сервер, а определяем мы его и как master для некоторых из зон. В нашем случае "кэширующий" говорит о том, что наш сервер не поддерживает ни одну из реально существующих зон, т.е. ему не делегировано прав на такое обслуживание.


===use===
Да, чуть не забыл, демон named должен быть разрешен для запуска на необходимых уровнях выполнения ОС (команда в RedHat - /sbin/chkconfig bind9 on, в Debian - /usr/sbin/update-rc.d bind9 defaults). После изменения конфигурационных файлов можно добавить сервис в автозагрузку и запустить демон:


Команда «'''use'''» предназначена только для генераторов команд. Последующие команды «'''put'''» добавят задачу в канал, предусмотренный настоящей командой. Если не был дана команда «'''use'''», задачи будут добавлены в канал под названием «'''default'''».
dns:~# update-rc.d bind9 defaults
Adding system startup for /etc/init.d/bind9 ...
/etc/rc0.d/K20bind9 -> ../init.d/bind9
/etc/rc1.d/K20bind9 -> ../init.d/bind9
/etc/rc6.d/K20bind9 -> ../init.d/bind9
/etc/rc2.d/S20bind9 -> ../init.d/bind9
/etc/rc3.d/S20bind9 -> ../init.d/bind9
/etc/rc4.d/S20bind9 -> ../init.d/bind9
/etc/rc5.d/S20bind9 -> ../init.d/bind9
dns:~# /etc/init.d/bind9 start
Starting domain name service...: bind9.
На этом настройка кэширующего DNS завершена. Все запросы, которые попадают в кэш DNS сервера он хранит в оперативной памяти компьютера и при перезапуске демона эти данные обнуляются. Для проверки работы кэша можно выполнить команду nslookup mail.ru example.com., если в ответе содержится строка Non-authoritative answer, то адрес пришел из кэша, а так же если выполнить dig www.ru. (или другой домен, которого еще нет в кэше) и через некоторое время повторить команду, то время ответа должно быть гораздо меньше.


'''use <tube>\r\n'''
Давайте рассмотрим другие варианты сервера.


*'''<tube>''' - название канала, длиной не более 200 байт. Указывает какой канал станет текущим для использования. Если такого канала нет, то он будет создан.
Главный (master) сервер зоны


Возможен только один вариант ответа:
Основной конфиг содержит следующие настройки:
*'''USING <tube>\r\n '''- указывает имя используемого канала
**<tube> - Имя канала, который стал текущим


==Команды исполнителей задач==
dns:~# cat /etc/bind/named.conf
acl "lan" {
          192.168.1.1/24;
          127.0.0.1;
};


Клиент, который хочет получить задачу из очереди должен использовать команды «'''reserve'''», «'''delete'''», «'''release'''» и «'''bury'''» (прим переводчика: если точнее, то это набор команд исполнителя для работы с очередью в канале).
options {
          directory "/var/cache/bind";
          allow-query { any; };      // отвечать на зпросы со всех интерфейсов
          recursion no;              // запретить рекурсивные запросы
          auth-nxdomain no;          // для совместимости RFC1035
          listen-on-v6 { none; };    // IPv6 нам не нужен
          version "unknown";          // не отображать версию DNS сервера при ответах


===reserve, reserve-with-timeout===
          /*
          *  Раскомментируйте строки ниже, если
          *  хотите разрешить рекрусивные запросы
          *  из локальной сети.
          *  (так же, необходимо закомментировать
          *  recursion no; )
          */
          # forwarders {                // указываем DNS сервера для пересылки
          #        83.239.0.202;        // предоставленные провайдером
          #        213.132.67.110;      // ибо до них ближе чем до корневых
          # };


Первая команда исполнителя «'''reserve'''», выглядит так:
          # allow-recursion { lan; };    // рекурсивные запросы тоже только из локальной


'''reserve\r\n'''
};


Альтернативно можно указать тайм-аут следующим образом:
// описание настроек корневых серверов
zone "." {
          type hint;
          file "db.root";
};


'''reserve-with-timeout <seconds>\r\n'''
// нижеописанные зоны определяют сервер авторитетным для петлевых
// интерфейсов, а так же для броадкаст-зон (согласно RFC 1912)


Команды вернут вновь зарезервированную задачу. Если не будет доступных для резервирования задач, beanstalkd будет ожидать возможности послать ответ, до тех пор пока это не станет возможным. После того, как задача будет зарезервирована за для клиента, у клиента есть строго ограниченное время (TTR) для выполнения задачи. При наступлении тайм-аута задачи, сервер будет поставить работу обратно в очередь готовности. И TTR и фактическое время выполнения можно найти в статистике по команде '''stats-job'''.
zone "localhost" {
          type master;
          file "localhost";
};


Если более одной задачи имеют статус ready, beanstalkd выберет одну из них с наименьшим значением приоритета. В рамках одного приоритета, будет выбрана та задача, которая была получена первой.
zone "127.in-addr.arpa" {
          type master;
          file "127.in-addr.arpa";
};


Тайм-аут со значением 0 заставит сервер немедленно возвращать либо ответ или '''TIMED_OUT '''. Положительное значение тайм-аута будет задавать время, в течении которого запросы «'''reserve'''» будет блокированы пока задача снова не станет доступной.
zone "0.in-addr.arpa" {
          type master;
          file "0.in-addr.arpa";
};


Всё время TTR зарезервированной задачи, вплоть до последней секунды сервер будет находится в безопасном режиме, при котором исполнитель гарантированно не может получить другую задачу. Если исполнитель дает команду «'''reserve'''» во время безопасного режима или безопасный режим наступает пока исполнитель ожидает ответ на команду «'''reserve'''», сервер может ответить следующим образом:
zone "255.in-addr.arpa" {
          type master;
          file "255.in-addr.arpa";
};


*'''DEADLINE_SOON\r\n''' - дает исполнителю шанс дать команду «'''delete'''» или «'''release'''» для зарезервированной задачи, до того как сервер автоматически даст команду «'''release'''» для зарезервированной задачи.
// описание основной зоны
*'''TIMED_OUT\r\n''' - если был указан неотрицательный тайм-аут и тайм-аут превышен до момента, когда задача стала доступна, или если соединение клиента является полузакрытыми, сервер ответит TIMED_OUT
zone "example.com" {
          type master;
          file "example.com";
          allow-transfer { 10.0.0.191; };
};


В противном случае, единственным ответом на эту команду является успешное резервирование задачи в виде текстовой строки, затем тела задачи:
//описание обратных зон
zone "0.0.10.in-addr.arpa" {
          type master;
          file "0.0.10.in-addr.arpa";
          allow-transfer { 10.0.0.191; };
};


*'''RESERVED <id><bytes>\r\n''' - успешное резервирование задачи
zone "1.168.192.in-addr.arpa" {
**'''<id>''' - имя канала, который стал текущим
          type master;
**'''<bytes>''' - целое число указывающее размер тела задачи, не включая граничные символы "\r\n".
          file "1.168.192.in-addr.arpa";
*'''<dаta>\r\n''' - тело успешно зарезервированной задачи — последовательность байтов длиной <bytes> указанной в строке команды. Это точная копия байтов, которые были изначально отправлены на сервер командой «'''put'''» в этой задаче.
#        allow-transfer { 10.0.0.191; };  // зона описывает локальную сеть поэтому ее не передаем
};


===delete===
// настройки логирования
logging {
          channel "misc" {
                    file "/var/log/bind/misc.log" versions 4 size 4m;
                    print-time yes;
                    print-severity yes;
                    print-category yes;
          };


Команда «'''delete'''» удаляет задачу с сервера целиком. Эта команда, как правило, используется клиентом, когда задача успешно выполнена. Исполнитель может удалять задания, которые он зарезервировал, а так же задачи со статусом «'''ready'''», «'''delayed'''» или «'''buried'''». Команда «'''delete'''» выглядит следующим образом:
          channel "query" {
                    file "/var/log/bind/query.log" versions 4 size 4m;
                    print-time yes;
                    print-severity no;
                    print-category no;
          };


'''delete <id>\r\n'''
          category default {
                    "misc";
          };


*'''<id>''' - идентификатор задачи, которую следует удалить.
          category queries {
                    "query";
          };
};
Давайте кратко разберем конфигурационный файл и настройки master сервера: мы настраиваем мастер сервер для зоны example.com. . Согласно конфига, наш BIND имеет рабочий каталог /var/cache/bind, сервер отвечает на запросы со всех интерфейсов (allow-query {any ;};), рекурсивные запросы обрабатывает как итеративные (recursion no), является мастер-сервером для зоны example.com и локальных служебных зон (type master). При этом, если необходимо разрешить кэширование (то есть рекурсивные запросы) для локальной сети, то необходимо раскомментировать параметры forwarders и allow-recursion и закомментировать recursion no;.


Исполнитель должен ожидать один из возможных вариантов ответа:
Так же, для примера, я привел возможности BIND логировать все происходящее при работе сервера (можно для этой цели использовать syslog). В разделе logging задаются 2 параметра channel (можно и больше двух - на ваше усмотрение), эти параметры дословно можно назвать "канал" записи. Каждый канал определяет имя канала и настройки параметров записи (что записывать, а что - нет и куда писать). Директива category задает какую категорию сообщений в какой канал отправлять. Исходя из этого, мы имеем: запись стандартной информации в канал misc, а приходящие запросы посылаются в канал query. При этом, если файлы журнала достигают 4Мб (size 4m), он переименовывается добавлением к имени .1 и начинается запись в новый журнал, числа в конце других журналов увеличиваются. Журналы с номером, более указанного в version (в нашем случае 4) удаляются (Управлять ротацией логов можно так же с помощью logrotate). Параметры print* определяют заносить ли в журнал время появления, важность и категорию информации. Более подробно про настройки раздела logging можно почитать в man (5) named.conf.


*'''DELETED\r\n - '''сигнализирует об успешности операции
Отдельно хочется описать параметр  allow-transfer { 10.0.0.191; };. Данный параметр описывает серверы, которым разрешено скачивать копию зоны - т.н. slave серверА. В следующем примере мы разберем настройку slave DNS.
*'''NOT_FOUND\r\n''' - если задача не существует, или была зарезервирована не этим исполнителем, была переведена в статус '''ready''' или '''buried''' (прим переводчика: неоднозначный, возможно неправильный перевод). Эта ситуация возможна в случае, когда тайм-аут для задачи наступил раньше, чем клиент дал команду «'''delete'''»


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


Команда «'''release'''» помещает зарезервированную задачу назад в очередь ready (и помечает её статус как «'''ready'''») для запуска любым исполнителем. Обычно это используется, когда выполнить задачу не удается из-за возникшей ошибки.  
dns:~# mkdir /var/log/bind/
dns:~# chmod 744 /var/log/bind/
dns:~# ps aux | grep named
bind      4298  0.0  3.4  46792 13272 ?        Ssl  Jul05  0:00 /usr/sbin/named -u bind
root      4815  0.0  0.1  3304  772 pts/4    S+  18:19  0:00 grep named
dns:~# chown bind /var/log/bind/
dns:~# ls -ld /var/log/bind/
drwxr--r-- 2 bind root 4096 Июл  6 18:18 /var/log/bind/
Давайте далее рассмотрим наш файл описания зоны example.com.:


Формат команды:  
dns:~# cat /var/cache/bind/example.com
$TTL 3D
@      IN      SOA    ns.example.com. root.example.com. (
                                        2011070601      ; serial
                                        8H              ; refresh
                                        2H              ; retry
                                        2W              ; expire
                                        1D)            ; minimum


'''release <id> <pri> <delay>\r\n'''
@      IN      NS      ns.example.com.
@      IN      NS      ns2.example.com.
@      IN      A      10.0.0.152
@      IN      MX      5 mx.example.com.
ns      IN      A      10.0.0.152
ns2    IN      A      10.0.0.191
mx      IN      A      10.0.0.152
www    IN      CNAME  @
а так же в домене in-addr.arpa.


* '''<id>''' идентификатор задачи, которую следует «реализовать».
dns:~# cat /var/cache/bind/0.0.10.in-addr.arpa
* '''<pri>''' новый приоритет для задачи.
$TTL 3600
* '''<delay>''' целое число секунд ожилания, до того как задача переместится в очередь ready. В течение этой задержки задача будет иметь статус «'''delayed'''».
@      IN      SOA    ns.examle.com.  root.example.com. (
            2007042001 ; Serial
            3600      ; Refresh
            900        ; Retry
            3600000    ; Expire
            3600 )    ; Minimum
        IN      NS      ns.examle.com.
        IN      NS      ns2.example.com.
152    IN      PTR    examle.com.
191    IN      PTR    ns.example.com.
*       IN      PTR    examle.com.


Исполнитель должен ожидать один из возможных вариантов ответа:
dns:~# cat /var/cache/bind/1.168.192.in-addr.arpa
$TTL 3600
@      IN      SOA    ns.examle.com.  root.example.com. (
            2007042001 ; Serial
            3600      ; Refresh
            900        ; Retry
            3600000    ; Expire
            3600 )    ; Minimum
        IN      NS      ns.examle.com.
        IN      NS      ns2.example.com.
*      IN      PTR    examle.com.
Наша сеть небольшая, предполагается, что в сети совсем мало машин. Все сервисы сети размещены на одном хосте example.com., поэтому и master DNS (ns.example.com.) и почтовый сервер (mx.example.com.) указывает на одну машину (10.0.0.152).


*'''RELEASED\r\n''' - сигнализирует об успешности операции
Вторичный (secondary, slave) авторитетный сервер зоны
*'''BURIED\r\n''' - указывает на то, что серверу не хватило памяти при попытке разобрать структуру данных очереди приоритетов.
*'''NOT_FOUND\r\n''' - если задача не существует или была зарезервирована не этим исполнителем


===bury===
Основная функция slave сервера - автоматическая синхронизация описания зоны с master сервером. Данная задача регламентируется документом RFC 1034 в разделе 4.3.5. Согласно данному документу обмен данными между серверами рекомендовано производить по протоколу TCP, посредством запроса AXFR. По этому запросу за одно TCP соединение должна передаваться вся зона целиком (RFC 1035).


Команда «'''bury'''» переводит задачу в статус «'''buried'''». Такие задачи помещаются в FIFO подобный список и не обрабатываются сервером до тех пор, пока исполнитель не даст команду «'''kick»'''.
Так же, slave DNS-сервер делит нагрузку с master сервером или принимает на себя всю нагрузку в случае аварии па первом сервере.


Формат команды:
Прежде чем приступить к настройке slave DNS сервера, необходимо проверить возможность получения зоны вручную со вторичного сервера с помощью следующей команды:


'''bury <id> <pri>\r\n'''
root@debian:~# dig @10.0.0.152 example.com. axfr


* '''<id>''' идентификатор задачи, которую следует «заморозить» (прим переводчика: в оригинальном тексте про команду release).
; <<>> DiG 9.7.3 <<>> @10.0.0.152 example.com. axfr
* '''<pri>''' новый приоритет, назначенный задаче.
; (1 server found)
;; global options: +cmd
example.com.            259200  IN      SOA    ns.example.com. root.example.com. 2011070801 28800 7200 1209600 86400
example.com.            259200  IN      NS      ns.example.com.
example.com.            259200  IN      NS      ns2.example.com.
example.com.            259200  IN      A      10.0.0.152
example.com.            259200  IN      MX      5 mx.example.com.
mx.example.com.        259200  IN      A      10.0.0.152
ns.example.com.        259200  IN      A      10.0.0.152
ns2.example.com.        259200  IN      A      10.0.0.191
www.example.com.        259200  IN      CNAME  example.com.
example.com.            259200  IN      SOA    ns.example.com. root.example.com. 2011070801 28800 7200 1209600 86400
;; Query time: 14 msec
;; SERVER: 10.0.0.152#53(10.0.0.152)
;; WHEN: Fri Jul  8 15:33:54 2011
;; XFR size: 11 records (messages 1, bytes 258)
Получение зоны прошло успешно. Далее, для настройки подчиненного сервера, алгоритм следующий:


Возможны два варианта ответа:
Скопировать конфигурационный файл named.conf с master сервера;
Заменить параметр type master на type slave в тех зонах, для которых он будет вторичным;
Параметр  allow-transfer { 10.0.0.191; }; заменить на masters { 10.0.0.152;}; в тех зонах, для которых он будет вторичным;
Удалить зоны, которые не будет обслуживать текущий сервер, в том числе и корневую, если slave не будет отвечать на рекурсивные запросы;
Создать каталоги для логов, как в предыдущем примере.
Итого, мы получаем конфиг slave сервера:


*'''BURIED\r\n''' - сигнализирует об успешности операции
root@debian:~# cat /etc/bind/named.conf
*'''NOT_FOUND\r\n''' - если задача не существует или была зарезервирована не этим исполнителем
options {
          directory "/var/cache/bind";
          allow-query { any; };      // отвечать на запросы со всех интерфейсов
          recursion no;              // запретить рекурсивные запросы
          auth-nxdomain no;          // для совместимости RFC1035
          listen-on-v6 { none; };    // IPv6 нам не нужен
          version "unknown";        // не отображать версию DNS сервера при ответах
};


===touch===
// нижеописанные зоны определяют сервер авторитетным для петлевых
// интерфейсов, а так же для броадкаст-зон (согласно RFC 1912)


Команда "'''touch'''" позволяет исполнителю запросить больше времени на выполнение задачи. Это полезно для задач, которые потенциально выполняются долго, но вы продолжаете использовать преимущества TTR при выполнении затянувшейся задачи не зависшим исполнителем. Исполнитель может ппереодически говорить серверу что он по-прежнему жив и выполняет задачу (например исполнитель может так делать при поступлении команды DEADLINE_SOON). Команда откладывает автоматическое выполнение команды «'''release'''» зарезервированной задачи на TTR секунд с момента поступления команды.
zone "localhost" {
          type master;
          file "localhost";
};


Формат команды:
zone "127.in-addr.arpa" {
          type master;
          file "127.in-addr.arpa";
};


'''touch <id>\r\n'''
zone "0.in-addr.arpa" {
          type master;
          file "0.in-addr.arpa";
};


* '''<id>''' идентификатор задачи, зарезервированной в текущем соединении.
zone "255.in-addr.arpa" {
          type master;
          file "255.in-addr.arpa";
};


Возможны два варианта ответа:
// описание основной зоны
zone "example.com" {
          type slave;
          file "example.com";
          masters { 10.0.0.152; };
};


*'''TOUCHED\r\n''' - сигнализирует об успешности операции
//описание обратной зоны
*'''NOT_FOUND\r\n''' - если задача не существует или была зарезервирована не этим исполнителем
zone "0.0.10.in-addr.arpa" {
          type slave;
          file "0.0.10.in-addr.arpa";
          masters { 10.0.0.152; };
};


===watch===
// настройки логирования
logging {
          channel "misc" {
                    file "/var/log/bind/misc.log" versions 4 size 4m;
                    print-time YES;
                    print-severity YES;
                    print-category YES;
          };


Команда «'''watch'''» добавляет именованный канал в '''watch list''' текущего соединения. Команда «'''reserve'''» принимает задачи из любого канала в watch list. Для каждого нового соединения создаётся новый '''watch list''', содержащий только один канал, называемый «'''default'''».
          channel "query" {
                    file "/var/log/bind/query.log" versions 4 size 4m;
                    print-time YES;
                    print-severity NO;
                    print-category NO;
          };


Формат команды:
          category default {
                    "misc";
          };


'''watch <tube>\r\n'''
          category queries {
                    "query";
          };
};
после перезапуска наш slave сервер благополучно скопирует необходимую ему информацию с главного сервера, о чем будет говорить наличие файлов в  каталоге:


* '''<tube>''' название канала, длиной не более 200 байт. Указывает какой канал будет добавлен в watch list. Если такого канала нет, то он будет создан.
root@debian:~# ls -la /var/cache/bind/
итого 28
drwxrwxr-x  2 root bind 4096 Июл  8 18:47 .
drwxr-xr-x 10 root root 4096 Июл  8 15:17 ..
-rw-r--r--  1 bind bind  416 Июл  8 18:32 0.0.10.in-addr.arpa
......
-rw-r--r--  1 bind bind  455 Июл  8 18:32 example.com
........
В принципе,/stroallow-transfer {pngp slave сервер может не хранить копию зоны у себя в файловой системе. Эта копия нужна только в момент старта DNS. Наличие копии зоны в файловой системе может избавить от сбоя при недоступности master сервера во время запуска slave DNS. Если не указать опцию file в разделе zone, то копия не создается.


Возможный ответ:
Настройка netfilter (iptables) для DNS BIND


'''WATCHING <count>\r\n'''
Собственно, настроив работу сервера, неплохо было бы его защитить. Мы знаем, что сервер работает на 53/udp порту. Почитав статью о том, что такое netfilter и правила iptables и ознакомившись с практическими примерами iptables, можно создать правила фильтрации сетевого трафика:


* '''<count>''' целое число каналов в текущем watch list.
dns ~ # iptables-save
# типовые правила iptables для DNS
*filter
:INPUT DROP [7511:662704]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
# разрешить доступ локальной сети к DNS серверу:
-A INPUT -s 192.168.1.1/24 -d 192.168.1.1/32 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
-A OUTPUT -p udp -m udp --sport 32768:61000 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 32768:61000 -j ACCEPT
-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# разрешить доступ DNS серверу совершать исходящие запросы
-A OUTPUT -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
Это типовой пример! Для задания правил iptables под Ваши задачи и конфигурацию сети, необходимо понимать принцип работы netfilter в Linux, почитав вышеуказанные статьи.


==Другие команды==
Устранение неполадок


===Группа команд peek===
Основным источником для выявления проблем с DNS является системный лог. Вот пример ошибок при запуске, когда я ошибся с путем к файлу зоны коревых серверов:


Группа команд «'''peek'''» позволяют клиенту инспектировать задачи в системе. Всего 4 варианта. Все команды, кроме первой, работают только для текущего именованного канала.
Jul  5 18:12:43 dns-server named[4224]: starting BIND 9.7.3 -u bind
Jul  5 18:12:43 dns-server named[4224]: built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-dlz-postgres=no' '--with-dlz-mysql=no' '--with-dlz-bdb=yes' '--with-dlz-filesystem=yes' '--with-dlz-ldap=yes' '--with-dlz-stub=yes' '--with-geoip=/usr' '--enable-ipv6' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2' 'LDFLAGS=' 'CPPFLAGS='
Jul  5 18:12:43 dns-server named[4224]: adjusted limit on open files from 1024 to 1048576
Jul  5 18:12:43 dns-server named[4224]: found 1 CPU, using 1 worker thread
Jul  5 18:12:43 dns-server named[4224]: using up to 4096 sockets
Jul  5 18:12:43 dns-server named[4224]: loading configuration from '/etc/bind/named.conf'
Jul  5 18:12:43 dns-server named[4224]: reading built-in trusted keys from file '/etc/bind/bind.keys'
Jul  5 18:12:43 dns-server named[4224]: using default UDP/IPv4 port range: [1024, 65535]
Jul  5 18:12:43 dns-server named[4224]: using default UDP/IPv6 port range: [1024, 65535]
Jul  5 18:12:43 dns-server named[4224]: listening on IPv4 interface lo, 127.0.0.1#53
Jul  5 18:12:43 dns-server named[4224]: listening on IPv4 interface eth1, 192.168.1.1#53
Jul  5 18:12:43 dns-server named[4224]: generating session key for dynamic DNS
Jul  5 18:12:43 dns-server named[4224]: could not configure root hints from '/etc/bind/db.root': file not found
Jul  5 18:12:43 dns-server named[4224]: loading configuration: file not found            # файл не найден
Jul  5 18:12:43 dns-server named[4224]: exiting (due to fatal error)
Jul  5 18:15:05 dns-server named[4298]: starting BIND 9.7.3 -u bind
Jul  5 18:15:05 dns-server named[4298]: built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-dlz-postgres=no' '--with-dlz-mysql=no' '--with-dlz-bdb=yes' '--with-dlz-filesystem=yes' '--with-dlz-ldap=yes' '--with-dlz-stub=yes' '--with-geoip=/usr' '--enable-ipv6' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2' 'LDFLAGS=' 'CPPFLAGS='
Jul  5 18:15:05 dns-server named[4298]: adjusted limit on open files from 1024 to 1048576
Jul  5 18:15:05 dns-server named[4298]: found 1 CPU, using 1 worker thread
Jul  5 18:15:05 dns-server named[4298]: using up to 4096 sockets
Jul  5 18:15:05 dns-server named[4298]: loading configuration from '/etc/bind/named.conf'
Jul  5 18:15:05 dns-server named[4298]: using default UDP/IPv4 port range: [1024, 65535]
Jul  5 18:15:05 dns-server named[4298]: using default UDP/IPv6 port range: [1024, 65535]
Jul  5 18:15:05 dns-server named[4298]: listening on IPv4 interface lo, 127.0.0.1#53
Jul  5 18:15:05 dns-server named[4298]: listening on IPv4 interface eth1, 192.168.1.1#53
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 254.169.IN-ADDR.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 2.0.192.IN-ADDR.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 100.51.198.IN-ADDR.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 113.0.203.IN-ADDR.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty 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.0.IP6.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty 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
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: D.F.IP6.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 8.E.F.IP6.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 9.E.F.IP6.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: A.E.F.IP6.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: B.E.F.IP6.ARPA
Jul  5 18:15:05 dns-server named[4298]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Jul  5 18:15:05 dns-server named[4298]: zone 0.in-addr.arpa/IN: loaded serial 1
Jul  5 18:15:05 dns-server named[4298]: zone 127.in-addr.arpa/IN: loaded serial 1
Jul  5 18:15:05 dns-server named[4298]: zone 255.in-addr.arpa/IN: loaded serial 1
Jul  5 18:15:05 dns-server named[4298]: zone localhost/IN: loaded serial 2
Jul  5 18:15:05 dns-server named[4298]: running                                  # запуск прошел удачно
Отличным инструментом для диагностики являются команды диагностики DNS.


* '''peek <id>\r\n''' — возвращает задачу по <id>.
* [http://www.k-max.name/linux/howto-dns-server-bind/ HOWTO DNS сервер BIND (практика)]
* '''peek-ready\r\n''' — возвращает следующую задачу со статусом '''ready'''.
* '''peek-delayed\r\n''' — возвращает следующую задачу со статусом '''delayed''' с наименьшим временем задержки.
* '''peek-buried\r\n''' - возвращает следующую в списке задачу со статусом '''buried'''.
 
Возможны два варианта ответа:
* '''NOT_FOUND\r\n''' — если запрашиваемая задача не создана или нет задачи с запрашиваемым статусом.
* '''FOUND <id> <bytes>\r\n<data>\r\n''' - случае успеха, строка ответа сопровождается строкой данных
** '''<id>''' идентификатор задачи.
** '''<bytes>''' целое число указывающее размер тела задачи, не включая граничные символы "\r\n".
** '''<data>''' тело задачи — последовательность байтов длиной '''<bytes> '''указанной в строке ответа.
 
===kick===
 
Команда «'''kick'''» применима только для текущего именованного канала. Она переносит задачи в очередь '''ready'''. Если есть хоть одна задача со статусом «'''buried'''», команда применится только к этим задачам. В противном случае, будут перемещены только задачи со статусом «'''delayed'''».
 
Формат команды:
 
'''kick <bound>\r\n'''
* '''<bound>''' целое число — количество задач для перемещения. Сервер переместит не более чем <bound> задач.
 
Возможный ответ:
 
'''KICKED <count>\r\n'''
* '''<count>''' целое число, указывающее число действительно перенесенных задач.
 
===kick-job===
 
Команда «'''kick-job'''» вариант команды '''kick''' с указанием конкретной задачи по её идентификатору. Если указываемая по id задача создана и имеет статус buried или delayed, она будет перемещена в очередь ready того же канала, в котором она находилась.
 
Формат команды:
 
'''kick-job <id>\r\n'''
* '''<id>''' идентификатор задачи для перемещения.
 
Возможен один из вариантов ответа:
 
* '''KICKED\r\n — '''если команда выполнена успешно.
* '''NOT_FOUND\r\n''' — если задачи не существует или у неё не подходящий статус. Это может быть так же внутренней ошибкой.
 
===stats-job===
 
Команда '''stats-job '''предоставляет статистику об указанной задаче, если указанная задача существует.
 
Формат команды:
 
'''stats-job <id>\r\n'''
* '''<id> '''идентификатор задачи
 
Возможен один из вариантов ответа:
* '''NOT_FOUND\r\n''' - если задачи не существует.
* '''OK <bytes>\r\n<data>\r\n'''"
** '''<bytes> '''размер последующей секции данных в байтах.
** '''<data>''' последовательность байт длиной <bytes> указанной в предыдущей строке. Это YAML файл со статистикой, представленной в виде словаря (прим переводчика: строки в виде <ключ>:<значение>).
 
Статистика содержит следующие параметры:
* '''id''' - идентификатор задачи;
* '''tube''' - название канала, в котором находится задача;
* '''state''' - статус: «'''ready'''», «'''delayed'''», «'''reserved'''» или «'''buried'''»
* '''pri''' - значение приоритета установленного командой «'''put'''», «'''release'''» или «'''bury'''».
* '''age''' - время в секундах с момента создания задачи командой «'''put'''».
* '''time-left''' - количество секунд до момента когда сервер переместит эту задачу в очередь '''ready'''. Это число имеет смысл только если задача имеет статус '''reserved''' или '''delayed'''. Если задача зарезервирована и время истекло раньше изменения статуса, то считается что у задачи тайм-аут.
* '''file''' - количество более ранних файлов binlog, содержащих эту задачу. Если при запуске сервера не была указана опция -b, число будет 0.
* '''reserves''' - количество раз, которое эта задача получала статус '''reserved'''.
* '''timeouts''' - количество раз, которое эта задача получала тайм-аут, находясь в резерве.
* '''releases ''' - количество раз, которое эта задача получала статус '''released''' от исполнителя, находясь в резерве.
* '''buries '''- количество раз, которое эта задача получала статус '''buried'''.
* '''kicks '''- количество раз, которое эта задача получала команду '''kick'''.
 
===stats-tube===
 
Команда '''stats-tube''' предоставляет статистику об указанном канале, если такой существует.
 
Формат команды:
 
'''stats-tube <tube>\r\n'''
* '''<tube>''' - название канала, длиной не более 200 байт. Статистика будет предоставлена для этого канала.
 
Возможен один из вариантов ответа:
* '''NOT_FOUND\r\n''' — если канала не существует.
* '''OK <bytes>\r\n<data>\r\n'''
** '''<bytes> ''' - размер последующей секции данных в байтах.
** '''<data>''' - последовательность байт длиной <bytes> указанной в предыдущей строке. Это YAML файл со статистикой, представленной в виде словаря (прим переводчика: строки в виде <ключ>:<значение>).
 
Статистика содержит следующие параметры:
* '''name''' - имя канала.
* '''current-jobs-urgent''' - количество задач со статусом '''ready''' и приоритетом < 1024 в этом канале.
* '''current-jobs-ready '''- количество задач в очереди '''ready''' в этом канале.
* '''current-jobs-reserved''' - количество зарезервированных исполнителями задач в канале.
* '''current-jobs-delayed''' - количество задач со статусом '''delayed''' в этом канале.
* '''current-jobs-buried''' - количество задач со статусом '''buried''' в этом канале.
* '''total-jobs''' - общее количество задач созданных в этом канале текущим процессом beanstalkd.
* '''current-using''' - количество открытых соединений использующих этот канал в настоящий момент.
* '''current-waiting''' -  количество открытых соединений, которые дали команду '''reserve''', наблюдая за каналом, но ещё не получили ответ.
* '''current-watching''' - количество открытых соединений, которые наблюдают за каналом.
* '''pause''' - количество секунд, которое канал был приостановлен.
* '''cmd-delete''' - общее количество раз, которое была выполнена команда '''delete''' в этом канале.
* '''cmd-pause-tube''' - общее количество раз, которое бал приостановлен канал командой '''pause-tube'''.
* '''pause-time-left''' - количество секунд до запуска канала (прим переводчика: не понял смысла этой фразы «is the number of seconds until the tube is un-paused.»).
 
===stats===
 
Команда '''stats''' предоставляет статистику о системе в целом.
 
'''stats\r\n'''
 
Ответ сервера:
 
'''OK <bytes>\r\n<data>\r\n'''
* '''<bytes>''' размер последующей секции данных в байтах.
* '''<data>''' последовательность байт длиной <bytes> указанной в предыдущей строке. Это YAML файл со статистикой, представленной в виде словаря (прим переводчика: строки в виде <ключ>:<значение>).
 
Параметры, описываемые как "общее количество", сбрасываются при запуске процесса beanstalkd. При указании опции -b, они не сохраняются на диске.
 
* '''current-jobs-urgent''' - количество задач в очереди (состоянии) '''ready''' с приоритетом менее 1024.
* '''current-jobs-ready''' - количество задач в очереди (состоянии) '''ready'''.
* '''current-jobs-reserved - '''количество задач зарезервированных всеми исполнителями.
* '''current-jobs-delayed '''- количество задач со сотатусом «'''delayed'''».
* '''current-jobs-buried '''- количество задач со сотатусом «'''buried'''».
* '''cmd-put''' - общее количество команд «'''put'''».
* '''cmd-peek''' - общее количество команд «'''peek'''».
* '''cmd-peek-ready''' - общее количество команд «'''peek-ready'''».
* '''cmd-peek-delayed''' - общее количество команд «'''peek-delayed'''».
* '''cmd-peek-buried''' - общее количество команд «'''peek-buried»'''.
* '''cmd-reserve''' - общее количество команд «'''reserve'''».
* '''cmd-use''' - общее количество команд «'''use'''».
* '''cmd-watch''' - общее количество команд «'''watch'''».
* '''cmd-ignore''' - общее количество команд «'''ignore'''».
* '''cmd-delete''' - общее количество команд «'''delete'''».
* '''cmd-release''' - общее количество команд «'''release'''».
* '''cmd-bury''' - общее количество команд «'''bury'''».
* '''cmd-kick''' - общее количество команд «'''kick'''».
* '''cmd-stats''' - общее количество команд «'''stats'''».
* '''cmd-stats-job''' - общее количество команд «'''stats-job»'''.
* '''cmd-stats-tube''' - общее количество команд «'''stats-tube»'''.
* '''cmd-list-tubes''' - общее количество команд «'''list-tubes'''».
* '''cmd-list-tube-used''' - общее количество команд «'''list-tube-used'''».
* '''cmd-list-tubes-watched''' - общее количество команд «'''list-tubes-watched'''».
* '''cmd-pause-tube''' - общее количество команд «'''pause-tube»'''.
* '''job-timeouts''' - общее количество раз, которое задача была в тайм-ауте.(прим переводчика: не точное описание, речь должна идти обо всех задачах, а не об одной)
* '''total-jobs''' - общее количество созданных задач.
* '''max-job-size''' - максимальное число байт в задаче.
* '''current-tubes''' - число существующих в настоящий момент каналов.
* '''current-connections''' - число открытых в настоящее время соединений.
* '''current-producers''' - число открытых соединений, через которое была дана по меньшей мере одна команда «'''put'''».
* '''current-workers''' - число открытых соединений, через которое была дана по меньшей мере одна команда «'''reserve'''».
* '''current-waiting''' - число открытых соединений, через которое была дана команда «reserve», но еще не получен ответ.
* '''total-connections''' - общее количество соединений (прим переводчика: не понятно, о каких соединениях идет речь, об открытых в настоящий момент или с учетом уже закрытых соединений)
* '''pid''' - pid процесса сервера.
* '''version''' - версия сервера.
* '''rusage-utime''' - общее время user CPU процесса в секундах и микросекундах.
* '''rusage-stime'''- общее время system CPU процесса в секундах и микросекундах.
* '''uptime''' - количество секунд с момента запуска процесса.
* '''binlog-oldest-index''' - индекс старейшего файла binlog, необходимого для хранения текущих задач.
* '''binlog-current-index''' -индекс текущего файла binlog, в который производится запись. Если binlog не активен, значение бедт равно 0.
* '''binlog-max-size''' - максимальный размер файла binlog в байтах, после которого будет создан новый.
* '''binlog-records-written''' - общее количество записей сделанных в binlog.
* '''binlog-records-migrated''' - общее количество записей, записанных как части архиров (прим переводчика: не понял смысл).
* '''id''' - случайный текстовый идентификатор для конкретного процесса сервера, генерируется при старте beanstalkd.
* '''hostname''' - hostname машины, выдаваемый командой uname.
 
===list-tubes===
 
Команда '''list-tubes''' возвращает список всех существующих каналов.
 
Формат команды:
 
'''list-tubes\r\n'''
 
Ответ сервера:
'''OK <bytes>\r\n<data>\r\n'''
* '''<bytes> - '''размер последующей секции данных в байтах.
* '''<data>''' - последовательность байт длиной <bytes> указанной в предыдущей строке. Это YAML файл содержащий названия всех каналов в виде списка строк.
 
===list-tube-used===
Команда '''list-tube-used''' возвращает канал, используемый клиентом в настоящее время.
 
Формат команды:
 
'''list-tube-used\r\n'''
 
Ответ сервера:
 
'''USING <tube>\r\n'''
*'''<tube>''' название используемого конала.
 
===list-tubes-watched===
Команда '''list-tubes-watched'''возвращает список каналов на которые подписан исполнитель в настоящий момент.
 
Формат команды:
 
'''list-tubes-watched\r\n'''
 
Ответ сервера:
 
'''OK <bytes>\r\n<data>\r\n'''
*'''<bytes> - '''размер последующей секции данных в байтах.
*'''<data>''' - последовательность байт длиной <bytes> указанной в предыдущей строке. Это YAML файл содержащий названия всех каналов на которые есть подписка в виде списка строк.
 
===quit===
Команда '''quit''' просто закрывает соединение.
 
Формат команды:
 
'''quit\r\n'''
 
===pause-tube===
 
Команда '''pause-tube''' позволяет приостановить резервирование новых задач на определенное время.
 
Формат команды:
 
'''pause-tube <tube-name> <delay>\r\n'''
* '''<tube>''' - название приостанавливаемого канала
* '''<delay>''' - целое число секунд до момента восстановления возможности резервирования задач из очереди.
 
Возможны два варианта ответа:
 
* '''PAUSED\r\n''' - сигнализирует об успешном выполнении.
* '''NOT_FOUND\r\n''' - если такого канала не существует.
 
===ignore===
 
Команда «'''ignore'''» только для исполнителей. Она удаляет именованый канал из watch list для текущего соединения.
 
Формат команды:
 
'''ignore <tube>\r\n'''
 
Возможен один из вариантов ответа:
 
* '''WATCHING <count>\r\n''' сигнализирует об успешности операции
** '''<count>''' целое число каналов в текущем watch list.
* '''NOT_IGNORED\r\n'''" если клиент пытается игнорировать единственный канал в его watch list.

Версия от 16:26, 16 октября 2016

Исходные данные

Для корректной работы DNS нем необходимо иметь настроенную сеть. DNS в текущей статье будет настроен на дистрибутиве Debian, особенности других дистрибутивов тоже будут отмечены. Конфиг сети стенда следующий:

dns:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
 address 10.0.0.152
 netmask 255.255.255.0
 gateway 10.0.0.254

auto eth1
iface eth1 inet static
 address 192.168.1.1
 netmask 255.255.255.0

где 10.0.0.152/24 - внешний интерфейс (подсеть, выделенная провайдером), 192.168.1.1/24 - внутренний (Локальная сеть). Настраиваемая зона будет иметь имя example.com. В примере со slave сервером, вторичный сервер будет расположен на IP 10.0.0.191.

Установка BIND9

Для работы DNS сервера необходимо установить пакет bind9 (в некоторых дистрибутивах - bind). Как отмечено на схеме - основным конфигурационным файлом BIND является файл named.conf (данный файл может быть размещен в каталоге /etc, иногда в /etc/bind ).

Параметры (синтаксис) named.conf

Синтаксис файла named.conf придерживается следующих правил:

IP-адреса - список IP должен быть разделен символом ";" , возможно указывать подсеть в формате 192.168.1.1/24 или 192.168.1.1/255.255.255.0, (для исключения IP перед ним нужно поставить знак !), возможно указывать имена "any", "none", "localhost" в двойных кавычках.

Комментарии - строки начинающиеся на #, // и заключенные в /* и */ считаются комментариями.

В файлах описания зон - символ @ является "переменной" хранящей имя зоны, указанной в конфигурационном файле named.conf или в директиве @ $ORIGIN текущего описания зоны.

Каждая завершенная строка параметров должна завершаться символом ; .

Раздел Acl Acl (access control list) - позволяет задать именованный список сетей. Формат раздела: acl "имя_сети" {ip; ip; ip; };

Раздел Options Раздел Options задает глобальные параметры конфигурационного файла, управляющие всеми зонами. Данный раздел имеет формат: options {операторы_раздела_Options};. Options может быть "вложен" в раздел Zone, при этом он переопределяет глобальные параметры. Часто используемые операторы options:

allow-query {список_ip} - Разрешает ответы на запросы только из список_ip. При отсутствии - сервер отвечает на все запросы.
allow-recursion {список_ip} - На запросы из список_ip будут выполняться рекурсивные запросы. Для остальных - итеративные. Если  не задан параметр, то сервер выполняет рекурсивные запросы для всех сетей.
allow-transfer {список_ip} - Указывает список серверов, которым разрешено брать зону с сервера (в основном тут указывают slave сервера)
directory /path/to/work/dir - указывает абсолютный путь к рабочему каталогу сервера. Этот оператор допустим только в разделе  options.
forwarders {ip порт, ip порт...} - указывает адреса хостов и если нужно порты, куда переадресовывать запросы (обычно тут указываются DNS провайдеров ISP).
forward ONLY или forward FIRST - параметр first указывает, DNS-серверу пытаться разрешать имена с помощью DNS-серверов, указанных в параметре forwarders, и лишь в случае, если разрешить имя с помощью данных серверов не удалось, то будет осуществлять попытки разрешения имени самостоятельно.
notify YES|NO - YES - уведомлять slave сервера об изменениях в зоне, NO - не уведомлять.
recursion YES|NO - YES - выполнять рекурсивные запросы, если просит клиент, NO - не выполнять (только итеративные запросы). Если ответ найден в кэше, то возвращается из кэша. (может использоваться только в разделе Options)

Раздел Zone Определяет описание зон(ы). Формат раздела: zone {операторы_раздела_zone}; Операторы, которые наиболее часто используются:

allow-update {список_ip} - указывает системы, которым разрешено динамически обновлять данную зону.
file "имя_файла" - указывает путь файла параметров зоны (должен быть расположен в каталоге, определенном в разделе options оператором directory)
masters {список_ip} -указывает список мастер-серверов. (допустим только в подчиненных зонах)
type "тип_зоны" - указывает тип зоны, описываемой в текущем разделе,тип_зоны может принимать следующие значения:
forward - указывает зону переадресации, которая переадресовывает запросы, пришедшие в эту зону.
hint - указывает вспомогательную зону (данный тип содержит информацию о корневых серверах, к которым сервер будет обращаться в случае невозможности найти ответ в кэше)
master - указывает работать в качестве мастер сервера для текущей зоны.
slave - указывает работать в качестве подчиненного сервера для текущей зоны.

Дополнительные параметры конфигурации Значения времени в файлах зон по умолчанию указывается в секундах, если за ними не стоит одна из следующих букв: S - секунды, M - минуты, H- часы, D - дни, W - недели. Соответственно, запись 2h20m5s будет иметь значение 2 часа 20 минут 5 секунд и соответствовать 8405 секунд.

Любое имя хоста/записи, не оканчивающиеся точкой считается неFQDN именем и будет дополнено именем текущей зоны. Например, запись domen в файле зоны examle.com будет развернуто в FQDN-имя domen.examle.com. .

В конфигурационных файлах BIND могут применяться следующие директивы:

$TTL - определяет TTL по-умолчанию для всех записей в текущей зоне.
$ORIGIN - изменяет имя зоны с указанного в файле named.conf. При этом, область действия данной директивы не распространяется  "выше" (то есть если файл включен директивой $INCLUDE, то область действия$ORIGN не распространяется на родительский)
$INCLUDE - включает указанный файл как часть файла зоны.

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

dns:~# cat /etc/resolv.conf
nameserver 127.0.0.1

Если в имени ресурсной записи встречается символ "*", то это он означает что вместо него можно подразумевать любую разрешенную последовательность символов. Такую запись называют "wildcard запись". Однако, символ "*" не может быть использован где угодно. Это может быть только первый символ в поле Name текущего домена, отделенный от остальных символом "."

Настройка кэширующего DNS сервера

После установки bind, он полностью готов работать как кэширующий DNS сервер без дополнительной настройки. Единственный недостаток - он обрабатывает запросы на всех интерфейсах, что нам абсолютно не нужно, поэтому мы немного подредактируем настройки сервера.

Для того, чтобы BIND работал в качестве кэширующего сервера, необходимо иметь конфигурационные файлы заполненные необходимой информацией:

named.conf;
описание серверов корневой зоны (зона типа hint);
описание зоны 127.in-addr.arpa.
dns:~# cat /etc/bind/named.conf
acl "lan" {
           192.168.1.1/24;
           127.0.0.1;
};

options {
           directory "/var/cache/bind";

          // If there is a firewall between you and nameservers you want
          // to talk to, you may need to fix the firewall to allow multiple
          // ports to talk.  See http://www.kb.cert.org/vuls/id/800113
          /*
          * Тут сказано, что если используется фаерволл, то необходимо
          *  нашему серверу создать соответствующие правила
          *  то есть открыть доступ по 53 TCP и UDP порту
          */

          forward first;              // задаем пересылку только первого запроса

          forwarders {                // указываем DNS сервера для пересылки
                     83.239.0.202;    // предоставленные провайдером
                     213.132.67.110;  // ибо до них ближе чем до корневых
          };

         listen-on { lan; };        // пусть слушает только нужные интерфейсы
         allow-query { lan; };      // разрешить запросы только из локальной сети
         allow-recursion { lan; };  // рекурсивные запросы тоже только из локальной
         allow-transfer { none; };  // трансфер зон нам не нужен

         version "unknown";         // не отображать версию DNS сервера при ответах

         auth-nxdomain no;    # для совместимости RFC1035
         listen-on-v6 { none; };    //IPv6 нам не нужен
         };

// описание настроек корневых серверов
zone "." {
         type hint;
         file "db.root";
};

// нижеописанные зоны определяют сервер авторитетным для петлевых
// интерфейсов, а так же для броадкаст-зон (согласно RFC 1912)

zone "localhost" {
         type master;
         file "localhost";
};

zone "127.in-addr.arpa" {
         type master;
          file "127.in-addr.arpa";
};

zone "0.in-addr.arpa" {
         type master;
         file "0.in-addr.arpa";
};

zone "255.in-addr.arpa" {
         type master;
         file "255.in-addr.arpa";
};

В данном примере приведен кэширующий DNS сервер, обрабатывающий запросы из списка сетей lan, в которую входит только одна локальная сеть 192.168.1.1/24 и петлевой интерфейс. При необходимости можно включить туда и другие сети. После определения списка сетей в директиве acl, в любом месте конфига можно будет ссылаться на этот список по имени (в нашем примере имя - lan), что, собственно и сделано в разделе options. Большинство параметров я прокомментировал, но отдельного внимания требует раздел, описывающий зону корневых серверов. В параметре file задан относительный путь к файлу описания корневых серверов (путь, относительно рабочего каталога сервера). За обновлениями данного файла необходимо следить, хотя он обновляется довольно редко (откуда брать обновленный файл я писал в теории DNS). Как вы заметили, имеется так же две записи для зоны localhost и две записи обратных зон для бродкаст доменов. Назначение этих зон состоит в том, чтобы избежать трансляции случайных запросов имен соответствующих IP-адресов на серверы, обслуживающие корневую зону.

Чтобы не вносить неразбериху в куче конфигурационных файлов, в статье я привожу примеры на основе единого конфигурационного файла. На самом деле, в последних версиях Debian (и других дистрибутивах Linux), файл named.conf выглядит следующим образом:

root@master:~# cat /etc/bind/named.conf // This is the primary configuration file for the BIND DNS server named. // // Please read /usr/share/doc/bind9/README.Debian.gz for information on the // structure of BIND configuration files in Debian, *BEFORE* you customize // this configuration file. // // If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options"; include "/etc/bind/named.conf.local"; include "/etc/bind/named.conf.default-zones"; То есть основной файл не содержит конфигураций, а включает в себя более узко специализированные файлы, которые отвечают за свои задачи, например named.conf.options - содержит глобальные параметры конфигурации, named.conf.default-zones - содержит описание localhost и broadcast зон, а named.conf.local содержит описания зон, за которые отвечает данный сервер.


Далее, хочу обратить внимание на наличие файлов зон в каталоге, указанном в разделе options в параметре directory с именами, соответствующими параметрам file в разделах, описывающих зоны:

dns:~# ls -l /var/cache/bind/ итого 24 -rw-r--r-- 1 root root 237 Май 28 01:28 0.in-addr.arpa -rw-r--r-- 1 root root 271 Май 28 01:28 127.in-addr.arpa -rw-r--r-- 1 root root 237 Май 28 01:28 255.in-addr.arpa -rw-r--r-- 1 root root 2994 Май 28 01:28 db.root -rw-r--r-- 1 root root 270 Май 28 01:28 localhost dns:~# cat /var/cache/bind/127.in-addr.arpa

BIND reverse data file for local loopback interface

$TTL 604800 @ IN SOA localhost. root.localhost. (

                             1         ; Serial
                             604800    ; Refresh
                             86400     ; Retry
                             2419200   ; Expire
                             604800 )  ; Negative Cache TTL

@ IN NS localhost. 1.0.0 IN PTR localhost. Рассматривать файлы "петлевых" и бродкастовых зон не вижу смысла, т.к. после установки пакета bind настройки заданные по умолчанию в данных файлах вполне приемлемы. Далее, при организации мастер сервера мы рассмотрим пример описания файла зоны. Хочу обратить внимание, что мы настраиваем кэширующий сервер, а определяем мы его и как master для некоторых из зон. В нашем случае "кэширующий" говорит о том, что наш сервер не поддерживает ни одну из реально существующих зон, т.е. ему не делегировано прав на такое обслуживание.

Да, чуть не забыл, демон named должен быть разрешен для запуска на необходимых уровнях выполнения ОС (команда в RedHat - /sbin/chkconfig bind9 on, в Debian - /usr/sbin/update-rc.d bind9 defaults). После изменения конфигурационных файлов можно добавить сервис в автозагрузку и запустить демон:

dns:~# update-rc.d bind9 defaults Adding system startup for /etc/init.d/bind9 ... /etc/rc0.d/K20bind9 -> ../init.d/bind9 /etc/rc1.d/K20bind9 -> ../init.d/bind9 /etc/rc6.d/K20bind9 -> ../init.d/bind9 /etc/rc2.d/S20bind9 -> ../init.d/bind9 /etc/rc3.d/S20bind9 -> ../init.d/bind9 /etc/rc4.d/S20bind9 -> ../init.d/bind9 /etc/rc5.d/S20bind9 -> ../init.d/bind9 dns:~# /etc/init.d/bind9 start Starting domain name service...: bind9. На этом настройка кэширующего DNS завершена. Все запросы, которые попадают в кэш DNS сервера он хранит в оперативной памяти компьютера и при перезапуске демона эти данные обнуляются. Для проверки работы кэша можно выполнить команду nslookup mail.ru example.com., если в ответе содержится строка Non-authoritative answer, то адрес пришел из кэша, а так же если выполнить dig www.ru. (или другой домен, которого еще нет в кэше) и через некоторое время повторить команду, то время ответа должно быть гораздо меньше.

Давайте рассмотрим другие варианты сервера.

Главный (master) сервер зоны

Основной конфиг содержит следующие настройки:

dns:~# cat /etc/bind/named.conf acl "lan" {

         192.168.1.1/24;
         127.0.0.1;

};

options {

         directory "/var/cache/bind";
         allow-query { any; };       // отвечать на зпросы со всех интерфейсов
         recursion no;               // запретить рекурсивные запросы
         auth-nxdomain no;           // для совместимости RFC1035
         listen-on-v6 { none; };     // IPv6 нам не нужен
         version "unknown";          // не отображать версию DNS сервера при ответах
         /*
         *  Раскомментируйте строки ниже, если
         *  хотите разрешить рекрусивные запросы
         *  из локальной сети.
         *  (так же, необходимо закомментировать
         *  recursion no; )
         */
         # forwarders {                 // указываем DNS сервера для пересылки
         #         83.239.0.202;        // предоставленные провайдером
         #         213.132.67.110;      // ибо до них ближе чем до корневых
         # };
         # allow-recursion { lan; };    // рекурсивные запросы тоже только из локальной

};

// описание настроек корневых серверов zone "." {

         type hint;
         file "db.root";

};

// нижеописанные зоны определяют сервер авторитетным для петлевых // интерфейсов, а так же для броадкаст-зон (согласно RFC 1912)

zone "localhost" {

         type master;
         file "localhost";

};

zone "127.in-addr.arpa" {

         type master;
         file "127.in-addr.arpa";

};

zone "0.in-addr.arpa" {

         type master;
         file "0.in-addr.arpa";

};

zone "255.in-addr.arpa" {

         type master;
         file "255.in-addr.arpa";

};

// описание основной зоны zone "example.com" {

         type master;
         file "example.com";
         allow-transfer { 10.0.0.191; };

};

//описание обратных зон zone "0.0.10.in-addr.arpa" {

         type master;
         file "0.0.10.in-addr.arpa";
         allow-transfer { 10.0.0.191; };

};

zone "1.168.192.in-addr.arpa" {

         type master;
         file "1.168.192.in-addr.arpa";
  1. allow-transfer { 10.0.0.191; }; // зона описывает локальную сеть поэтому ее не передаем

};

// настройки логирования logging {

         channel "misc" {
                   file "/var/log/bind/misc.log" versions 4 size 4m;
                   print-time yes;
                   print-severity yes;
                   print-category yes;
         };
         channel "query" {
                   file "/var/log/bind/query.log" versions 4 size 4m;
                   print-time yes;
                   print-severity no;
                   print-category no;
         };
         category default {
                   "misc";
         };
         category queries {
                   "query";
         };

}; Давайте кратко разберем конфигурационный файл и настройки master сервера: мы настраиваем мастер сервер для зоны example.com. . Согласно конфига, наш BIND имеет рабочий каталог /var/cache/bind, сервер отвечает на запросы со всех интерфейсов (allow-query {any ;};), рекурсивные запросы обрабатывает как итеративные (recursion no), является мастер-сервером для зоны example.com и локальных служебных зон (type master). При этом, если необходимо разрешить кэширование (то есть рекурсивные запросы) для локальной сети, то необходимо раскомментировать параметры forwarders и allow-recursion и закомментировать recursion no;.

Так же, для примера, я привел возможности BIND логировать все происходящее при работе сервера (можно для этой цели использовать syslog). В разделе logging задаются 2 параметра channel (можно и больше двух - на ваше усмотрение), эти параметры дословно можно назвать "канал" записи. Каждый канал определяет имя канала и настройки параметров записи (что записывать, а что - нет и куда писать). Директива category задает какую категорию сообщений в какой канал отправлять. Исходя из этого, мы имеем: запись стандартной информации в канал misc, а приходящие запросы посылаются в канал query. При этом, если файлы журнала достигают 4Мб (size 4m), он переименовывается добавлением к имени .1 и начинается запись в новый журнал, числа в конце других журналов увеличиваются. Журналы с номером, более указанного в version (в нашем случае 4) удаляются (Управлять ротацией логов можно так же с помощью logrotate). Параметры print* определяют заносить ли в журнал время появления, важность и категорию информации. Более подробно про настройки раздела logging можно почитать в man (5) named.conf.

Отдельно хочется описать параметр allow-transfer { 10.0.0.191; };. Данный параметр описывает серверы, которым разрешено скачивать копию зоны - т.н. slave серверА. В следующем примере мы разберем настройку slave DNS.

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

dns:~# mkdir /var/log/bind/ dns:~# chmod 744 /var/log/bind/ dns:~# ps aux | grep named bind 4298 0.0 3.4 46792 13272 ? Ssl Jul05 0:00 /usr/sbin/named -u bind root 4815 0.0 0.1 3304 772 pts/4 S+ 18:19 0:00 grep named dns:~# chown bind /var/log/bind/ dns:~# ls -ld /var/log/bind/ drwxr--r-- 2 bind root 4096 Июл 6 18:18 /var/log/bind/ Давайте далее рассмотрим наш файл описания зоны example.com.:

dns:~# cat /var/cache/bind/example.com $TTL 3D @ IN SOA ns.example.com. root.example.com. (

                                       2011070601      ; serial
                                       8H              ; refresh
                                       2H              ; retry
                                       2W              ; expire
                                       1D)             ; minimum

@ IN NS ns.example.com. @ IN NS ns2.example.com. @ IN A 10.0.0.152 @ IN MX 5 mx.example.com. ns IN A 10.0.0.152 ns2 IN A 10.0.0.191 mx IN A 10.0.0.152 www IN CNAME @ а так же в домене in-addr.arpa.

dns:~# cat /var/cache/bind/0.0.10.in-addr.arpa $TTL 3600 @ IN SOA ns.examle.com. root.example.com. (

            2007042001 ; Serial
            3600       ; Refresh
            900        ; Retry
            3600000    ; Expire
            3600 )     ; Minimum
       IN      NS      ns.examle.com.
       IN      NS      ns2.example.com.

152 IN PTR examle.com. 191 IN PTR ns.example.com.

  • IN PTR examle.com.

dns:~# cat /var/cache/bind/1.168.192.in-addr.arpa $TTL 3600 @ IN SOA ns.examle.com. root.example.com. (

            2007042001 ; Serial
            3600       ; Refresh
            900        ; Retry
            3600000    ; Expire
            3600 )     ; Minimum
       IN      NS      ns.examle.com.
       IN      NS      ns2.example.com.
  • IN PTR examle.com.

Наша сеть небольшая, предполагается, что в сети совсем мало машин. Все сервисы сети размещены на одном хосте example.com., поэтому и master DNS (ns.example.com.) и почтовый сервер (mx.example.com.) указывает на одну машину (10.0.0.152).

Вторичный (secondary, slave) авторитетный сервер зоны

Основная функция slave сервера - автоматическая синхронизация описания зоны с master сервером. Данная задача регламентируется документом RFC 1034 в разделе 4.3.5. Согласно данному документу обмен данными между серверами рекомендовано производить по протоколу TCP, посредством запроса AXFR. По этому запросу за одно TCP соединение должна передаваться вся зона целиком (RFC 1035).

Так же, slave DNS-сервер делит нагрузку с master сервером или принимает на себя всю нагрузку в случае аварии па первом сервере.

Прежде чем приступить к настройке slave DNS сервера, необходимо проверить возможность получения зоны вручную со вторичного сервера с помощью следующей команды:

root@debian:~# dig @10.0.0.152 example.com. axfr

<<>> DiG 9.7.3 <<>> @10.0.0.152 example.com. axfr
(1 server found)
global options
+cmd

example.com. 259200 IN SOA ns.example.com. root.example.com. 2011070801 28800 7200 1209600 86400 example.com. 259200 IN NS ns.example.com. example.com. 259200 IN NS ns2.example.com. example.com. 259200 IN A 10.0.0.152 example.com. 259200 IN MX 5 mx.example.com. mx.example.com. 259200 IN A 10.0.0.152 ns.example.com. 259200 IN A 10.0.0.152 ns2.example.com. 259200 IN A 10.0.0.191 www.example.com. 259200 IN CNAME example.com. example.com. 259200 IN SOA ns.example.com. root.example.com. 2011070801 28800 7200 1209600 86400

Query time
14 msec
SERVER
10.0.0.152#53(10.0.0.152)
WHEN
Fri Jul 8 15:33:54 2011
XFR size
11 records (messages 1, bytes 258)

Получение зоны прошло успешно. Далее, для настройки подчиненного сервера, алгоритм следующий:

Скопировать конфигурационный файл named.conf с master сервера; Заменить параметр type master на type slave в тех зонах, для которых он будет вторичным; Параметр allow-transfer { 10.0.0.191; }; заменить на masters { 10.0.0.152;}; в тех зонах, для которых он будет вторичным; Удалить зоны, которые не будет обслуживать текущий сервер, в том числе и корневую, если slave не будет отвечать на рекурсивные запросы; Создать каталоги для логов, как в предыдущем примере. Итого, мы получаем конфиг slave сервера:

root@debian:~# cat /etc/bind/named.conf options {

         directory "/var/cache/bind";
         allow-query { any; };      // отвечать на запросы со всех интерфейсов
         recursion no;              // запретить рекурсивные запросы
         auth-nxdomain no;          // для совместимости RFC1035
         listen-on-v6 { none; };    // IPv6 нам не нужен
         version "unknown";         // не отображать версию DNS сервера при ответах

};

// нижеописанные зоны определяют сервер авторитетным для петлевых // интерфейсов, а так же для броадкаст-зон (согласно RFC 1912)

zone "localhost" {

         type master;
         file "localhost";

};

zone "127.in-addr.arpa" {

         type master;
         file "127.in-addr.arpa";

};

zone "0.in-addr.arpa" {

         type master;
         file "0.in-addr.arpa";

};

zone "255.in-addr.arpa" {

         type master;
         file "255.in-addr.arpa";

};

// описание основной зоны zone "example.com" {

         type slave;
         file "example.com";
         masters { 10.0.0.152; };

};

//описание обратной зоны zone "0.0.10.in-addr.arpa" {

         type slave;
         file "0.0.10.in-addr.arpa";
         masters { 10.0.0.152; };

};

// настройки логирования logging {

         channel "misc" {
                   file "/var/log/bind/misc.log" versions 4 size 4m;
                   print-time YES;
                   print-severity YES;
                   print-category YES;
         };
         channel "query" {
                   file "/var/log/bind/query.log" versions 4 size 4m;
                   print-time YES;
                   print-severity NO;
                   print-category NO;
         };
         category default {
                   "misc";
         };
         category queries {
                   "query";
         };

}; после перезапуска наш slave сервер благополучно скопирует необходимую ему информацию с главного сервера, о чем будет говорить наличие файлов в каталоге:

root@debian:~# ls -la /var/cache/bind/ итого 28 drwxrwxr-x 2 root bind 4096 Июл 8 18:47 . drwxr-xr-x 10 root root 4096 Июл 8 15:17 .. -rw-r--r-- 1 bind bind 416 Июл 8 18:32 0.0.10.in-addr.arpa ...... -rw-r--r-- 1 bind bind 455 Июл 8 18:32 example.com ........ В принципе,/stroallow-transfer {pngp slave сервер может не хранить копию зоны у себя в файловой системе. Эта копия нужна только в момент старта DNS. Наличие копии зоны в файловой системе может избавить от сбоя при недоступности master сервера во время запуска slave DNS. Если не указать опцию file в разделе zone, то копия не создается.

Настройка netfilter (iptables) для DNS BIND

Собственно, настроив работу сервера, неплохо было бы его защитить. Мы знаем, что сервер работает на 53/udp порту. Почитав статью о том, что такое netfilter и правила iptables и ознакомившись с практическими примерами iptables, можно создать правила фильтрации сетевого трафика:

dns ~ # iptables-save

  1. типовые правила iptables для DNS
  • filter
INPUT DROP [7511:662704]
FORWARD DROP [0:0]
OUTPUT DROP [0:0]

-A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -m conntrack --ctstate INVALID -j DROP

  1. разрешить доступ локальной сети к DNS серверу:

-A INPUT -s 192.168.1.1/24 -d 192.168.1.1/32 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT -A OUTPUT -o lo -j ACCEPT -A OUTPUT -p icmp -j ACCEPT -A OUTPUT -p udp -m udp --sport 32768:61000 -j ACCEPT -A OUTPUT -p tcp -m tcp --sport 32768:61000 -j ACCEPT -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

  1. разрешить доступ DNS серверу совершать исходящие запросы

-A OUTPUT -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT COMMIT Это типовой пример! Для задания правил iptables под Ваши задачи и конфигурацию сети, необходимо понимать принцип работы netfilter в Linux, почитав вышеуказанные статьи.

Устранение неполадок

Основным источником для выявления проблем с DNS является системный лог. Вот пример ошибок при запуске, когда я ошибся с путем к файлу зоны коревых серверов:

Jul 5 18:12:43 dns-server named[4224]: starting BIND 9.7.3 -u bind Jul 5 18:12:43 dns-server named[4224]: built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-dlz-postgres=no' '--with-dlz-mysql=no' '--with-dlz-bdb=yes' '--with-dlz-filesystem=yes' '--with-dlz-ldap=yes' '--with-dlz-stub=yes' '--with-geoip=/usr' '--enable-ipv6' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2' 'LDFLAGS=' 'CPPFLAGS=' Jul 5 18:12:43 dns-server named[4224]: adjusted limit on open files from 1024 to 1048576 Jul 5 18:12:43 dns-server named[4224]: found 1 CPU, using 1 worker thread Jul 5 18:12:43 dns-server named[4224]: using up to 4096 sockets Jul 5 18:12:43 dns-server named[4224]: loading configuration from '/etc/bind/named.conf' Jul 5 18:12:43 dns-server named[4224]: reading built-in trusted keys from file '/etc/bind/bind.keys' Jul 5 18:12:43 dns-server named[4224]: using default UDP/IPv4 port range: [1024, 65535] Jul 5 18:12:43 dns-server named[4224]: using default UDP/IPv6 port range: [1024, 65535] Jul 5 18:12:43 dns-server named[4224]: listening on IPv4 interface lo, 127.0.0.1#53 Jul 5 18:12:43 dns-server named[4224]: listening on IPv4 interface eth1, 192.168.1.1#53 Jul 5 18:12:43 dns-server named[4224]: generating session key for dynamic DNS Jul 5 18:12:43 dns-server named[4224]: could not configure root hints from '/etc/bind/db.root': file not found Jul 5 18:12:43 dns-server named[4224]: loading configuration: file not found # файл не найден Jul 5 18:12:43 dns-server named[4224]: exiting (due to fatal error) Jul 5 18:15:05 dns-server named[4298]: starting BIND 9.7.3 -u bind Jul 5 18:15:05 dns-server named[4298]: built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-dlz-postgres=no' '--with-dlz-mysql=no' '--with-dlz-bdb=yes' '--with-dlz-filesystem=yes' '--with-dlz-ldap=yes' '--with-dlz-stub=yes' '--with-geoip=/usr' '--enable-ipv6' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2' 'LDFLAGS=' 'CPPFLAGS=' Jul 5 18:15:05 dns-server named[4298]: adjusted limit on open files from 1024 to 1048576 Jul 5 18:15:05 dns-server named[4298]: found 1 CPU, using 1 worker thread Jul 5 18:15:05 dns-server named[4298]: using up to 4096 sockets Jul 5 18:15:05 dns-server named[4298]: loading configuration from '/etc/bind/named.conf' Jul 5 18:15:05 dns-server named[4298]: using default UDP/IPv4 port range: [1024, 65535] Jul 5 18:15:05 dns-server named[4298]: using default UDP/IPv6 port range: [1024, 65535] Jul 5 18:15:05 dns-server named[4298]: listening on IPv4 interface lo, 127.0.0.1#53 Jul 5 18:15:05 dns-server named[4298]: listening on IPv4 interface eth1, 192.168.1.1#53 Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 254.169.IN-ADDR.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 2.0.192.IN-ADDR.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 100.51.198.IN-ADDR.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 113.0.203.IN-ADDR.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty 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.0.IP6.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty 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 Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: D.F.IP6.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 8.E.F.IP6.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 9.E.F.IP6.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: A.E.F.IP6.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: B.E.F.IP6.ARPA Jul 5 18:15:05 dns-server named[4298]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA Jul 5 18:15:05 dns-server named[4298]: zone 0.in-addr.arpa/IN: loaded serial 1 Jul 5 18:15:05 dns-server named[4298]: zone 127.in-addr.arpa/IN: loaded serial 1 Jul 5 18:15:05 dns-server named[4298]: zone 255.in-addr.arpa/IN: loaded serial 1 Jul 5 18:15:05 dns-server named[4298]: zone localhost/IN: loaded serial 2 Jul 5 18:15:05 dns-server named[4298]: running # запуск прошел удачно Отличным инструментом для диагностики являются команды диагностики DNS.