Привет. Представьте ситуацию — у вас есть какая то локальная сеть, есть какой то ресурс или доменное имя, и вы хотите, что бы клиентам из локальной сети возвращался локальный адрес ресурса, а клиентам из интернета — внешний.
Первое что приходит на ум — поднять 2 DNS сервера, один — для внешних клиентов, другой для внутренних. Но допустим, в вашей внутренней сети несколько подсетей и для каждой нужно отдавать свои ответы — поднимать кучу серверов? Или весьма проблематично или не возможно изменить используемые клиентами DNS адреса в настройках клиентских устройств?
В общем задался я этим вопросом и нашел весьма простое и интересное решение — использовать DNS сервер bind9, и для него использовать ACL списки. О том как это сделать — читайте ниже.
Как всегда у меня установлена чистая Ubuntu Server 16.04.
И как всегда зайдем в режим суперпользователя и обновим нашу систему:
sudo su
apt update
apt upgrade
Далее уставим bind9:
apt install bind9
После установки создадим папки для хранения конфигураций для локальных и внешних клиентов:
mkdir /etc/bind/internals
mkdir /etc/bind/externals
Создадим конфигурации зон:
nano /etc/bind/internals/test.loc
Соответсвенно test.loc замените на ваш домен. Содержимое файла должно быть примерно таким:
; test.loc
$TTL 604800
@ IN SOA ns1.test.loc. root.test.loc. (
2006020201 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800); Negative Cache TTL
;
@ IN NS ns1
IN A 192.168.1.201
ns1 IN A 1.2.3.4
* IN A 192.168.1.201
@ IN A 192.168.1.201
192.168.1.201 — внутренний адрес ресурса, 1.2.3.4 — реальный адрес dns сервера.
nano /etc/bind/externals/test.loc
Содержимое файла:
; test.loc
$TTL 604800
@ IN SOA ns1.test.loc. root.test.loc. (
2006020201 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800); Negative Cache TTL
;
@ IN NS ns1
IN A 1.2.3.5
ns1 IN A 1.2.3.4
* IN A 1.2.3.5
@ IN A 1.2.3.5
1.2.3.5 — внешний адрес ресурса.
Дальше отредактируем кофигурационный файл bind для того что бы он возращал правльный адрес ресурса клиентам:
nano /etc/bind/named.conf.local
Приводим содержимое этого файла к следующему виду:
acl internals {
127.0.0.0/8;
192.168.1.121/32;
};
view «internal» {
match-clients { internals; };
recursion yes;
zone «test.loc» {
type master;
file «/etc/bind/internals/test.loc»;
};
};
view «external» {
match-clients { any; };
recursion no;
zone «test.loc» {
type master;
file «/etc/bind/externals/test.loc»;
};
};
Здесь — acl internals — собственно наш список доступ, таких списков может быть несколько. В этой секции мы указываем адреса или сети, для которых хотим отдавать локальный адрес ресурса.
view «internal» — обработка для клиентов, которые входят в список internals.
view «external» — обработка для всех остальных клиентов.
Еще обратите внимание на параметр — recursion no; и recursion yes; Будьте внимательны, включенные рекурсивные запросы могут использоваться для различных атак с использованием вашего сервера. Если вы не планируете прописывать ваш DNS сервер клиентам — лучше отключите рекурсивные запросы.
Так же не плохо было бы включить логи для нашего DNS сервера, это необязательно, и даже наверное лучше после тестирования выключить. В общем набираем:
mkdir /var/log/named/
touch /var/log/named/misc.log
touch /var/log/named/query.log
chmod 664 /var/log/named/*
chown bind:bind /var/log/named/*
nano /etc/bind/named.conf
Приводим файл 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»;), их в данной конфигурации нужно выключать независимо от того, включите вы логи или нет.
Перезапускаем bind:
/etc/init.d/bind9 restart
Удостоверяемся, что он запустился без ошибок:
systemctl status bind9
Он должен быть в статусе active:
После этого можно проверять — для адресов указаных в acl будут возвращаться одни адреса, для других адресов другие.
Тут есть один нюанс — запрос на ваш сервер будет приходить с адресов DNS серверов, которые указаны у клиента, а не непосредственно с клиентского адреса. Т.е. если у клиента прописаны гугловые DNSы, то и запросы на ваш сервер будут приходить с гугловых серверов, учитывайте это.

