UMGUM.COM (лучше) 

Bind9 ( Установка и простейшая настройка DNS-серверов "Bind9". )

24 марта 2010  (обновлено 15 августа 2016)

OS: "Linux Debian 6/7/8/9", "Linux Ubuntu 14/16 LTS".
Apps: "Bind9".


Задача: завести пару-тройку "кеширующих" серверов прямого и обратного разрешения имён (далее: NS) обслуживающих внешние запросы и запросы локальной сети с разделением зон выдачи по принципу определения источника запроса.

DNS-сервис слушает и отвечает через порты TCP:53 и UDP:53. Обеспечиваем видимость наших NS-серверов как извне, так и со стороны локальных сетей по указанным портам.


Устанавливаем необходимые пакеты:

# aptitude install bind9 bind9utils

Создаем директории для двух типов "доменных зон" - конфигурируемые на этом сервере и загружаемые с других:

# mkdir -p /etc/bind/master
# mkdir -p /etc/bind/slave

Учитывая то, что наши NS-серверы взаимодействуют также и через интернет, постараемся обеспечить им повышенные условия безопасности. Заставим сервера при транзакциях использовать механизм подписей md5-ключами (это нужно для того, что бы, если действительный сервер будет выведен из строя, на его место нельзя было бы "подставить" сервер злоумышленника, могущего внести путаницу в работе инфраструктуры).

Создаем директорию для хранения ключей подписания транзакций:

# mkdir -p /etc/bind/key

Создадим, предназначенным для этого генератором ключей, каждому из наших серверов ключ подписи транзакций:

# cd /tmp
# dnssec-keygen -a HMAC-MD5 -b 128 -n HOST -r /dev/urandom ./ns.local.
# dnssec-keygen -a HMAC-MD5 -b 128 -n HOST -r /dev/urandom ./ns1.local.

При генерации ключей мы использовали алгоритм шифрования HMAC-MD5, с длиной ключа в 128 bit. Тип создаваемого ключа в нашей конфигурации не важен - мы указали HOST.

В результате выполнения вышеприведённых команд в текущей директории будут созданы файлы с "говорящими" именами и расширениями ".key" и ".private". Нас интересует значение переменной "Key: " из этих файлов - это и есть секретная последовательность для "ключа".

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

# vi /etc/bind/key/ns.local.key

key ns.local {
  algorithm hmac-md5;
  secret "наш-ключ-сгенерированный-ранее-для-этого-сервера";
};

# vi /etc/bind/key/ns1.local.key

key ns1.local {
  algorithm hmac-md5;
  secret "наш-ключ-сгенерированный-ранее-для-этого-сервера";
};

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

Генерируем ещё один ключ, наличие которого требуется для подписания транзакций между службой "named" и управляющей утилитой "rndc" (возможно этого не потребуется и ключ уже создан в процессе инсталляции). Если утилита "rndc" если его не обнаружит в корне директории "Bind9" (а при отсутствии собственного конфигурационного файла она именно там ищет ключ подписания транзакций), то она не сможет соединится с службой "named" для управления ею (мы можем переместить этот ключ в другое место, но после этого потребуется указать новое месторасположение ключа службе "named" и утилите "rndc" в их конфигурационных файлах или параметрах запуска):

# cd /tmp
# dnssec-keygen -a HMAC-MD5 -b 128 -n USER -r /dev/urandom ./rndckey

Создаем файл описания ключа:

# vi /etc/bind/rndc.key

key "rndc-key" {
  algorithm hmac-md5;
  secret "наш-rndc-key-сгенерированный-ранее";
};

После создания необходимых ключей необходимо в обязательном порядке удалить все временные файлы, сгенерированные утилитой "dnssec-keygen" - они нам уже не нужны.

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

Создаем или доводим имеющийся конфигурационный файл опций службы "named" до следующего вида:

# vi /etc/bind/named.conf.options

# Включение конфигурационных файлов описания ключей для подписания транзакций
include "/etc/bind/rndc.key";
include "/etc/bind/key/ns.local.key";
include "/etc/bind/key/ns1.local.key";

# Привязываем описанные ранее в своих конфигурационных файлах ключи к определённым ресурсам (это дополнительный уровень проверки, только от этих ресурсов будет принята подпись транзакции указанным ключём), в нашем случае, индивидуально ко всем нашим серверам:
server 10.10.2.21 { keys { ns.local; }; };
server 10.10.2.22 { keys { ns1.local; }; };

# В зоне "trusted-dns" находятся те, кому будет далее разрешён трансфер зон, проверка на принадлежность производится как на основании адреса источника запроса, так и на наличии у него соответствующего ключа подписи транзакции
acl trusted-dns { 127.0.0.1; key ns.local; key ns1.local; };

# Распределение поступающих запросов на зоны по источнику (локальная сеть / не локальная сеть)
acl internal-subnet { 192.168/16; 10.10/16; 127.0.0.1; };
acl external-subnet { !192.168/16; !10.10/16; any; };

options {
  directory       "/var/cache/bind"; # директория временных файлов, где будет хозяйничать наш кеширующий сервер
  dump-file       "/var/lib/bind/named.dump";
  statistics-file "/var/lib/bind/named.stats";
  version         "0.0"; # слабая попытка ввести в недоумение начинающих "хацкеров"
  port            53;
  listen-on       { any; }; # служба слушает и отвечает на всех интерфейсах
  listen-on-v6    { none; }; # шестую версию TCP использовать пока не будем, все равно некому воспользоваться
  allow-query     { any; }; # разрешаем запросы к нашим серверам всем, не жалко
  allow-transfer  { trusted-dns; }; # трансфер зон разрешён только доверенным серверам, жалко
  allow-update    { none; }; # никому не позволяем вмешиваться в содержимое наших таблиц зон
};

# Описание разрешений для удалённого доступа утилиты "rndc" управления сервисом (в нашем случае запросы принимаются по адресу 127.0.0.1 на порту 953 от клиента с адресом 127.0.0.1 подтвердившего свою подлинность с помощью ключа) - может быть мы и не воспользуемся этим сервисом, но опишем для исключения несанкционированного доступа из-за неоднозначного толкования настроек "по умолчанию":
controls {
  inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; };
};

logging {
  channel default_ch {
    file "/var/log/named/named.log" versions 3 size 1024k;
    severity info;
    print-time yes;
    print-category yes;
  };

  channel security_ch {
    file "/var/log/named/security.log" versions 3 size 1024k;
    severity info;
    print-time yes;
    print-category yes;
  };

  category default { default_ch; };
  category security { security_ch; };
};

Создаем или доводим имеющийся конфигурационный файл службы "named" до следующего вида:

# vi /etc/bind/named.conf

include "/etc/bind/named.conf.options";

view "external-subnet" {
  match-clients   { external-subnet; }; # клиенты представления - только внешние сети
  allow-query     { external-subnet; }; # разрешены запросы только из внешних сетей
  allow-transfer  { trusted-dns; };
  allow-update    { none; };
  recursion       no;
  allow-recursion { none; }; # запрещаем извне рекурсивные запросы через нас, в последне время этот функционал часто используется для DDoS сторонних ресурсов транзитным усиленным трафиком (dns-amplification)

  zone "." {
    type hint;
    file "/etc/bind/db.root";
  };

  zone "localhost" {
    type master;
    file "/etc/bind/db.localhost";
  };

  zone "127.in-addr.arpa" {
    type master;
    file "/etc/bind/db.127";
  };

  # описание первичной зоны прямого разрешения имён для домена domain.name (применимо в конфигурации первичного NS)
  zone "domain.name" {
    type master;
    file "/etc/bind/master/db.domain.name";
  };

# описание вторичной зоны прямого разрешения имён для домена domain.name (применимо в конфигурации вторичного NS)
  zone "domain.name" {
    type slave;
    masterfile-format text;
    file "/etc/bind/slave/db.domain.name";
    masters { 10.10.2.21; };
  };

  # описание зоны обратного разрешения имён для "подсети" получаемой от провайдера (в нашем случае каждый NS получает свою "подсеть" от разных провайдеров, потому нет смысла её распространять на вторичные сервера). В примере провайдером делегируется нашему NS обратное разрешение адресов для "подсети" 88.204.202.240/29
  zone "240/29.202.204.88.in-addr.arpa" {
    type master;
    file "/etc/bind/master/db.240-29.202.204.88.in-addr.arpa";
  };

};

view "internal-subnet" {
  match-clients   { internal-subnet; }; # клиенты представления - только локальные сети
  allow-query     { internal-subnet; }; # разрешены запросы только из локальных сетей
  allow-transfer  { trusted-dns; };
  allow-update    { none; };
  recursion       yes;
  allow-recursion { any; }; # разрешаем всем рекурсивные запросы изнутри наружу

  zone "localhost" {
    type master;
    file "/etc/bind/db.localhost";
  };

  zone "127.in-addr.arpa" {
    type master;
    file "/etc/bind/db.127";
  };

  zone "0.in-addr.arpa" {
    type master;
    file "/etc/bind/db.0";
  };

  zone "255.in-addr.arpa" {
    type master;
    file "/etc/bind/db.255";
  };

  # описание первичной зоны прямого разрешения имён для домена domain.name (применимо в конфигурации первичного NS)
  zone "domain.name" {
    type master;
    file "/etc/bind/master/db.domain.name.local";
  };

# описание вторичной зоны прямого разрешения имён для домена domain.name (применимо в конфигурации вторичного NS)
  zone "domain.name" {
    type slave;
    masterfile-format text;
    file "/etc/bind/slave/db.domain.name";
    masters { 10.10.2.21; };
  };

  # описание первичной зоны обратного разрешения имён для поддерживаемой локальной сети (применимо в конфигурации первичного NS)
  zone "168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/master/db.168.192.in-addr.arpa.local";
  };

  # описание первичной зоны обратного разрешения имён для поддерживаемой локальной сети (применимо в конфигурации первичного NS)
  zone "10.10.in-addr.arpa" {
    type master;
    file "/etc/bind/master/db.10.10.in-addr.arpa.local";
  };

  # описание вторичной зоны обратного разрешения имён для поддерживаемой локальной сети (применимо в конфигурации вторичного NS). Распространять зоны обратного разрешения имён в локальной сети имеет смысл, так как диапазон адресов локальной сети одинаков для всех NS
  zone "168.192.in-addr.arpa" {
    type slave;
    masterfile-format text;
    file "/etc/bind/slave/db.168.192.in-addr.arpa";
    masters { 10.10.2.21; };
  };

  # описание вторичной зоны обратного разрешения имён для поддерживаемой локальной сети (применимо в конфигурации вторичного NS). Распространять зоны обратного разрешения имён в локальной сети имеет смысл, так как диапазон адресов локальной сети одинаков для всех NS
  zone "10.10.in-addr.arpa" {
    type slave;
    masterfile-format text;
    file "/etc/bind/slave/db.10.10.in-addr.arpa";
    masters { 10.10.2.21; };
  };

};

В конфигурационных файлах зон начало комментария обозначается символом точки с запятой ";". Никаких "#" или "//", только точка с запятой. После доменных имён, прописываемых в конфигурационных файлах зон обязательно ставится символ "." (например: "domain.name."). Немало минут, а то и часов, провели в раздражённом поиске неисправности люди, забывающие об этих особенностях построения конфигурационных файлов зон bind.

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

# vi /etc/bind/master/db.domain.name

$TTL 3600
; SOA
@  IN  SOA  domain.name.  nsadmin.domain.name. (
  2009102801
  7200
  900
  1209600
  3600
);

; NS - Name Servers
@    IN    NS    ns.local.
@    IN    NS    ns1.local.

; A - Address records
@ IN    A    10.10.2.21
mx1 IN    A    10.10.2.21
@ IN    A    10.10.2.22
mx2 IN    A    10.10.2.22

; MX - Mail eXchange records
domain.name.    IN    MX    10    mx1.domain.name.
domain.name.    IN    MX    20    mx2.domain.name.

Где:

2009102801 - (Serial) - последовательность в виде даты с дополнением YYYYMMDDNN (где NN - это количество изменений файла зоны за один день), по которой сервера, извлекающие информацию из нашего NS, понимают, что запись зоны была изменена и обновлена;
604800 - (Refresh) - указание на то, как часто вторичным NS нужно проверять изменения зоны (в секундах);
86400 - (Retry) - указание на то, через какой промежуток времени вторичные сервера могут попытаться соединится с нашим NS при потере связи (в секундах);
2419200 - (Expire) - указывает на то, сколько может быть действительной запись, если нет возможности произвести её обновление или восстановление (в секундах);
604800 - (Minimum or Negative Cache TTL) - указание на то, на которое времени запись может кешированна.

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

Псевдонимы (aliases in canonical name), описываемые с помощью записей "CNAME", мы не будем применять. Вполне допустимо прописывание двух доменных имён, таких как: domian.name и www.domain.name. Я считаю, что совсем ни к чему городить раздельные блоки в разных местах одного и того же конфигурационного файла для описания схожих сущностей, рискуя потерять над ними контроль из-за элементарной невнимательности при правке одного из блоков.

Сочиняем конфигурационные файлы зон обратного отображения для диапазонов адресов локальных "подсетей". Обобщённо, они должны строится по приведённому шаблону:

# vi /etc/bind/master/db.10.10.in-addr.arpa.local

$TTL 3600
; SOA
@  IN  SOA  domain.name.  nsadmin.domain.name. (
  2009102801
  3600
  900
  1209600
  3600
);

; NS - Name Servers
@    IN    NS    ns.local.
@    IN    NS    ns1.local.

; PTR
21.2    IN    PTR    ns.local.
22.2    IN    PTR    ns1.local.

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

# vi /etc/bind/master/db.240-29.202.204.88.in-addr.arpa

$TTL 3600
; SOA
@  IN  SOA  domain.name.  nsadmin.domain.name. (
  2009102801
  3600
  900
  1209600
  3600
);

; NS - Name Servers
@    IN    NS    ns.domain.name.
@    IN    NS    ns1.domain.name.
@    IN    NS    ns2.domain.name.

; PTR
241    IN    PTR    ns.domain.name.
242    IN    PTR    mx1.domain.name.

Стоит иметь в виду, что, в отличие от прямых зон, обратные описывают административную принадлежность хостов, но сами принадлежат оператору сети (как правило, провайдеру). Возникает особого рода затруднение, связанное с работой DNS-сервера уже не во внутренней сети, а в сети Интернет. Дело в том, что "подсети" класса C (так называемые сети /24, в которых сетевая маска занимает 24 (двадцать четыре) бита, а адрес компьютера — 8 (восемь)) выдаются только организациям, способным такую "подсеть" освоить. Чаще всего выдаются меньшие "подсети" — от /30 (на два абонентских адреса) до /27 (на 30 адресов) — или другие диапазоны, сетевая маска которых не выровнена по границе байта. Таких "подсетей" в обратной зоне получится несколько, а возможности просто разделить её, отдав часть адресов в администрирование хозяевам, нет. Грамотный провайдер в таких случаях пользуется RFC2317, предписывающем в обратной зоне заводить не записи вида PTR, а ссылки CNAME на адреса в “классифицированных” обратных зонах специального вида. Обратное преобразование становится двухступенчатым, зато администрирование каждой классифицированной зоны можно отдать хозяину.

Опираясь на вышеописанные шаблоны строим описания наших зон, принимаем делегированные записи зон обратного разрешения имён, строим свои зоны обратного разрешения имён локальных сетей.

Подправим флаги разрешений на право доступа к созданным нами директориям и файлам:

# chown -R bind:bind /etc/bind
# chmod -R o-rx /etc/bind

Проверяем корректность составления файлов конфигурации "Bind9" следующей командой (нужно бы выработать безусловный рефлекс на совершение этого действия после любого проникновения в конфигурационные файлы):

# named-checkconf /etc/bind/named.conf

Проверяем корректность составления файлов конфигурации зоны "Bind9" следующей командой:

# named-checkzone /etc/bind/master/db.domain.name

С учётом того, что мы сменили конфигурацию и ключевой файл утилиты "rndc" перезапустить службу "named" штатным скриптом не получится, "убиваем" службу "named" вручную и запускаем её скриптом:

# /bin/kill `cat /var/run/named/named.pid`
# /etc/init.d/bind9 start

Или, если мы только изменили записи зон:

# /etc/init.d/bind9 reload

Та же команда перезагрузки записей зон, только без скриптовой "обёртки", что было применёно выше:

# /usr/sbin/rndc reload

Проверяем журнал событий "/var/log/syslog" на предмет наличия ошибок.

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

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

# vi /etc/logrotate.d/bind9

/var/log/named/*.log {
  # размер журнального файла, после которого он обрабатывается утилитой
  size 10M
  # отсутствие файла не вызывает ошибку
  missingok
  # количество хранимых отработанных резервных копий
  rotate 10
  # указание сжимать отрабатываемые резервные копии
  compress
  # указание не сжимать первую резервную копию, делать это при повторном проходе
  delaycompress
  # указание не отрабатывать пустые файлы
  notifempty
  # добавлять к наименованию файла резервной копии даты в формате "-YYYYMMDD"
  dateext
  # задать права доступа, владельца и группу создаваемого журнального файла
  create 640 bind bind
}

Проверяем корректность конфигурационного файла:

# logrotate -d /etc/logrotate.d/bind

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


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )