UMGUM.COM (лучше) 

Конфигурирование Bind 9 ( Конфигурирование сервера доменных имен Bind 9. )

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

OS: Debian Lenny.

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

Конфигурационные файлы, скрипты и структуру дерева директорий сервисов в Debian пишут умные люди, старающиеся унифицировать все по максимуму и предусмотреть обход самых различных конфликтных ситуаций. Все так. Но я предпочитаю не вестись на нововведения, в которых не чувствую острой необходимости; потому мы будем строить несколько упрощённую, "олдскульную" конфигрурацию.

Создаем директории зон типов зон на наших серверах. Конфигурация наших NS смешанная, так что они не будут пустовать:


# mkdir -p /var/lib/named/etc/bind/master
# mkdir -p /var/lib/named/etc/bind/slave

Предпочитаю в корне директории конфигураций оставить файлы зон:

прямого разрешения для loopback (db.localhost);
обратного разрешения для loopback (db.127);
обратного разрешения для широковещательной зоны (db.0);
обратного разрешения для широковещательной зоны (db.255);
обратного разрешения для специальной зоны rfc1918 (db.empty);
корневых серверов для сервиса кеширующего NS (db.root).

Все остальные конфигурационные файлы удалим и создадим свои собственные.

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

# mkdir -p /var/lib/named/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. С указанием типа устройства, с которого снимаем "случайные" данные при генерации ключа есть свой нюанс; устройство /dev/random, с которым "по умолчанию" работает утилита dnssec-keygen не всегда корректно настроено да ещё и работает "на выдачу" только тогда, когда собирается действительно достаточно случайных данных от "окружающих устройств"; а вот устройство /dev/urandom добавляет в случае необходимости свой "шумовой фон" и отрабатывает гораздо быстрее и не так сильно зависит от настроек, как /dev/random, хоть и выдает "менее случайные" данные.

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

Создадим конфигурационные файлы описания ключей подписания транзакций в директории "/var/lib/named/etc/bind/key/":

# touch /var/lib/named/etc/bind/key/ns.local.key
# touch /var/lib/named/etc/bind/key/ns1.local.key

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

# cat /var/lib/named/etc/bind/key/ns.local.key

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

# cat /var/lib/named/etc/bind/key/ns1.local.key

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

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

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

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

Создаем файл "/var/lib/named/etc/bind/rndc.key":

# touch /var/lib/named/etc/bind/rndc.key

Размещаем в нем следующее:

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

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

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

Создаем или доводим имеющийся конфигурационный файл опций службы named "/var/lib/named/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/run/bind/named.dump";
  statistics-file       "/var/run/bind/named.stats";
  version               "0.0"; # слабая попытка ввести в недоумение начинающих "хацкеров"
  port                  53;
  listen-on             { any; }; # служба слушает и отвечает на всех интерфейсах
  listen-on-v6          { none; }; # шестую версию TCP использовать пока не будем, все равно некому воспользоваться
  recursion             yes;
  allow-recursion       { any; }; # разрешаем всем рекурсивные запросы через нас, не жалко
  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.log" versions 3 size 1024k;
    severity info;
    print-time yes;
    print-category yes;
  };

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

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

Создаем или доводим имеющийся конфигурационный файл службы NS "/var/lib/named/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; };

  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;
    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; };

  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;
    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;
    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;
    file "/etc/bind/slave/db.10.10.in-addr.arpa";
    masters { 10.10.2.21; };
  };

};

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

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

# cat /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. Я считаю, что совсем ни к чему городить раздельные блоки в разных местах одного и того же конфигурационного файла для описания схожих сущностей, рискуя потерять над ними контроль из-за элементарной невнимательности при правке одного из блоков.

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

# cat /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.

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

# cat /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 /var/lib/named/etc/bind/*

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

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

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

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

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

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

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

# /etc/init.d/bind9 reload

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

# /usr/sbin/rndc reload

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

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


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


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