В качестве примера будет использована ВМ с остановленной ОС Centos 8 в режиме минимальной установки со следующими данными:
- ОС - Centos 8
- RAM - 1Gb
- HDD - 20Gb
- Один сетевой интерфейс
- Приватный IP - 192.168.0.10
- Приватный адрес почтового сервера - 192.168.0.11
Первое, что нам потребуется, установить сервис ДНС на сервер. Устанавливать будем в режиме CHROOT для обеспечения большей надежности и безопасности ДНС сервере.
Установка ДНС сервера в режиме CHROOT
- Устанавливаем необходимые пакеты:
#dnf install bind-chroot
- Проверяем установились ли все необходимые пакеты:
# 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
- Проверяем созданы ли директории для функционирование 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
- Включаем bind в режиме chroot. Все файлы и каталоги, связанные с работой ДНС-сервера будут смонтированы в
/var/named/chroot
. Сценарий инициализации смонтирует все файлы конфигурации BIND в папку chroot с помощью команды mount --bind, чтобы вы могли управлять конфигурацией за пределами этой среды. Нет необходимости копировать что-либо в каталог/vaк/named/chroot/
, потому что он монтируется автоматически.# /usr/libexec/setup-named-chroot.sh /var/named/chroot on
- Проверяем пути монтирования в
/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)
- Уточняем 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
- Настраиваем первоначальную конфигурацию сервера. Открываем файл
/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;
- Добавляем записи для прямой и обратной зоны:
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; }; };
Сохраняем и записываем файл конфигурации. - Переходим в каталог
/var/named
. - Создаем файл прямой зоны
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
- Создаем файл обратной зоны
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.
- Меняем права и владельца на созданные файлы:
# chmod 644 lab.int.* # chown root:named lab.int.*
- Проверяем файл конфигурации:
# named-checkconf -t /var/named/chroot/ etc/named.conf
- Проверяем файлы зон:
# 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
- Останавливаем и запрещаем запуск обычного сервиса named:
# systemctl stop named # systemctl disable named
- Стартуем сервис в режиме 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.
- Приводим файл /etc/resolv.conf (настраиваем сетевой интерфейс) к виду:
# cat /etc/resolv.conf # Generated by NetworkManager search lab.int nameserver 192.168.0.10
- Разрешаем файрволлу принимать ДНС запросы:
# firewall-cmd --permanent --add-service=dns success # firewall-cmd --reload success
ДНС сервер запущен и готов к использованию.
Разделение зон в сервере BIND.
Теперь нам необходимо, что бы сервер выдавал разные адреса на одно и то же имя при поступлении запросов из локальной и внешней сети. Необходимо будет немного переделать файл конфигурации named.conf
.
Здесь мы рассмотрим вариант, когда публичная зона располагается на другом (внешнем) сервере, а внутренняя в локальной сети. Причем публичная зона содержит записи по большей части никак не связанные с локальными ресурсами за редким исключением. Например почтовый сервер транслирует свой адрес в глобальную сеть. Нужно организовать доступ к нему из локальной сети по публичному имени, но по приватному адресу. В публичной зоной проблем нет. Запись вносится в соответствующую публичную зону. Ресурс становится доступен из глобальной сети по публичному имени с "белым" адресом. Если ничего не делать, то клиент из локальной сети обращаясь к этому имени ресурса будет получать "белый" адрес и отправлять запросы в соответствии с таблицей маршрутизации. Т.е. в лучшем случае получается: клиент-ядро-пограничный роутер (firewall)-ресурс-ядро-клиент. Мы можем укоротить эту цепочку: клиент-ядро-ресрс-ядро-клиент. Т.е. весь трафик будет циркулировать только в локальной сети. Для этого используется технология разделение представлений (split view) в ДНС сервере BIND.
- Создаем аксесс-листы, описывающие локальную и глобальные сети. Это делается с помощью параметра
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 и, соответственно, клиенты которых должны получать приватные адреса на запрашиваемый ресурс. Обработка списка идет сверху вниз до первого срабатывания. Таких списков может быть несколько в зависимости от того, что мы хотим отдавать клиентам из разных подсетей.- Далее создаем "представления". Сделаем обработку запросов для внутренней и внешней сети.
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
описываются ресурсы, доступные из глобальной сети. Этот раздел нужен, если наш ДНС сервер должен принимать такие запросы. - Теперь вернемся к нашей изначальной задаччи. Необходимо клиенту из локальной сети выдавать адрес почтового сервера (
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
. Таким образом мы можем с помощью локального ДНС сервера переназначать адреса для всех ресурсов, находящихся в локальной сети и опубликованных в глобальной сети,
- Далее создаем "представления". Сделаем обработку запросов для внутренней и внешней сети.