 Яков Коваленко
Яков Коваленко
Split DNS: заставим BIND работать на два фронта!
Вы системный администратор организации, которая использует много внешних адресов и свои DNS-серверы? У вас единое адресное пространство для внешних и внутренних серверов? Вы используете разные DNS-серверы для внутренней и внешней сети? Не стоит так усложнять себе жизнь. Есть способ заставить BIND работать на два фронта!
BIND – DNS-сервер для UNIX. Для воплощения в жизнь информации из этой статьи вам потребуются знания UNIX и BIND на уровне продвинутого пользования.
Что такое Split DNS-конфигурация? Конфигурация BIND, позволяющая использовать различные настройки DNS в зависимости от адреса источника запроса.
Для чего это может быть полезно? Допустим, ваша организация называется «Horns And Hooves inc.» и соответственно доменное имя hornsandhooves.ru. Вероятно, системному администратору покажется удобным назвать логичными и понятными именами все свои серверы и рабочие компьютеры.
Например, сервер разработки dev.hornsandhooves.ru, почтовые серверы – mx1.hornsandhooves.ru и mx2.hornsandhooves.ru, компьютеры сотрудников тоже захочется назвать понятными именами, например bender.hornsandhooves.ru, panikovsky.hornsandhooves.ru и так далее.
Получается, что внутренние компьютеры и внешние серверы объединены общим именным пространством. Это, на первый взгляд, очень удобно при администрировании, но несет в себе дополнительные трудозатраты при администрировании, проблемы с безопасностью и дополнительные финансовые затраты.
Я знаю несколько системных администраторов, которые покупали и настраивали совершенно отдельные DNS-серверы, один для интернет-сервисов, другой для внутренних сервисов. Схема их сети была такой, как на рис. 1. Как видим – DNS разделен на внутренние серверы, которые обеспечивают разрешение имен внутренних сервисов, кэшируют запросы, разрешают имена и делают прочую полезную работу.

Рисунок 1. Модель обычной расстановки DNS-серверов без использования Split DNS
За брандмауэром расположены DNS-серверы для обслуживания зоны hornsandhooves.ru.
Вполне логичная и безопасная схема, но экономически не эффективна и усложнена для администрирования.
Давайте попробуем разобраться, каким образом, используя всего одну пару DNS-серверов, отдавать в Интернет только то, что положено – www-сервер с внешним адресом, DNS-сервер, почтовые серверы, а внутренним клиентам – адреса внутренних серверов и клиентских компьютеров, так называемое «затененное пространство имен», которое показывать в Интернете минимум опасно.
Расщепление пространства имен. Виды
Нам потребуется создать 2 разных файла зоны hornsandhooves.ru: один из них будет содержать информацию для Интернета, второй будет содержать информацию для внутренних клиентов.
Примечание: все доменные имена и IP-адреса вымышлены, совпадения случайны.
В файле зоны ext.hornsandhooves.ru указан минимальный набор серверов, необходимых для того, чтобы компания нормально работала, разрешала свои интернет-имена и принимала почту. При условии, что у регистратора зоны прописаны ваши DNS-серверы как ответственные за зону (см листинг 1).
Листинг 1. Файл ext.hornsandhooves.ru
$TTL 86400
hornsandhooves.ru.      IN     SOA ns1.hornsandhooves.ru. noc.hornsandhooves.ru.
                        (
                        2007032900          ; serial
                        21600               ; refresh (6 hours)
                        1200                ; retry (20 minutes)
                        86400               ; expire (1 day)
                        432000              ; minimum (5 days)
                        )
                        IN     NS           ns1.hornsandhooves.ru.
                        IN     NS           ns2.hornsandhooves.ru.
                        IN     MX     5      mx1.hornsandhooves.ru.
                        IN     MX     10     mx2.hornsandhooves.ru.
                        IN     A            194.0.1.1
www                     IN     A            194.0.1.1
ns1                     IN     A            194.0.1.3
ns2                     IN     A            194.0.1.4
mx1                     IN     A            194.0.1.3
mx2                     IN     A            194.0.1.4
А в файле int.hornsandhooves.ru, кроме внешних интернет-сервисов, но с внутренними адресами, мы видим еще несколько адресов, а именно адреса внутренних сервисов, о которых незачем знать внешнему Интернету, плюс адреса рабочих станций, о которых Интернету знать тоже незачем (см. листинг 2).
Листинг 2. Файл int.hornsandhooves.ru
$TTL 86400
hornsandhooves.ru.      IN     SOA ns1.hornsandhooves.ru. noc.hornsandhooves.ru.
                        (
                        2007032900          ; serial
                        21600               ; refresh (6 hours)
                        1200                ; retry (20 minutes)
                        86400               ; expire (1 day)
                        432000              ; minimum (5 days)
                        )
                        IN     NS           ns1.hornsandhooves.ru.
                        IN     NS           ns2.hornsandhooves.ru.
                        IN     MX     5      mx1.hornsandhooves.ru.
                        IN     MX     10     mx2.hornsandhooves.ru.
                        IN     A            192.168.1.1
www                     IN     A            192.168.1.1
ns1                     IN     A            192.168.1.3
ns2                     IN     A            192.168.1.4
mx1                     IN     A            192.168.1.3
mx2                     IN     A            192.168.1.4
dev                     IN     A            192.168.1.10
gate                    IN     A            192.168.1.11
filesrv                 IN     A            192.168.1.12
dhcp                    IN     A            192.168.1.13
bender                  IN     A            192.168.1.20
panikovsky              IN     A            192.168.1.21
funt                    IN     A            192.168.1.22
shura                   IN     A            192.168.1.23
Итак, мы создали 2 разных файла для зоны, теперь осталось научить BIND отдавать информацию из этих файлов дифференцированно. Зоны обратного отображения тоже должны быть разными.
Конфигурирование named.conf
Для начала разберемся с конфигурацией наших DNS-серверов.
У нас 2 сервера, master и slave. Ns1 и ns2 соответственно. Они по совместительству являются почтовыми серверами, ничто им не мешает заниматься еще и почтой.
В каждом сервере по два сетевых интерфейса. Один имеет внешний IP-адрес (194.0.1.3 для ns1 и 194.0.1.4 для ns2), второй интерфейс имеет адрес из внутренней сети (192.168.1.3 и 192.168.1.4 соответственно).
О конфигурации с одним интерфейсом с внутренним адресом (например, если у вас DMZ) будет сказано в конце статьи.
В BIND 9 есть замечательная возможность создавать Views (виды). В одном View мы расположим зону для Интернета, а в другом – зону для внутренней сети. Назовем их external и internal.
Файл конфигурации named.conf для master-сервера:
options {
        directory "/var/named";
        notify yes;
        pid-file "/var/run/named/named.pid";
        statistics-file "named.stats"; 
};
controls {
        inet 127.0.0.1 allow { localhost; } keys { rndckey; };
};
// Создадим ACL, в котором укажем, что внутренние адреса – подсеть 192.168.1
acl "internals" {192.168.1.0/24; 127.0.0.1/32;};
// Объявляем вид – internal зоны для внутренней сети
view "internal" {
        // Этот вид разрешено просматривать только внутренним клиентам
        match-clients { "internals"; };
        // Обозначим slave-сервер. Только ему разрешим скачивать зону
        allow-transfer {192.168.1.4;};
        // Наш сервер рекурсивен для внутренних клиентов, сам будет узнавать адрес для клиента
        recursion yes;
        //ROOT zone
        zone "." IN {
        type hint;
        file "named.ca";
        };
        //Forward zones
        zone "hornsandhooves.ru" in {
        type master;
        file "forward/int.hornsandhooves.ru";
        };
        //Reverse zone
        zone "1.168.192.in-addr.arpa" in {
        type master;
        file "reverse/1.168.192";
        };
        zone "localhost" IN {
        type master;
        file "localhost.zone";
        allow-update { none; };
        };
        zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "named.local";
        allow-update { none; };
        };
};
// Объявляем вид для внешних запросов
view "external" {
        // К этому виду имеют доступ все
        match-clients {"any"; };
        // Наш сервер не рекурсивен для Интернета
        allow-recursion { localhost; };
        // Укажем внешний адрес slave-сервера
        allow-transfer { 194.0.1.4;};
        //ROOT zone
        zone "." IN {
        type hint;
        file "named.ca";
        };
        //Forward zones
        zone "hornsandhooves.ru" in {
        type master;
        file "forward/ext.hornsandhooves.ru";
        };
        //Reverse zone
        zone "1.0.194.in-addr.arpa" in {
        type master;
        file "reverse/1.0.194";
        };
};
include "/etc/rndc.key";
// Файл можно сгенерировать командой rndc-confgen -a -c /etc/rndc.key
Теперь, если с компьютера из внутренней сети сделать запрос на разрешение имени www.hornsandhooves.ru, то в ответ получим 192.168.1.1, если из Интернета, то получим 194.0.1.1. Если из внутренней сети дать запрос на разрешение имени bender.hornsandhooves.ru, то получим 192.168.1.20, а если из Интернета, то ничего не получим. Вот так наш сервер стал работать на два фронта.
Теперь давайте разберемся со slave-сервером.
Я не буду рассказывать, зачем нужен slave-сервер, но расскажу, как нужно его настроить специальным образом, для того чтобы он правильно синхронизировал зоны.
Специальная настройка заключается в указании серверу, с какого интерфейса надо запрашивать каждый вид. Делается это для того, чтобы сервер не перепутал виды и не скачал внутреннюю зону во внешний View.
Конфигурационный файл named.conf для slave-сервера:
options {
        directory "/var/named";
        notify yes;
        pid-file "/var/run/named/named.pid";
        statistics-file "named.stats"; 
};
controls {
        inet 127.0.0.1 allow { localhost; } keys { rndckey; };
        };
//ACLs
acl "internals" {192.168.1.0/24; 127.0.0.1/32; };
view "internal" {
        match-clients { "internals"; };
        query-source address 192.168.1.4 port 43303;
        recursion yes;
        // Здесь мы как раз указываем, с какого интерфейса запрашиваем передачу зоны.
        // В данном случае – с внутреннего, так как на внутреннем виде, на мастере,
        // трансфер разрешен для внутреннего интерфейса
        transfer-source 192.168.1.4;
        //ROOT zone
        zone "." IN {
        type hint;
        file "named.ca";
        };
        zone "hornsandhooves.ru" in {
        type slave;
        file "slave/int.hornsandhooves.ru";
        masters { 192.168.1.3; };
        };
        zone "localhost" IN {
        type master;
        file "localhost.zone";
        allow-update { none; };
        };
        zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "named.local";
        allow-update { none; };
        };
        //Reverse zone
        zone "1.168.192.in-addr.arpa" in {
        type slave;
        file "reverse/1.168.192";
        masters { 192.168.1.3; };
        };
};
view "external" {
        match-clients {"any"; };
        query-source address 194.0.1.4 port 43303;
        allow-recursion { localhost; };   
        // Здесь мы указываем, что забираем зону с внешнего интерфейса –
        // только для него на мастере внешняя зона отдается
        transfer-source 194.0.1.4;
        //ROOT zone
        zone "." IN {
        type hint;
        file "named.ca";
        };
        //Forward zones
        zone "hornsandhooves.ru" in {
        type slave;
        file "slave/ext.hornsandhooves.ru";
        masters { 194.0.1.3; };
        };
        //Reverse zone
        zone "1.0.194.in-addr.arpa" in {
        type slave;
        file "reverse/1.0.194";
        masters { 194.0.1.3; };
        };
};
include "/etc/rndc.key";
Что получилось в результате?
На рис. 2 схематично представлено, что примерно должно получиться.

Рисунок 2. Модель расстановки DNS-серверов при использовании Split DNS
В результате мы добились экономической эффективности, легкости в администрировании, надежности и безопасности.
Во-первых, вместо четырех серверов у нас всего два.
Во-вторых, изменения нужно вносить только в master-сервер, на slave будут корректно синхронизироваться зоны.
В-третьих, у нас два сервера, полностью взаимозаменяющие друг друга. Если даже один из них сломается, второй полностью возьмет на себя его функцию.
В-четвертых, адреса внутренних ресурсов не видны, так как ограничен просмотр видов и четко определен slave-сервер, которому разрешается скачивать зону.
Такая схема вполне подойдет для малых и средних компаний. На внешних серверах нужно соответствующим образом настроить врапперы и внутренние брандмауэры, дабы усложнить взломщикам жизнь.
Крупным компаниям рекомендуется использовать DMZ для интернет-серверов. С DMZ схема будет немного другая, так как не будет внешнего и внутреннего интерфейса, будет всего один.
Конфигурация с DMZ
Если ваши серверы находятся в DMZ, то у них используются только внутренние DMZ-IP-адреса, которые DMZ-маршрутизатором транслируются во внешние. Как решить проблему скачивания зон на slave-сервере?
Очень просто – поднимите дополнительный интерфейс на slave-сервере (можно alias, например eth0:1) и укажите его как transfer-source для одного из видов. На master-сервере для выбранного вида поставьте разрешение на скачивание, а для второго вида поставьте отказ в доступе. Делается это через acl.
Например:
acl "internals" {!192.168.1.5; 192.168.1.0/24;};
Здесь 192.168.1.5 – дополнительный интерфейс, которым мы будем скачивать external view. Ему не разрешено скачивать internal view (перед адресом стоит восклицательный знак).
Вот такое решение.
Послесловие
Если отбросить UNIX и BIND составляющую прочитанной вами статьи, кстати, спасибо, что дочитали, то информацию можно применить к любому DNS-серверу на любой платформе.
Комментарии и предложения, а также просьбы о разъяснениях непонятных вам деталей, принимаются на электронную почту.
Удачи!