Умный DNS — это DNS, который отдает разные адреса, в зависимости от адреса клиента.
Представьте ситуацию — у вас есть какая то локальная сеть, есть какой то ресурс или доменное имя, и вы хотите, что бы клиентам из локальной сети возвращался локальный адрес ресурса, а клиентам из интернета — внешний.
Первое что приходит на ум — поднять 2 DNS сервера, один — для внешних клиентов, другой для внутренних. Но допустим, в вашей внутренней сети несколько подсетей и для каждой нужно отдавать свои ответы — поднимать кучу серверов? Или весьма проблематично или невозможно изменить используемые клиентами DNS адреса в настройках клиентских устройств?
В общем задался я этим вопросом и нашел весьма простое и интересное решение — использовать DNS сервер bind9, и для него использовать ACL списки.
Начальные данные
Имеем сервер:
- Ubuntu Server 18.04;
- isc-dhcp-server;
- bind9;
- настроен nat.
Как все это установить и настроить читаем в данной статье.
Обновление системы
И как всегда первым делом обновим нашу систему:
sudo apt update
sudo apt dist-upgrade -y
Создадим папки для хранения конфигураций для локальных и внешних клиентов:
sudo mkdir /etc/bind/local
sudo mkdir /etc/bind/inet
Создадим конфигурацию зон:
sudo nano /etc/bind/local/db.dom
Соответственно db.dom замените на ваш домен.
Содержимое файла должно быть примерно таким:
$ORIGIN .
$TTL 604800
dom IN SOA ns1.dom. root.ns1.dom. (
2018041007 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ; Negative Cache TTL
)
@ NS ns1.dom.
@ A 10.5.5.1
$ORIGIN dom.
$TTL 604800
ns1 A 10.5.5.1
10.5.5.1 — внутренний адрес ресурса
sudo nano /etc/bind/inet/db.dom
Содержимое файла:
$ORIGIN .
$TTL 604800
dom IN SOA ns1.dom. root.ns1.dom. (
2018041007 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ; Negative Cache TTL
)
@ NS ns1.dom.
@ A 11.22.33.44
$ORIGIN dom.
$TTL 604800
ns1 A 11.22.33.44
11.22.33.44 — внешний адрес ресурса.
Дальше отредактируем конфигурационный файл bind для того, чтобы он возвращал правильный адрес ресурса клиентам:
nano /etc/bind/named.conf.local
Приводим содержимое этого файла к следующему виду:
acl lan {
127.0.0.0/8;
10.5.5.0/24;
};
view lan {
match-clients { lan; };
recursion yes;
zone "." {type hint; file "/etc/bind/db.root";};
zone "localhost" {type master; file "/etc/bind/db.local";};
zone "127.in-addr.arpa" {type master; file "/etc/bind/db.127";};
zone "0.in-addr.arpa" {type master; file "/etc/bind/db.0";};
zone "255.in-addr.arpa" {type master; file "/etc/bind/db.255";};
zone "dom" {type master; file "/etc/bind/local/db.dom";};
};
view "inet" {
match-clients { any; };
recursion no;
zone "dom" {type master; file "/etc/bind/inet/db.dom";};
};
- acl lan — наш список IP адресов, таких списков может быть несколько. В этой секции мы указываем адреса или сети, для которых хотим отдавать локальный адрес ресурса.
- view «lan» — обработка для локальных клиентов сети lan.
- view «inet» — обработка для всех остальных клиентов, которые не входят в список lan.
Еще обратите внимание на параметр recursion no; и recursion yes;. Будьте внимательны, включенные рекурсивные запросы могут использоваться для различных атак с использованием вашего сервера. Если вы не планируете прописывать ваш DNS сервер клиентам — лучше отключите рекурсивные запросы.
Так же неплохо было бы включить логи для нашего DNS сервера, это необязательно, и даже наверное лучше после тестирования выключить. В общем набираем:
mkdir -p /var/log/named/
cd /var/log/named
touch ./misc.log ./query.log
chmod -R 664 /var/log/named/
chown -R bind:bind /var/log/named/
Приводим файл named.conf к следующему виду:
nano /etc/bind/named.conf
logging {
channel "misc" {file "/var/log/named/misc.log" versions 4 size 4m; print-time YES; print-severity YES; print-category YES;};
channel "query" {file "/var/log/named/query.log" versions 4 size 4m; print-time YES; print-severity NO; print-category NO;};
category default {"misc";};
category queries {"query";};
};
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
//include "/etc/bind/named.conf.default-zones";
Мы включили логирование, а так же отключили стандартные зоны (обратите внимание на строчку //include «/etc/bind/named.conf.default-zones»;, т.к. мы их прописали в файле named.conf.local, их в данной конфигурации нужно выключать обязательно.
Перезапускаем bind:
/etc/init.d/bind9 restart
Проверяем, что он запустился без ошибок:
systemctl status bind9
Он должен быть в статусе active:
Active: active (running)
После этого можно проверять — для адресов указанных в acl будут возвращаться одни адреса, для всех остальных другие.
Тут есть один нюанс — запрос на ваш сервер будет приходить с адресов DNS серверов, которые указаны у клиента, а не непосредственно с клиентского адреса. Т.е. если у клиента прописаны гугловские DNSы, то и запросы на ваш сервер будут приходить с гугловых серверов, учитывайте это.
Ошибки в логах DNS
Если во время настройки клиента возникли какие-либо ошибки, вы увидите их. К примеру, часто случается такая ошибка:
resolving 'sns-pb.isc.org/AAAA/IN': 2001:500:f::1#53
Jun 25 13:16:23 cache named[2004]: error (network unreachable)
resolving 'ns3.nic.fr/A/IN': 2a00:d78:0:102:193:176:144:22#53
Это значит, что сервер пытается разрешить данные IPv6, но он не настроен для поддержки IPv6. Чтобы устранить ошибку, нужно настроить Bind для обслуживания только IPv4.
Откройте /etc/default/bind9:
sudo nano /etc/default/bind9
Найдите параметр OPTIONS и добавьте в него флаг -4, чтобы настроить поддержку только IPv4.
OPTIONS="-u bind -4"
Сохраните и закройте файл.
Перезапустите сервер:
sudo service bind9 restart
После этого в логах не должно быть данных ошибок.
Проверка DNS сервера в Ubuntu | Debian
Набираем в терминале:
nslookup ns1
должны получить ответ:
Server: 10.5.5.1
Address: 10.5.5.1#53
Name: ns1.dom
Address: 10.5.5.1
Если отображается адрес 127.0.0.1, то необходимо в файле resolv.conf прописать dns сервер.
sudo nano /etc/resolv.conf
Прописываем наш dns сервер
nameserver 10.5.5.1
[endtxt]