В этой статье мы поднимем DNS-сервер. Для чего? Ну во-первых, для нужд домашнего home.dns, во-вторых, для DoH/DoT, в-третьих, для инфраструктурных нужд, к примеру VPN-подключения anywhere-to-home, в-четвертых, для исключения открытых DNS-запросов к вашему провайдеру или например к google (8.8.8.8, 8.8.4.4).
Нам понадобится:
DoH - DNS over HTTPS, для использования требуется 1ый запрос отправить открытым способом на публичный DNS-сервер, а именно - срезолвить сервер DoH
DoT - DNS over TLS, здесь обращение идет по IP-адресу, поэтому такой запрос как в DoH не потребуется. Контроль осуществляется на базе сертификата TLS
dnf install bind bind-utils bind-libs bind-chroot -y
Настройка chroot-окружения (/var/named/)
В файле /var/named/chroot/etc/named.conf внесем корректировки (указать своих клиентов):
acl homeclients {
localhost;
192.168.0.0/16; # Домашняя сеть
10.0.0.0/8; # Корпоративная сеть
100.64.0.0/14; # Сеть удаленного доступа
172.16.0.0/12; # Сеть защищенного доступа
};
options {
listen-on port 53 { any; }; # listen any interfaces on IPv4
...
allow-query { homeclients; };
...
recursion yes;
allow-recursion { homeclients; };
...
version "DNS Server";
dnssec-enable yes;
dnssec-validation no;
...
};
Расширенное логирование:
Важно: /var/log/named при запуске chroot-окружения превратится в /var/named/chroot/var/log/named/
Важно: файлы лога автоматически не создадутся, их необходимо создать вручную и выставить правильные права доступа. При старте службы выдаст ошибку, если файлов нет.
logging {
channel default_file {
file "/var/log/named/default.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel general_file {
file "/var/log/named/general.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
cannel database_file {
file "/var/log/named/database.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel security_file {
file "/var/log/named/security.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel config_file {
file "/var/log/named/config.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel resolver_file {
file "/var/log/named/resolver.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel xfer-in_file {
file "/var/log/named/xfer-in.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel xfer-out_file {
file "/var/log/named/xfer-out.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel notify_file {
file "/var/log/named/notify.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel client_file {
file "/var/log/named/client.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel unmatched_file {
file "/var/log/named/unmatched.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel queries_file {
file "/var/log/named/queries.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel network_file {
file "/var/log/named/network.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel update_file {
file "/var/log/named/update.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel dispatch_file {
file "/var/log/named/dispatch.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel dnssec_file {
file "/var/log/named/dnssec.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel lame-servers_file {
file "/var/log/named/lame-servers.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
category default { default_file; };
category general { general_file; };
category database { database_file; };
category security { security_file; };
category config { config_file; };
category resolver { resolver_file; };
category xfer-in { xfer-in_file; };
category xfer-out { xfer-out_file; };
category notify { notify_file; };
category client { client_file; };
category unmatched { unmatched_file; };
category queries { queries_file; };
category network { network_file; };
category update { update_file; };
category dispatch { dispatch_file; };
category dnssec { dnssec_file; };
category lame-servers { lame-servers_file; };
};
Настройка пересылки запросов для всех зон, исключения описываются ниже:
zone "." IN {
type forward;
forward only;
forwarders { 127.0.0.1 port 8053; };
};
Далее можно указывать свои зоны:
zone "home.dns" IN {
type master;
file "home.dns.zone";
};
Соответственно необходимо создать файл зоны: /var/named/home.dns.zone, например такого содержания:
$TTL 86400 ;
home.dns. IN SOA ns1.home.dns. ns2.home.dns. (
1 ; Serial
600 ; Refresh
3600 ; Retry
1w ; Expire
360 ; Minimum TTL
)
@ IN NS ns1.home.dns.
@ IN NS ns2.home.dns.
@ IN A 192.168.0.5 # Какой-нибудь ресурс в локальной сети
ns1 IN A 192.168.1.2 # IP-адрес нашего BIND
ns2 IN A 192.168.1.2 # IP-адрес нашего BIND
router IN A 192.168.0.1 # Допустим адрес нашего роутера
Включаем и запускаем наш сервер
systemctl enable --now named-chroot
Из репозитория epel
dnf install stubby -y
Корректируем /etc/stubby/stubby.yml
Главное указать:
listen_addresses:
- 127.0.0.1@8053
- 0::1@8053
Далее раскомменчиваем нужный сервис (секция DEFAULT UPSTREAM и/или OPTIONAL UPSTREAMS), например Quad9-сервис:
- address_data: 9.9.9.9
tls_auth_name: "dns.quad9.net"
- address_data: 149.112.112.112
tls_auth_name: "dns.quad9.net"
Запускаем сервис:
systemctl enable --now stubby
Вообще, установка AdGuardHome в связке с тем что уже установлено может быть следующей:
Клиент -> BIND -> AdGuardHome -> Stubby -> AdGuardDNS External
Но такая схема скорее наследственная и имеет ограничение в наблюдаемости. Т.е. в Web-статистике AdGuardHome мы будем наблюдать только одного клиента - 127.0.0.1. Во внешнем AdGuardDNS мы также увидим одного клиента - наш сервер DNS. Вся статистика останется в логах BIND, которая не визуализируется. В идеале (если имеем домашнюю зону) схема будет сложнее, с учетом настройки исключений и т.д:
Клиент -> AdGuardHome -> [Stubby для удобства] -> AdGuardDNS External (Внешние зоны)
Клиент -> AdGuardHome -> BIND (Внутренние зоны)
Как видно из схемы выше - Stubby мы оставили для удобства. В чем же удобство? Удобство миграции, переподключения, смены провайдера или движка DNS. Легкости ради. В установке «с нуля» Stubby можно не устанавливать, но для себя я бы оставил.
Что же касается того, какой DNS-сервер External выбрать - личное дело каждого. AdGuardDNS:
+
Блокирует рекламу-
Требует регистрацию (отсюда логирование всех запросов - персонализировано)-
В бесплатном тарифе имеет ограничения: до 5 клиентов и до 300тыс. запросов в месяц+
По тестам DNS Leaks не имеет утечекУстановка домашнего AdGuardHome сократит количество запросов к внешнему DNS за счет блокировок «паразитных» запросов (см. списки), а также количество клиентов (1 AdGuardHome сервер = 1 клиент)
Итак, берем AdGuardHome и скачиваем на наш DNS-сервер.
cd /opt/
wget https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh
В скрипте убираем автоматическую установку в качестве сервиса, для этого в конце скрипта комментируем строку:
#install_service
Потом запускаем скрипт, который скачивает соответствующий архив, распаковывает и удаляет его:
/bin/sh install.sh
Ну и теперь самостоятельно создаем файл сервиса:
cd AdGuardHome
./AdGuardHome -s install
При первом запуске потребуется настроить параметры - порт для клиентов DNS, порт для WEB, потом уже внутри настроим следующий сервер DNS ( -> [DNS Server] ).
По сути, AdGuardHome - это рекурсивный сервер DNS, весь конфиг которого будет расположен в файле /opt/AdGuardHome/AdGuardHome.yaml
и списки фильтрации в /opt/AdGuardHome/data/filters/
По умолчанию AdGuardHome для Web поднимает порт 3000 (можно поменять в любой момент). В моем случае это 8080, и nginx reverse proxy https (443/tcp). В случае с nginx не забыть настроить selinux policy.
2 варианта настройки AdGuardHome (см. 2 схемы работы)
Здесь 53/udp/tcp слушает named и пересылает запросы для неизвестных доменов рекурсивно в AdGuardHome. Для этого внесен следующие изменения в имеющуюся структуру:
zone "." IN {
type forward;
forward only;
forwarders { 127.0.0.1 port 5353; };
};
dns:
bind_hosts:
- 127.0.0.1
port: 5353
upstream_dns:
- 127.0.0.1:8053
Таким образом получается BIND принимает запросы от клиентов и направляет их в AdGuardHome, а тот, после обрабатывания по спискам отправляет отфильтрованные запросы в Stubby (который на текущий момент настроен на Quad9). Полная схема выглядит так:
Клиент --udp/53--> BIND --udp/5353--> AdGuardHome --udp/8053--> Stubby --tls--> Quad9
Таким образом, шифрованный запрос уходит только во внешний DNS, внутри же все запросы в открытом виде.
После чего запускаем AdGuardHome, перезапускаем BIND и схема заработала (про настройки AdGuardHome ниже, ввиде YAML-файла)
Здесь слушать 53/udp/tcp будет AdGuardHome и рекурсивно пересылать запросы в named (либо в named домены-исключения, остальные в NextHop-DNS
Таким образом необходимо перенастроить BIND:
options {
listen-on port 5353 { any; };
listen-on-v6 port 5353 { ::1; };
Настроить AdGuardHome:
dns:
bind_hosts:
- 127.0.0.1
port: 53
upstream_dns:
- 127.0.0.1:5353
Перезапустить BIND и запустить AdGuardHome.
Теперь схема уже выглядит вот так (при условии что предыдущий шаг не выполнялся с изменением зоны «.»)
Клиент --udp/53--> AdGuardHome --udp/5353--> BIND --udp/8053--> Stubby --tls--> Quad9
Из схемы видно, что в AdGuard теперь можно будет фильтровать запросы по клиентам, а также, что все запросы (кроме отфильтрованных по спискам блокировок) все равно будут через BIND.
Усложняем. Вписываем в конфиг AdGuardHome зоны-исключения:
dns:
bind_hosts:
- 127.0.0.1
port: 53
upstream_dns:
- 127.0.0.1:8053
- [/home.zone/]127.0.0.1:5353
- [/somehome.ru/]127.0.0.1:5353
Перезапускаем AdGuardHome. Теперь схема такая:
Клиент --udp/53--> AdGuardHome --udp/8053--> Stubby --tls--> Quad9 (Внешние зоны)
Клиент --udp/53--> AdGuardHome --udp/5353--> BIND (Внутренние зоны)
В качестве следующего NextHop-DNS будем использовать Stubby (хотя и необязательно, как писал выше).
Уже все дороги уперты в конечном итоге в Stubby, его мы теперь перенаправим на AdGuardDNS.
Регистрируемся AdGuardDNS.
Регистрируем нового клиента и получаем его ключ, например вот такой:
cbd426ac5.d.adguard-dns.com
Вписываем его в конфиг Stubby
## AdGuardDNS
- address_data: 94.140.14.49
tls_auth_name: "cbd426ac5.d.adguard-dns.com"
- address_data: 94.140.14.59
tls_auth_name: "cbd426ac5.d.adguard-dns.com"
Выпиливаем из Stubby Quad9 и DEFAULT UPSTREAM:
### Test servers ###
# The getdnsapi.net server
# - address_data: 185.49.141.37
# tls_auth_name: "getdnsapi.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
####### IPv6 addresses ######
### Test servers ###
# The getdnsapi.net server
# - address_data: 2a04:b900:0:100::38
# tls_auth_name: "getdnsapi.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
## Quad 9 'secure' service - Filters, does DNSSEC, doesn't send ECS
# - address_data: 9.9.9.9
# tls_auth_name: "dns.quad9.net"
# - address_data: 149.112.112.112
# tls_auth_name: "dns.quad9.net"
Перезапускаем Stubby.
Теперь схема в части внешнего DNS изменена и можно смотреть в личном кабинете запросы от клиентов (AdGuardHome) и отфильтрованные запросы (AdGuardDNS).
* --udp/8053--> Stubby --tls--> AdGuardDNS
В качестве NextHop-DNS можно указывать следующие варианты:
И в заключении: в настройках своего домашнего роутера - устанавливаем DNS-сервер наш IP