Версия для печати
Вторник, 05 февраля 2019 11:08

Bind 9 - разделение ДНС для разных сетей

Автор
Оцените материал
(37 голосов)

 

В этой статье описана настройка dns bind (view). Данная настройка может пригодиться, где в качестве внешнего и внутреннего dns используется один сервер. И есть необходимость разделить доменную зону (например: test.ru), назначая разные адреса различным сегментам сети.

Для чего это может понадобиться? Для примера, предположим есть почтовый сервер mail.company.ru у которого в интернете опубликован соответствующее имя с привязкой к публичному IP. Физически сервер находится в локальной сети и имеет приватный IP адрес. Необходимо, что бы клиенты в интернете видели имя сервера с публичным IP, а клиенты локальной сети обращались к серверу по приватному IP. Можно конечно пойти путем создания двух имен для сервера и ведения двух зон (приватной и публичной) и почтовые клиенты пользователей внутренней сети отправлять на сервер с внутренним адресом. Но это не удобно мобильным пользователям, которые должны со своими устройствами одинаково работать, как внутри сети, так и на выезде. В данном случае и поможет разделение (split) зон.

 

В качестве примера будет использована ВМ с остановленной ОС Centos 8 в режиме минимальной установки со следующими данными:

  1. ОС - Centos 8
  2. RAM - 1Gb
  3. HDD - 20Gb
  4. Один сетевой интерфейс
  5. Приватный IP - 192.168.0.10
  6. Приватный адрес почтового сервера - 192.168.0.11

Первое, что нам потребуется, установить сервис ДНС на сервер. Устанавливать будем в режиме CHROOT для обеспечения большей надежности и безопасности ДНС сервере.

Установка ДНС сервера в режиме CHROOT

  1. Устанавливаем необходимые пакеты:
    #dnf install bind-chroot
  2. Проверяем установились ли все необходимые пакеты:
    # rpm -qa | grep bind
    bind-license-9.11.20-5.el8.noarch
    bind-libs-lite-9.11.20-5.el8.x86_64
    bind-utils-9.11.20-5.el8.x86_64
    bind-libs-9.11.20-5.el8.x86_64
    bind-chroot-9.11.20-5.el8.x86_64
    bind-export-libs-9.11.20-5.el8.x86_64
    python3-bind-9.11.20-5.el8.noarch
    bind-9.11.20-5.el8.x86_64
  3. Проверяем созданы ли директории для функционирование bind в режиме chroot:
    # ls -l /var/named/chroot/
    итого 0
    drwxr-x---. 2 root named  6 авг 24 20:31 dev
    drwxr-x---. 5 root named 53 ноя 13 11:41 etc
    drwxr-x---. 3 root named 19 ноя 13 11:41 run
    drwxr-xr-x. 4 root root  32 ноя 13 11:41 usr
    drwxr-x---. 5 root named 52 ноя 13 11:41 var
    
  4. Включаем bind в режиме chroot. Все файлы и каталоги, связанные с работой ДНС-сервера будут смонтированы в /var/named/chroot. Сценарий инициализации смонтирует все файлы конфигурации BIND в папку chroot с помощью команды mount --bind, чтобы вы могли управлять конфигурацией за пределами этой среды. Нет необходимости копировать что-либо в каталог /vaк/named/chroot/, потому что он монтируется автоматически.
    # /usr/libexec/setup-named-chroot.sh /var/named/chroot on
  5. Проверяем пути монтирования в /var/named/chroot
    # mount | grep chroot
    /dev/mapper/cs-root on /var/named/chroot/etc/localtime type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/etc/named.root.key type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/etc/named.conf type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/etc/named.rfc1912.zones type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/etc/crypto-policies/back-ends/bind.config type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/etc/protocols type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/etc/services type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/etc/named type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/usr/lib64/bind type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /var/named/chroot/usr/share/GeoIP type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    tmpfs on /var/named/chroot/run/named type tmpfs (rw,nosuid,nodev,seclabel,mode=755)
    /dev/mapper/cs-root on /var/named/chroot/var/named type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
  6. Уточняем IP адрес, который будет использоваться для настройки BIND в среде CHROOT:
    # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 00:0c:29:1b:db:a0 brd ff:ff:ff:ff:ff:ff
        inet 192.168.0.10/24 brd 192.168.0.255 scope global noprefixroute ens32
           valid_lft forever preferred_lft forever
        inet6 fe80::20c:29ff:fe1b:dba0/64 scope link 
           valid_lft forever preferred_lft forever
  7. Настраиваем первоначальную конфигурацию сервера. Открываем файл /etc/named.conf и вносим в него некоторые изменения (выделено красным):
    options {
            listen-on port 53 { 127.0.0.1; any; };
            listen-on-v6 port 53 { ::1; };
            directory       "/var/named";
            dump-file       "/var/named/data/cache_dump.db";
            statistics-file "/var/named/data/named_stats.txt";
            memstatistics-file "/var/named/data/named_mem_stats.txt";
            secroots-file   "/var/named/data/named.secroots";
            recursing-file  "/var/named/data/named.recursing";
            allow-query     { localhost; any; };
            allow-query-cache { localhost; any; };
    
            recursion yes;
    
            dnssec-enable yes;
            dnssec-validation yes;
  8. Добавляем записи для прямой и обратной зоны:
    zone "lab.int" IN {
            type master;
            file "lab.int.zone";
            allow-update { none; };
    };
    zone "0.168.192.in-addr.arpa" IN {
            type master;
            file "lab.int.rzone";
            allow-update { none; };
    };
    Сохраняем и записываем файл конфигурации.
  9. Переходим в каталог /var/named.
  10. Создаем файл прямой зоны lab.int.zone примерно такого содержания:
    ;$ORIGIN .
    
    $TTL 3600
    
    lab.int.     IN      SOA     ns.lab.int. hostmaster.lab.int. (
                                            2020111301      ; serial
                                            1D              ; refresh
                                            1H              ; retry
                                            1W              ; expire
                                            3H )            ; minimum
                    NS      ns.lab.int.
                    A       182.168.0.10
    $ORIGIN lab.int.
    ns      IN      A       192.168.0.10
  11. Создаем файл обратной зоны lab.int.rzone со следующим содержимым:
    ;$ORIGIN .
    
    $TTL 3600
    
    0.168.192.in-addr.arpa.     IN      SOA     ns.lab.int. hostmaster.lab.int. (
                                            2020111301      ; serial
                                            1D              ; refresh
                                            1H              ; retry
                                            1W              ; expire
                                            3H )            ; minimum
                    NS      ns.lab.int.
    $ORIGIN 0.168.192.in-addr.arpa.
    10      IN      PTR     ns.lab.int.
  12. Меняем права и владельца на созданные файлы:
    # chmod 644 lab.int.*
    # chown root:named lab.int.*
  13. Проверяем файл конфигурации:
    # named-checkconf -t /var/named/chroot/ etc/named.conf
  14. Проверяем файлы зон:
    # named-checkzone lab.int /var/named/lab.int.zone 
    zone lab.int/IN: loaded serial 2020111301
    OK
    # named-checkzone 0.168.192.in-addr.arpa /var/named/lab.int.rzone 
    zone 0.168.192.in-addr.arpa/IN: loaded serial 2020111301
    OK
  15. Останавливаем и запрещаем запуск обычного сервиса named:
    # systemctl stop named
    # systemctl disable named
  16. Стартуем сервис в режиме chroot и разрешаем его автозапуск:
    # systemctl start named-chroot
    # systemctl enable named-chroot
    Created symlink /etc/systemd/system/multi-user.target.wants/named-chroot.service → /usr/lib/systemd/system/named-chroot.service.
  17. Приводим файл /etc/resolv.conf (настраиваем сетевой интерфейс) к виду:
    # cat /etc/resolv.conf 
    # Generated by NetworkManager
    search lab.int
    nameserver 192.168.0.10
  18. Разрешаем файрволлу принимать ДНС запросы:
    # firewall-cmd --permanent --add-service=dns
    success
    # firewall-cmd --reload
    success
    ДНС сервер запущен и готов к использованию.

Разделение зон в сервере BIND.

Теперь нам необходимо, что бы сервер выдавал разные адреса на одно и то же имя при поступлении запросов из локальной и внешней сети. Необходимо будет немного переделать файл конфигурации named.conf.

Здесь мы рассмотрим вариант, когда публичная зона располагается на другом (внешнем) сервере, а внутренняя в локальной сети. Причем публичная зона содержит записи по большей части никак не связанные с локальными ресурсами за редким исключением. Например почтовый сервер транслирует свой адрес в глобальную сеть. Нужно организовать доступ к нему из локальной сети по публичному имени, но по приватному адресу. В публичной зоной проблем нет. Запись вносится в соответствующую публичную зону. Ресурс становится доступен из глобальной сети по публичному имени с "белым" адресом. Если ничего не делать, то клиент из локальной сети обращаясь к этому имени ресурса будет получать "белый" адрес и отправлять запросы в соответствии с таблицей маршрутизации. Т.е. в лучшем случае получается: клиент-ядро-пограничный роутер (firewall)-ресурс-ядро-клиент. Мы можем укоротить эту цепочку:  клиент-ядро-ресрс-ядро-клиент. Т.е. весь трафик будет циркулировать только в локальной сети. Для этого используется технология разделение представлений (split view) в ДНС сервере BIND.

  1. Создаем аксесс-листы, описывающие локальную и глобальные сети. Это делается с помощью параметра acl. Для примера вставим несколько записей, что бы был понятен принцип:
    acl "local-subnets" {
            !172.28.131.129;
            127.0.0.0/8;
            172.20.20.0/24;
            172.28.0.0/16;
            10.0.0.0/8;
            192.168.0.0/24;
    };
    Что здесь указано? Адрес 172.28.131.129 по каким то причинам исключен из локальных адресов ( знак "!" перед адресом). Остальные адреса описывают локальные сети, запросы из которых должны попадать в этот ACL и, соответственно, клиенты которых должны получать приватные адреса на запрашиваемый ресурс. Обработка списка идет сверху вниз до первого срабатывания. Таких списков может быть несколько в зависимости от того, что мы хотим отдавать клиентам из разных подсетей.
    1. Далее создаем "представления". Сделаем обработку запросов для внутренней и внешней сети.
      view "internal" {
              match-clients { "local-subnets"; };
              recursion yes;
              include "/etc/named.rfc1912.zones";
              zone "lab.int" IN {
                                 type master;
                                 file "lab.int.zone";
                                 allow-update { none; };
               };
      };
      
      view "external" {
              match-clients {
      #               secondary-dns;
                      any;
              };
              recursion no;
              zone "external.ru" IN {
                                 type master;
                                 file "external.ru.zone";
                                 allow-update { none; };
               };
      };
      В данном примере примере описаны две зоны. Клиент из внутренней сети (192.168.0.Х) попадает в раздел "internal" и получает данные о ресурсах, описанных в файле lab.int.zone для домена lab.int. Запросы от клиентов не попадающих в acl local-subnet попадают в раздел "external" (признак "any") и получают данные для домена external.ru. Домен lab.int они просто не видят. В файле external.ru.zone описываются ресурсы, доступные из глобальной сети. Этот раздел нужен, если наш ДНС сервер должен принимать такие запросы.
    2. Теперь вернемся к нашей изначальной задаччи. Необходимо клиенту из локальной сети выдавать адрес почтового сервера (mail.company.ru) из диапазона приватных адресов. Причем введем дополнительное условие: администратором публичного ДНС является другой администратор и взаимодействие с ним затруднено. Примем к сведению, что в публичной зоне находится очень много записей и они достаточно динамично могут меняться (добавляться). Можно пойти путем добавления в конфиг нашего сервера в раздел view "internal" описания зоны company.ru, создать копию публичной зоны и заменить в нем необходимые адреса на приватные. Но это плохой путь. Придется постоянно следить за изменениями в публичной зоне. Либо руками-глазами, либо городить огород из различных скриптов. Есть более легкий и простой способ.
      Добавим в раздел view internal описание домена третьего уровня mail.company.ru.
      view "internal" {
              match-clients { "local-subnets"; };
              recursion yes;
              include "/etc/named.rfc1912.zones";
              zone "lab.int" IN {
                                 type master;
                                 file "lab.int.zone";
                                 allow-update { none; };
               };
              zone "mail.company.ru" IN {
                                 type master;
                                 file "mail.company.ru.zone";
                                 allow-update { none; };
               };
      };
      

      В файле описания зоны будет присутствовать только один ресурс - наш почтовый сервер с локальным IP адресом. Содержание файла mail.company.ru будет примерно следующим:
      $TTL 3600
      mail.company.ru.   IN      SOA     ns.company.ru. admin.lab.int. (
                                      2020111401 ; serial
                                      3600 ; refresh [1h]
                                      600 ; retry [10m]
                                      3600000 ; expire
                                      3600 ; min TTL [1h]
                                      )
                              NS      ns.lab.int.
                              A       192.168.0.11
      
      
      Таким образом клиент из внутренней сети посылает запрос данных на внутренний ДНС сервер о ресурсе mail.company.ru. Сервер видит, что у него присутствует такая запись и отдает данные, содержащие приватный адрес, клиенту. Если клиент запрашивает данные о другом ресурсе этого домена (например www.company.ru), то локальный сервер не находит в своей базе данных этот ресурс и передает запрос в глобальную сеть, где уже содержутся данные о всех ресурсах домена company.ru. Таким образом мы можем с помощью локального ДНС сервера переназначать адреса для всех ресурсов, находящихся в локальной сети и опубликованных в глобальной сети,

 

Дополнительная информация

Прочитано 7189 раз Последнее изменение Суббота, 14 ноября 2020 12:40
Андрей Иванов

Последнее от Андрей Иванов

Авторизуйтесь, чтобы получить возможность оставлять комментарии