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]

Рисунок 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]

Рисунок 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-серверу на любой платформе.

smag.ru