Ниже описывается установка DNS сервера BIND (Berkeley Internet Name Domain) на AWS EC2 в VPC + два дополнительных инстанса в разных подсетях (А и В), после чего на нём реализуем следующее:
- DNS round-robin Load Balancer — будет распределять трафик по очереди на каждый из двух дополнительных интансов
- DNS network-based routing — тут задача интереснее:
- если запрос приходит из подсети A — возвращаем адрес из подсети A
- если запрос приходит из подсети B — возвращаем адрес из посети B
- всем остальным — возвращаем «общий» IP
Практического смысла во второй части особо нет, особенно если дело касается AWS, но для «поиграться» с DNS «маршрутизацией» на основе сети клиента — подойдёт.
Когда-то аналогично выполнялась настройка GeoIP маршрутизации через BIND — для второй части используем точно такой же подход: view
и match-clinets
.
Содержание
DNS AWS
Лирическое отступление, касающееся DNS network-based routing и AWS.
У Amazon для раздачи разных IP используется другой подход: в VPC создаётся свой DNS (если указана опция enableDnsSupport
, по умолчанию она True), и DNS запросы внутри этой VPC направляются на него (см. DNS Support in Your VPC и Amazon DNS Server).
Далее этот DNS указывается в resolv.conf
EC2 интанса самим AWS во время запуска EC2 в VPC:
[simterm]
admin@ip-10-0-1-246:~$ cat /etc/resolv.conf | grep name nameserver 10.0.0.2
[/simterm]
Поэтому при запросе DNS с EC2 — будет использован приватный IP:
[simterm]
root@ip-10-0-1-157:/home/admin# dig ec2-34-253-58-71.eu-west-1.compute.amazonaws.com +short 10.0.1.157 root@ip-10-0-1-157:/home/admin# dig @10.0.0.2 ec2-34-253-58-71.eu-west-1.compute.amazonaws.com +short 10.0.1.157
[/simterm]
А «через мир», например DNS Google — внешний:
[simterm]
root@ip-10-0-1-157:/home/admin# dig @8.8.8.8 ec2-34-253-58-71.eu-west-1.compute.amazonaws.com +short 34.253.58.71
[/simterm]
т.к. Google получает информацию о зонах с authority servers, которые для доменов Amazon-а являются… DNS серверами Amazon-а, которые и возвращают публичный IP.
Проверим: находим Authority Section для домена eu-west-1.compute.amazonaws.com, который содержит нашу запись ec2-34-253-58-71.eu-west-1.compute.amazonaws.com:
[simterm]
$ dig eu-west-1.compute.amazonaws.com +noall +authority ; <<>> DiG 9.12.0 <<>> eu-west-1.compute.amazonaws.com +noall +authority ;; global options: +cmd eu-west-1.compute.amazonaws.com. 872 IN SOA dns-external-master.amazon.com. root.amazon.com. 2013095035 28800 900 604800 7207
[/simterm]
И проверяем значение IN A
, который отдаёт dns-external-master.amazon.com (и который в результате попадает в DNS Google и нашего провайдера):
[simterm]
14:28:28 [setevoy@setevoy-arch-work ~] $ dig @dns-external-master.amazon.com ec2-34-253-58-71.eu-west-1.compute.amazonaws.com +short 34.253.58.71
[/simterm]
Понятно, что запрос с EC2 напрямую (через @ns.name.tld) к тому же DNS вернёт тот же результат:
[simterm]
root@ip-10-0-1-157:/home/admin# dig @dns-external-master.amazon.com ec2-34-253-58-71.eu-west-1.compute.amazonaws.com +short 34.253.58.71
[/simterm]
Создание сервисов
Для начала развернём тестовое окружение, которое будет включать в себя 3 EC2 — один для DNS, и два в роли клиентов, и VPC с тремя подсетями — для DNS и для клиентов.
Подсети все будут публичными, потому обойдёмся без NAT Gateway.
VPC
Создаём VPC:
[simterm]
$ aws ec2 create-vpc --cidr-block 10.0.0.0/16
[/simterm]
Добавляем тег Name:
[simterm]
$ aws ec2 create-tags --resources vpc-13951475 --tags Key=Name,Value=DNStest
[/simterm]
Проверяем:
[simterm]
$ aws ec2 describe-vpcs --vpc-ids vpc-13951475 --query 'Vpcs[*].Tags' --output text Name DNStest
[/simterm]
Security Group
Обновляем Security Group этой VPC — открываем 22 TCP:
[simterm]
$ aws ec2 authorize-security-group-ingress --group-id sg-69520913 --protocol tcp --port 22 --cidr 194.***.***.45/24
[/simterm]
53 UDP и TCP для BIND отовсюду (т.к. мы будем обслуживать собственню зону, и нам надо будет её отдавать другим DNS):
[simterm]
$ aws ec2 authorize-security-group-ingress --group-id sg-69520913 --protocol udp --port 53 --cidr 0.0.0.0/0 $ aws ec2 authorize-security-group-ingress --group-id sg-69520913 --protocol tcp --port 53 --cidr 0.0.0.0/0
[/simterm]
Subnets
Создаём подсеть для ЕС2 с BIND:
[simterm]
$ aws ec2 create-subnet --vpc-id vpc-13951475 --cidr-block 10.0.1.0/24
[/simterm]
Тег:
[simterm]
$ aws ec2 create-tags --resources subnet-48657413 --tags Key=Name,Value=DNStestBINDnet
[/simterm]
Аналогично добавляем ещё две подсети для клиентов:
[simterm]
$ aws ec2 create-subnet --vpc-id vpc-13951475 --cidr-block 10.0.2.0/24 $ aws ec2 create-tags --resources subnet-817e6fda --tags Key=Name,Value=DNStestSubnetA $ aws ec2 create-subnet --vpc-id vpc-13951475 --cidr-block 10.0.3.0/24 $ aws ec2 create-tags --resources subnet-c2776699 --tags Key=Name,Value=DNStestSubnetB
[/simterm]
Internet Gateway
Добавляем Internet Gateway:
[simterm]
$ aws ec2 create-internet-gateway $ aws ec2 create-tags --resources igw-c1690ca6 --tags Key=Name,Value=DNStestIGW
[/simterm]
Подключаем IGW к VPC:
[simterm]
$ aws ec2 attach-internet-gateway --internet-gateway-id igw-c1690ca6 --vpc-id vpc-13951475
[/simterm]
Route Table
Добавляем таблицу маршрутизации:
[simterm]
$ aws ec2 create-route-table --vpc-id vpc-13951475 $ aws ec2 create-tags --resources rtb-cdbf63b4 --tags Key=Name,Value=DNStestRTB
[/simterm]
Добавляем правило маршрутизации в эту таблицу — весь трафик к 0.0.0.0 через IGW, созданный ранеее:
[simterm]
$ aws ec2 create-route --route-table-id rtb-cdbf63b4 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-c1690ca6
[/simterm]
Подключаем эту таблицу к подсетям:
[simterm]
$ aws ec2 associate-route-table --route-table-id rtb-cdbf63b4 --subnet-id subnet-48657413 $ aws ec2 associate-route-table --route-table-id rtb-cdbf63b4 --subnet-id subnet-817e6fda $ aws ec2 associate-route-table --route-table-id rtb-cdbf63b4 --subnet-id subnet-c2776699
[/simterm]
EC2
Создаём инстансы.
Для BIND:
[simterm]
$ aws ec2 run-instances --image-id ami-913a40e8 --count 1 --instance-type t2.nano --key-name rtfm-dev --subnet-id subnet-48657413 --associate-public-ip-address --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=BINDtestServer}]'
[/simterm]
Клиент в посети А:
[simterm]
$ aws ec2 run-instances --image-id ami-913a40e8 --count 1 --instance-type t2.nano --key-name rtfm-dev --subnet-id subnet-817e6fda --associate-public-ip-address --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=BINDtestClientA}]'
[/simterm]
Клиент B:
[simterm]
$ aws ec2 run-instances --image-id ami-913a40e8 --count 1 --instance-type t2.nano --key-name rtfm-dev --subnet-id subnet-c2776699 --associate-public-ip-address --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=BINDtestClientB}]'
[/simterm]
Подключаемся, проверяем сеть:
[simterm]
$ ssh -i rtfm-dev.pem [email protected] admin@ip-10-0-1-157:~$ ping ya.ru -c 1 PING ya.ru (87.250.250.242) 56(84) bytes of data. 64 bytes from ya.ru (87.250.250.242): icmp_seq=1 ttl=36 time=44.4 ms --- ya.ru ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 44.424/44.424/44.424/0.000 ms
[/simterm]
ОК — можно приступать к установке BIND.
Установка BIND
Наш BIND будет авторитарным (authoritative) сервером для домена bindtest.rtfm.co.ua, и рекурсивным (или resolving) сервером для клиентов А и В.
«Поняслася!» (с)
Устанавливаем BIND:
[simterm]
root@ip-10-0-1-157:/home/admin# apt update && apt -y install bind9 bind9utils bind9-doc
[/simterm]
Редактируем /etc/bind/named.conf.options
, добавляем ACL, который будет содержать сервера, с которых будут разрешены рекурсивные запросы (сам сервер, и клиенты А и В).
Перед options
добавляем ACL «trusted»:
acl "trusted" { 10.0.1.157; # current host 10.0.2.145; # ClientA 10.0.3.164; # ClientB };
В сам блок options
добавляем:
... recursion yes; # enables resursive queries allow-recursion { trusted; }; # allows recursive queries from "trusted" clients listen-on { 10.128.10.11; }; # ns1 private IP address - listen on private network only allow-transfer { none; }; # disable zone transfers by default ...
В конце добавляем логгирование, в результате весь файл сейчас выглядит так:
acl "trusted" { 10.0.1.157; # current host 127.0.0.1; 10.0.2.145; # ClientA 10.0.3.164; # ClientB }; options { directory "/var/cache/bind"; dnssec-validation auto; auth-nxdomain no; # conform to RFC1035 listen-on-v6 { any; }; recursion yes; # enables resursive queries allow-recursion { trusted; }; # allows recursive queries from "trusted" clients allow-transfer { none; }; # disable zone transfers by default allow-query { any; }; # disable built-in server information version none; hostname none; server-id none; }; logging { channel b_query { file "/var/log/bind9/query.log" versions 2 size 1m; print-time yes; severity info; }; category queries { b_query; }; };
Создаём каталог для логов:
[simterm]
root@ip-10-0-1-157:/etc/bind# mkdir /var/log/bind9 && chown bind:bind /var/log/bind9
[/simterm]
Проверяем конфиг:
[simterm]
root@ip-10-0-1-157:/etc/bind# named-checkconf
[/simterm]
Добавляем BIND в автозапуск:
[simterm]
root@ip-10-0-1-157:/etc/bind# systemctl enable bind9 Synchronizing state of bind9.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable bind9
[/simterm]
Перезапускаем сервис:
[simterm]
root@ip-10-0-1-157:/etc/bind# systemctl restart bind9
[/simterm]
Проверяем:
[simterm]
root@ip-10-0-1-157:/etc/bind# netstat -anp | grep named tcp 0 0 10.0.1.157:53 0.0.0.0:* LISTEN 1782/named tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1782/named tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN 1782/named tcp6 0 0 :::53 :::* LISTEN 1782/named tcp6 0 0 ::1:953 :::* LISTEN 1782/named udp 0 0 10.0.1.157:53 0.0.0.0:* 1782/named udp 0 0 127.0.0.1:53 0.0.0.0:* 1782/named udp6 0 0 :::53 :::* 1782/named
[/simterm]
Пробуем запрос:
[simterm]
root@ip-10-0-1-157:/etc/bind# dig @localhost ya.ru +short 87.250.250.242
[/simterm]
Лог:
[simterm]
root@ip-10-0-1-157:/etc/bind# tail /var/log/bind9/query.log 21-Mar-2018 13:41:14.014 client 127.0.0.1#40641 (ya,ru): query: ya.ru IN A +E (127.0.0.1)
[/simterm]
ОК, тут всё готово.
Настройка Authoritative сервера
Наш BIND работает на EC2, на IP которого через CNAME
направлены домены ns1-example.rtfm.co.ua и ns2-example.rtfm.co.ua (потребуется два, что бы добавить новый субдомен у регистратора):
[simterm]
14:42:19 [setevoy@setevoy-arch-work ~] $ dig ns1-example.rtfm.co.ua +short ec2-34-253-58-71.eu-west-1.compute.amazonaws.com. 34.253.58.71
[/simterm]
Это будут Name Servers для нашего bindtest.rtfm.co.ua, над которым мы будем «проводить эксперименты».
Сами домены ns1-example.rtfm.co.ua и ns2-* обслуживаются серверами регистратора — Freehost.ua:
[simterm]
16:24:05 [setevoy@venti ~] $ whois rtfm.co.ua | grep "Name Server" Name Server:DELTA.FREEHOST.COM.UA Name Server:ALPHA.FREEHOST.COM.UA Name Server:BETA.FREEHOST.COM.UA Name Server:GAMMA.FREEHOST.COM.UA
[/simterm]
Добавление зоны в BIND
Редактируем /etc/bind/named.conf.local
, добавляем указание на домен (зону), который мы будем обслуживать:
zone "bindtest.rtfm.co.ua" { type master; file "/etc/bind/zones/db.bindtest.rtfm.co.ua"; };
Создаём каталог:
[simterm]
root@ip-10-0-1-157:/etc/bind# mkdir /etc/bind/zones/
[/simterm]
В нём создаём файл зоны — копируем файл /etc/bind/db.local
:
[simterm]
root@ip-10-0-1-157:/etc/bind# cp /etc/bind/db.local /etc/bind/zones/db.bindtest.rtfm.co.ua
[/simterm]
Редактируем /etc/bind/zones/db.bindtest.rtfm.co.ua
, меняем SOA с записи вида:
@ IN SOA localhost. root.localhost. (
На:
@ IN SOA bindtest.rtfm.co.ua. ns1-example.rtfm.co.ua. (
Тут bindtest.rtfm.co.ua — домен, который мы будем обслуживать, а ns1-example.rtfm.co.ua — FQDN нашего ЕС2 с BIND-ом, он и будет Start of authority для bindtest.rtfm.co.ua.
Обновляем остальную информацию, не забываем увеличивать поле Serial на единицу при каждому изменении.
Приводим его к виду:
$TTL 604800 @ IN SOA bindtest.rtfm.co.ua. ns1-example.rtfm.co.ua. ( 3 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns1-example.rtfm.co.ua. @ IN NS ns2-example.rtfm.co.ua. @ IN A 34.253.58.71
Проверяем конфиги:
[simterm]
root@ip-10-0-1-157:/etc/bind# named-checkconf
[/simterm]
Проверяем файл зоны:
[simterm]
root@ip-10-0-1-157:/etc/bind# named-checkzone bindtest.rtfm.co.ua zones/db.bindtest.rtfm.co.ua zone bindtest.rtfm.co.ua/IN: loaded serial 4 OK
[/simterm]
Перезагружаем named
:
[simterm]
root@ip-10-0-1-157:/etc/bind# systemctl restart bind9
[/simterm]
Пробуем получить информацию:
[simterm]
root@ip-10-0-1-157:/etc/bind# dig @localhost bindtest.rtfm.co.ua +answer ; <<>> DiG 9.10.3-P4-Debian <<>> @localhost bindtest.rtfm.co.ua +answer ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4154 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;bindtest.rtfm.co.ua. IN A ;; ANSWER SECTION: bindtest.rtfm.co.ua. 604800 IN A 34.253.58.71 ;; AUTHORITY SECTION: bindtest.rtfm.co.ua. 604800 IN NS ns1-example.rtfm.co.ua. bindtest.rtfm.co.ua. 604800 IN NS ns2-example.rtfm.co.ua.
ОК — тут всё работает.
[/simterm]
Добавляем у регистратора домена rtfm.co.ua запись bindtest.rtfm.co.ua с параметрами IN NS
ns1-example.rtfm.co.ua и ns2-example.rtfm.co.ua:
И пробуем получить информацию о домене «из мира»:
[simterm]
16:37:54 [setevoy@setevoy-arch-work ~] $ dig @ns1-example.rtfm.co.ua bindtest.rtfm.co.ua +short 34.253.58.71
[/simterm]
DNS Load Balancing
Идея простого DNS Load Balancing — вернуть клиенту несколько IP в ответ на запрос записи IN A
.
В списке IP, который будет возвращать BIND порядок IP меняется случайным образом — такой себе round-robin. Клиент первым делом попробует выполнить подключение к первому из полученных IP, и если это не сработает — он использует следующий из списка.
ОК, обновляем файл зоны:
$TTL 604800 @ IN SOA bindtest.rtfm.co.ua. ns1-example.rtfm.co.ua. ( 5 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns1-example.rtfm.co.ua. @ IN NS ns2-example.rtfm.co.ua. @ IN A 34.253.58.71 @ IN A 34.240.126.223 @ IN A 34.242.8.220
Тут 34.242.8.220 — публичный IP Клиента А, а 34.240.126.223 — Клиента В, используем просто для примера.
Не забываем обновить Serial.
Проверяем файл зоны:
[simterm]
root@ip-10-0-1-157:/etc/bind# named-checkzone bindtest.rtfm.co.ua zones/db.bindtest.rtfm.co.ua zone bindtest.rtfm.co.ua/IN: loaded serial 5 OK
[/simterm]
Пробуем получить IP:
[simterm]
17:11:42 [setevoy@setevoy-arch-work ~] $ dig bindtest.rtfm.co.ua +short 34.253.58.71 34.242.8.220 34.240.126.223 17:11:50 [setevoy@setevoy-arch-work ~] $ dig bindtest.rtfm.co.ua +short 34.242.8.220 34.240.126.223 34.253.58.71 17:12:00 [setevoy@setevoy-arch-work ~] $ dig bindtest.rtfm.co.ua +short 34.240.126.223 34.253.58.71 34.242.8.220
[/simterm]
Три раза получаем первыми разные IP — вот и простой DNS Load balancer.
Продемонстрируем с NIGNX — на каждом хосте устанавливаем его:
[simterm]
17:14:06 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] 'sudo apt install -y nginx' 17:14:37 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] 'sudo apt install -y nginx' 17:15:04 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] 'sudo apt install -y nginx'
[/simterm]
На каждом обновляем файл /var/www/html/index.nginx-debian.html
:
[simterm]
$ ssh -i rtfm-dev.pem [email protected] 'sudo bash -c "echo BindServer > /var/www/html/index.nginx-debian.html"' $ ssh -i rtfm-dev.pem [email protected] 'sudo bash -c "echo This is ClientA > /var/www/html/index.nginx-debian.html"' $ ssh -i rtfm-dev.pem [email protected] 'sudo bash -c "echo This is ClientB > /var/www/html/index.nginx-debian.html"'
[/simterm]
Открываем порт 80 в SecurityGroup:
[simterm]
$ aws ec2 authorize-security-group-ingress --group-id sg-69520913 --protocol tcp --port 80 --cidr 0.0.0.0/0
[/simterm]
Проверяем:
[simterm]
17:21:34 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientB 17:21:35 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua BindServer 17:21:36 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientA 17:21:37 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientB 17:21:38 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua BindServer 17:21:39 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientA 17:21:40 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientB
[/simterm]
Гасим NGINX на одном из северов, например на ClientB:
[simterm]
17:20:06 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] 'sudo bash -c "service nginx stop"'
[/simterm]
Проверяем:
[simterm]
17:22:23 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientA 17:25:52 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua BindServer 17:25:53 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua BindServer 17:25:54 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientA 17:25:55 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua BindServer 17:25:56 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua BindServer 17:25:57 [setevoy@setevoy-arch-work ~] $ curl bindtest.rtfm.co.ua This is ClientA
[/simterm]
Главный недостаток DNS Load Balancer — что он не имеет никакой возможности узнать насколько загружен тот или иной хост из пула адресов, которые DNS возвращает клиенту, и даже не может проверить — жив ли он (например — отвечает ли NGINX на 80 порту), поэтому не стоит считать его fail-over механизмом.
Кроме того — DNS медленно реагирует на изменения в конфигурации: пока не истечёт TTL для зоны — другие DNS не обновят информацию в своих кешах и будут отдавать старые параметры.
DNS network-based routing
Следующая задача — обеспечить раздачу разных IP в зависимости от того — откуда пришёл клиент.
Если запрос приходит от ClientA (из подсети A) — отдаём ему IP 34.242.8.220, если ClientB — то 34.240.126.223, для всех остальных — 34.253.58.71.
Аналогичный подход используется в посте Debian: настройка GeoIP для BIND — создаём отдельные файлы зон для различных клиентов, и с помощью view
и оператора match-clients
выбираем какую зону кому отдавать.
Обновляем named.conf.options
— создаём access control list-ы для каждого клиента — подсетей, которые создавали:
... acl "subnet-a" { 10.0.2.0/24; }; acl "subnet-b" { 10.0.3.0/24; }; ...
Копируем файл зоны db.bindtest.rtfm.co.ua
— создаём два дополнительных файла — для клиентов из подсети А, и для клиентов из подсети В:
[simterm]
root@ip-10-0-1-157:/etc/bind# cp zones/db.bindtest.rtfm.co.ua zones/db-net-a.bindtest.rtfm.co.ua root@ip-10-0-1-157:/etc/bind# cp zones/db.bindtest.rtfm.co.ua zones/db-net-b.bindtest.rtfm.co.ua
[/simterm]
Теперь у нас тут есть:
[simterm]
root@ip-10-0-1-157:/etc/bind# ls -l zones total 12 -rw-r--r-- 1 root bind 328 Mar 21 15:10 db.bindtest.rtfm.co.ua -rw-r--r-- 1 root bind 328 Mar 21 15:53 db-net-a.bindtest.rtfm.co.ua -rw-r--r-- 1 root bind 328 Mar 21 15:53 db-net-b.bindtest.rtfm.co.ua
[/simterm]
Данные из файла db.bindtest.rtfm.co.ua
будем отдавать всем «внешним» клиентам, данные из db-net-a.bindtest.rtfm.co.ua
— клиентам из подсети А, данные из db-net-b.bindtest.rtfm.co.ua
— клиентам из подсети В.
Обновляем в них IN A
, оставляем по одной, и инкременим Serial:
[simterm]
root@ip-10-0-1-157:/etc/bind# grep -r "A\|Serial" zones/* | grep -v SOA zones/db.bindtest.rtfm.co.ua: 6 ; Serial zones/db.bindtest.rtfm.co.ua:@ IN A 34.253.58.71 zones/db-net-a.bindtest.rtfm.co.ua: 6 ; Serial zones/db-net-a.bindtest.rtfm.co.ua:@ IN A 34.242.8.220 zones/db-net-b.bindtest.rtfm.co.ua: 6 ; Serial zones/db-net-b.bindtest.rtfm.co.ua:@ IN A 34.240.126.223
[/simterm]
Проверяем:
[simterm]
root@ip-10-0-1-157:/etc/bind# named-checkzone bindtest.rtfm.co.ua zones/db.bindtest.rtfm.co.ua zone bindtest.rtfm.co.ua/IN: loaded serial 6 OK root@ip-10-0-1-157:/etc/bind# named-checkzone bindtest.rtfm.co.ua zones/db-net-a.bindtest.rtfm.co.ua zone bindtest.rtfm.co.ua/IN: loaded serial 6 OK root@ip-10-0-1-157:/etc/bind# named-checkzone bindtest.rtfm.co.ua zones/db-net-b.bindtest.rtfm.co.ua zone bindtest.rtfm.co.ua/IN: loaded serial 6 OK
[/simterm]
Обновляем name.conf.local
добавляем view
и условия:
view "network-A" { match-clients { subnet-a; }; recursion no; zone bindtest.rtfm.co.ua { type master; file "/etc/bind/zones/db-net-a.bindtest.rtfm.co.ua"; }; }; view "network-B" { match-clients { subnet-b; }; recursion no; zone bindtest.rtfm.co.ua { type master; file "/etc/bind/zones/db-net-b.bindtest.rtfm.co.ua"; }; }; view "NotMatched" { match-clients { any; }; recursion no; zone bindtest.rtfm.co.ua { type master; file "/etc/bind/zones/db.bindtest.rtfm.co.ua"; }; };
Во избежание ошибки:
[simterm]
root@ip-10-0-1-157:/etc/bind# named-checkconf /etc/bind/named.conf.default-zones:2: when using 'view' statements, all zones must be in views
[/simterm]
Добавляем view
для всех зон в /etc/bind/named.conf.default-zones
:
view localhost_resolver { // prime the server with knowledge of the root servers zone "." { type hint; file "/etc/bind/db.root"; }; // be authoritative for the localhost forward and reverse zones, and for // broadcast zones as per RFC 1912 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"; }; };
Проверяем:
[simterm]
root@ip-10-0-1-157:/etc/bind# named-checkconf
[/simterm]
Перезапускаем bind
:
[simterm]
root@ip-10-0-1-157:/etc/bind# systemctl restart bind9
[/simterm]
Пробуем с клиента А:
[simterm]
18:15:28 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] dig @ns1-example.rtfm.co.ua bindtest.rtfm.co.ua +short 34.242.8.220
[/simterm]
И лог BIND:
21-Mar-2018 16:15:30.585 client 10.0.2.145#55753 (bindtest.rtfm.co.ua): view network-A: query: bindtest.rtfm.co.ua IN A +E (10.0.1.157)
Пробуем с клиента из подсети В:
[simterm]
18:15:30 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] dig @ns1-example.rtfm.co.ua bindtest.rtfm.co.ua +short 34.240.126.223
[/simterm]
И лог BIND:
21-Mar-2018 16:15:30.585 client 10.0.2.145#55753 (bindtest.rtfm.co.ua): view network-A: query: bindtest.rtfm.co.ua IN A +E (10.0.1.157)
21-Mar-2018 16:16:12.364 client 10.0.3.164#36711 (bindtest.rtfm.co.ua): view network-B: query: bindtest.rtfm.co.ua IN A +E (10.0.1.157)
И пробуем из мира:
[simterm]
18:16:52 [setevoy@setevoy-arch-work ~] $ dig @ns1-example.rtfm.co.ua bindtest.rtfm.co.ua +short 34.253.58.71
[/simterm]
Лог:
21-Mar-2018 16:15:30.585 client 10.0.2.145#55753 (bindtest.rtfm.co.ua): view network-A: query: bindtest.rtfm.co.ua IN A +E (10.0.1.157)
21-Mar-2018 16:16:12.364 client 10.0.3.164#36711 (bindtest.rtfm.co.ua): view network-B: query: bindtest.rtfm.co.ua IN A +E (10.0.1.157)
21-Mar-2018 16:16:52.487 client 194.***.***.45#12659 (bindtest.rtfm.co.ua): view NotMatched: query: bindtest.rtfm.co.ua IN A +E (10.0.1.157)
Один нюанс тут — если мы вызов curl
с любого из клиентов — он нам везде вернёт 34.253.58.71:
[simterm]
18:24:05 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] curl -s bindtest.rtfm.co.ua BindServer 18:36:01 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] curl -s bindtest.rtfm.co.ua BindServer
[/simterm]
А в логе будет указано сработвашее условие NotMached:
21-Mar-2018 16:36:14.348 client 52.213.251.132#13928 (bindtest.rtfm.co.ua): view NotMatched: query: bindtest.rtfm.co.ua IN A -EDC (10.0.1.157)
21-Mar-2018 16:36:14.390 client 34.245.138.44#57054 (bindtest.rtfm.co.ua): view NotMatched: query: bindtest.rtfm.co.ua IN AAAA -EDC (10.0.1.157)
Если обратить внимание на client — 52.213.251.132 и 34.245.138.44 — то становится понятна причина, вспомним наши ACL-ки:
... acl "subnet-a" { 10.0.2.0/24; }; acl "subnet-b" { 10.0.3.0/24; }; ...
Кроме того — всоминаем resolv.conf
, о котором упоминалось в начале — он содержит 10.0.0.2, который уже выполняет запрос через вышестоящий DNS, в результате к нашему ns1-example.rtfm.co.ua
запросы приходят не с IP Клиента А и В, а от внешних DNS-серверов.
Обновим /etc/resolv.conf
например на Клиенте А, укажем IP нашего DNS, что бы Клиент А обращался к нему напрямую:
nameserver 34.253.58.71
На BIND обновляем ACL для подсети-а:
... acl "subnet-a" { 10.0.2.0/24; 34.242.8.220; }; ...
Перезапускаем:
[simterm]
root@ip-10-0-1-157:/etc/bind# systemctl restart bind9
[/simterm]
Пробуем curl
с клиента-А:
[simterm]
18:44:34 [setevoy@setevoy-arch-work ~/Work/Bitbucket/aws-credentials] [master*] $ ssh -i rtfm-dev.pem [email protected] curl -s bindtest.rtfm.co.ua This is ClientA
[/simterm]
И лог BIND:
21-Mar-2018 16:44:39.276 client 34.242.8.220#39845 (bindtest.rtfm.co.ua): view network-A: query: bindtest.rtfm.co.ua IN AAAA + (10.0.1.157)
Вот — как-то так оно всё и работает…