Настройка DNS-сервера Bind для поддержки внутренних доменов


Для чего все это надо?

При разработке крупных комплексных информационных систем с несколькими Stage-серверами и автоматическим развертываем комплекса под тестирование и разработку фиче-брэнчей обычно используются разного рода системы автодеплоя и взаимодействие внутренних элементов в рамках одного тестового комплекса производится по хитро сформированным доменным именам.

Например:

  • api.stage-r12.usearch
  • api.prod.usearch

Рассмотрим подробнее каждый элемент схемы:

  • usearch - это разрабатываемый проект
  • stage-r12 - соответствующая ветка в GIT-репозитарии (в нескольких репозитариях для каждого фиче-брэнча существует одинаковая ветка)
  • api - имя сервера

Доступ по этим именам фактически происходит в рамках тестового комплекса и с рабочих станций разработкиков, поэтому нам потребуется еще и создать slave-зону в домене Active Directory для взаимодействия с Master-зоной которую мы будем строить на основе DNS-сервера Bind.

Настроим DNS сервер Bind для обслуживания локальной зоны

Сразу говорю, что зоны вида .local использовать нельзя, лучше используйте зоны .vm или чтонибудь из этой серии. Почему нельзя использовать доменную зону .local я уже довольно подробно рассказывал в стать "Устранение проблем с разрешением DNS-имен для домена .local в современных дистрибутивах Linux" и думаю повторяться не стоит, просто не используйте этот домен.

Подготовим виртуальную машину для нашего DNS-сервера.

Создание DNS-сервера на базе Debian Linux

Лучше создать отдельную виртуальную машину под проект, не стоит выделять ей много ресурсов, но пусть она будет изолированная и в моем случае я выделил ей 256 мб оперативной памяти и 16GB диска. Проводим базовую подготовку, за это у меня отвечает ansible который умеет настраивать обновления, часовой пояс, устанавливать базовый набор ПО и еще пачку мелких типовых операций которые хоть и задокументированы, но постоянно забываются, да и вообще в целом скука и рутина.

Итак сервер мы настроили, а следующим этапом у нас будет собственно установка DNS-сервера:

# aptitude install bind9

И пакеты дла поддержки команд nslookup и dig (первый теперь почему то не входит в штатную поставку Debian):

# apt-get install dnsutils

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

Во первых, создадим текстовый файл содержащий описание DNS-зоны, я обычно располагаю их в каталоге конфигурации Bind и называю по имени зоны которую он описывает. У меня получился файл /etc/bind/db.stage.usearch следующего содержания:

$ORIGIN stage.usearch.
@                      8640 SOA   ns1.stage.usearch. (
                              anton.stage.usearch.     ; address of responsible party
                              102110                 ; serial number
                              10800                       ; refresh period
                              3600                        ; retry period
                              604800                     ; expire time
                              3600                     ) ; minimum ttl

; Production
ns1                    3600    IN      A       10.54.8.8
@                      86400   IN      NS      ns1.stage.usearch.
db                     3600    IN      A       10.54.8.4
app                    3600    IN      A       10.54.8.5
php                    3600    IN      A       10.54.8.6

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

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

Глобальный файл конфигурации (/etc/bind/named.conf.options) необходимо привести к следующему виду:

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

        forwarders {
                8.8.8.8;
        };

        dnssec-validation auto;

        auth-nxdomain no;
        listen-on { any; };
        listen-on-v6 { none; };
};

Итак, что я здесь настроил:

  • Отключил прием подключений по IPv6 протоколу
  • Включил прием IPv4 подключений по порту 53 (TCP и UDP) на всех интерфейсах (на внешнем и локальном)
  • Разрешил форвардинг запросов которые не может обслужить этот сервер на DNS Гугла

Сразу же проверим, что форвардинг запросов работает:

# dig A mail.ru @127.0.0.1

В результате вы должны увидеть все A-записи mail.ru:

; <<>> DiG 9.10.3-P4-Debian <<>> A mail.ru @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30490
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 13, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;mail.ru.                       IN      A

;; ANSWER SECTION:
mail.ru.                56      IN      A       94.100.180.202
mail.ru.                56      IN      A       94.100.180.200
mail.ru.                56      IN      A       217.69.139.199
mail.ru.                56      IN      A       217.69.139.202

....

Если все прошло OK, то переходим в следующий глобальный файл конфигурации (/etc/bind/named.conf.local) и в нем то мы уже и описываем обсуживаемую нами зону:

zone "stage.usearch" IN {
    type master;
    file "/etc/bind/db.stage.usearch";
    allow-update { none; };
};

И таких записей можно сделать сколько вам угодно, или вообще лучше генерируйте файлы DNS-зон при помощи систем управления конфигурацией, например Ansible (так будет надежнее) и не забывайте делать reload службе bind для того, чтобы применить изменения (а вы что забыли?):

# systemctl reload bind9

И теперь как говориться наступает момент истины и попробуем спросить у нашего сервера созданные внутренние DNS-имена:

# dig A db.stage.usearch @127.0.0.1

; <<>> DiG 9.10.3-P4-Debian <<>> A db.stage.usearch @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30111
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;db.stage.usearch.              IN      A

;; ANSWER SECTION:
db.stage.usearch.       3600    IN      A       10.54.8.4

;; AUTHORITY SECTION:
stage.usearch.          86400   IN      NS      ns1.stage.usearch.

;; ADDITIONAL SECTION:
ns1.stage.usearch.      3600    IN      A       10.54.8.8

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Mar 21 02:51:07 EDT 2019
;; MSG SIZE  rcvd: 95

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

Настройка Microsoft DNS в качестве Slave-сервера для внутреннего домена

Все, что я выше описывал конечно интересно, но ситуация довольно типовая. Нас же интересует все нестандартное, а главное как я уже говорил выше, мне требуется настроить доступ разработчикам с их рабочих мест до внутреннего домена и проще всего это реализовать создав SLAVE-зону на корпоративном Microsoft DNS-сервере.

Для создания Slave зоны запустите "Мастер создания новой зоны" из оснастки "DNS-сервер" и выберите тип зоны "Дополнительная зона". Дополнительная зона, это в терминологии Microsoft и есть Slave-зона.

Настройка Slave DNS-сервера в Windows

На следующем экране мастера установки укажите имя зоны аналогичное указанному в конфигурационном файле.

Имя DNS-зоны

Прежде чем переходить к следующему этапу нам необходимо модифицировать конфигурационный файл /etc/bind/named.conf.local разрешив трансфоер зоны с Master-сервера:

zone "stage.usearch" IN {
    type master;
    file "/etc/bind/db.stage.usearch";
    allow-update { none; };
    allow-transfer { 127.0.0.1; 10.1.1.200; };
};

Я разрешил трансфер зоны как с Microsoft DNS-сервера, так и с локального хоста, причем второе я сделал исключительно для тестов (если будут проблемы). Не забываем перезапустить службу Bind9 и переходим к следующему экрану мастера настройки. Здесь как вы наверное догадались вам потребуется указать адрес Master-сервера и попытаться загрузить с него данные.

Трансфер DNS-зоны на Microsoft DNS-сервер

Если все прошло успешно, то вы увидите домен в списке обслуживаемых DNS-сервером и он должен "подтянуть данные".

Зона успешно передана на Microsoft DNS-сервер

И вот теперь обратите внимание на одну маленькую, но очень важную деталь, а именно то, что такие домены не синхронизируются через Active Directory и вам необходимо будет проделать эти операции на всех DNS-серверах обслуживающих ваш домен Active Directory.

Автоматическая передача зоны между DNS-сервером Bind и Microsoft DNS-сервер

Как вы наверное помните, я сказал, что описание DNS-зоны не совсем корректное, а именно в нем указан один NS-сервер и сейчас мы укажем в конфигурационном файле все три NS (включая два Microsoft Slave) и в такой конфигурации наш Master-сервер будет знать кому отправлять сведения о том, что данные DNS-зоны обновлены.

Не забудьте так же увеличить серийный номер зоны и выполнить reload службе bind:

$ORIGIN stage.usearch.
@                      8640 SOA   ns1.stage.usearch. (
                              anton.stage.usearch.     ; address of responsible party
                              102115                 ; serial number
                              10800                       ; refresh period
                              3600                        ; retry period
                              604800                     ; expire time
                              3600                     ) ; minimum ttl

; Production
ns1                    3600    IN      A       10.54.8.8
ns2                    3600    IN      A       10.1.1.200
ns3                    3600    IN      A       10.1.1.201
@                      86400   IN      NS      ns1.stage.usearch.
@                      86400   IN      NS      ns2.stage.usearch.
@                      86400   IN      NS      ns3.stage.usearch.
db                     3600    IN      A       10.54.8.4
app                    3600    IN      A       10.54.8.5
php                    3600    IN      A       10.54.8.6

Первую операцию передачи сведений о DNS-зоне (новых NS-серверах) вам правда придется выполнить вручную.

Передача DNS-зоны на Microsoft DNS-сервер вручную

Вот теперь все должно работать как часы.