Knot DNS resolver для Centos 8
Стоит сейчас bind, собранный опциями --prefix=/opt/bind --with-tuning=large --enable-threads --with-openssl --with-libtool. Потребовалось вынести DNS сервер, т.к. нагрузка получилась на нем немаленькая. Обратил внимание на Knot. Но есть нюанс - разные адреса для разных сетей должны отдаваться. Что из этого получится - посмотрим.
Knot, как заверяют разработчики, весьма высокопроизводителен. Однако резолвер и непосредственно DNS сервер в нем разделены на разные программы.
knot-resolver - то, что мне нужно для того, чтобы клиенты сети могли пользоваться настройками моего DNS, а не ставить Google или Cloudflare.
knot - обычный DNS сервер для поднятия своих зон.

Исходные данные:
[root@noc01 ~]# cat /etc/centos-release
CentOS Linux release 8.2.2004 (Core)

Установил epel репозиторий
[root@noc01 ~]# dnf install epel-release
Last metadata expiration check: 1:34:35 ago on Срд 22 июл 2020 17:10:58.
Package epel-release-8-8.el8.noarch is already installed.
Dependencies resolved.
Nothing to do.
Complete!

Там должен быть пакет с Knot-resolver
[root@noc01 knot-resolver]# dnf info knot-resolver
Last metadata expiration check: 5:05:40 ago on Чтв 23 июл 2020 11:18:53.
Installed Packages
Name         : knot-resolver
Version      : 5.1.2
Release      : 1.el8
Architecture : x86_64
Size         : 980 k
Source       : knot-resolver-5.1.2-1.el8.src.rpm
Repository   : @System
From repo    : epel
Summary      : Caching full DNS Resolver
URL          : https://www.knot-resolver.cz/
License      : GPL-3.0-or-later
Description  : The Knot Resolver is a DNSSEC-enabled caching full resolver implementation
             : written in C and LuaJIT, including both a resolver library and a daemon.
             : Modular architecture of the library keeps the core tiny and efficient, and
             : provides a state-machine like API for extensions.
             : 
             : The package is pre-configured as local caching resolver.
             : To start using it, start a single kresd instance:
             : $ systemctl start kresd@1.service
Конфиги лежат в /etc/knot-resolver

Примеры конфигов также есть
[root@noc01 examples]# ls /usr/share/doc/knot-resolver/examples/ -l
total 28
-rw-r--r--. 1 root root 1277 июл  1 15:27 config.cluster
-rw-r--r--. 1 root root 2694 июл  1 15:27 config.docker
-rw-r--r--. 1 root root  661 июл  1 15:27 config.internal
-rw-r--r--. 1 root root 2086 июл  1 15:27 config.isp
-rw-r--r--. 1 root root  634 июл  1 15:27 config.personal
-rw-r--r--. 1 root root 1203 июл  1 15:27 config.privacy
-rw-r--r--. 1 root root 1033 июл  1 15:27 config.splitview
Для отладки лучше запустить без ухода в демон
[root@noc01 ~]# kresd -v -c /etc/knot-resolver/kresd.conf

После этого будет доступна консоль самого резолвера.
Можно посмотреть, к примеру, какие интерфейсы слушает и какие есть в системе.
> net.list()
[1] => {
    [kind] => dns
    [transport] => {
        [family] => inet4
        [freebind] => false
        [ip] => 0.0.0.0
        [port] => 53
        [protocol] => udp
    }
}
[2] => {
    [kind] => dns
    [transport] => {
        [family] => inet4
        [freebind] => false
        [ip] => 0.0.0.0
        [port] => 53
        [protocol] => tcp
    }
}

В данном случае выключен IPv6 и слушается на всех IP адресах.
 
> net.interfaces()
[eno1.50] => {
    [addr] => {
        [1] => 192.168.1.1    }
    [mac] => d4:ae:52:c5:4f:ce
}
[lo] => {
    [addr] => {
        [1] => 127.0.0.1
    }
    [mac] => 00:00:00:00:00:00
}
Также в verbose режиме будут выводится и запросы от клиентов.

Можно смотреть логи из journalctl
[root@noc01 examples]# journalctl -u kresd@* -f

Еще можно подключиться к этому демону и увидеть CLI
# ps -ef | awk '/[k]resd/{print $2}'
35395
# socat - UNIX-CONNECT:/run/knot-resolver/control/1
> cache.count()
60

>
Чтобы забирать статистику в Prometheus нужно подгрузить еще модули: stats и http
-- load modules
modules = {
    'view',
    'stats',
    'policy',
    'http'
}
Но для этого еще нужно доставить knot-resolver-module-http
dnf install knot-resolver-module-http
Теперь про мою конфигурацию:
т.к. нужно отдавать разным сетям разные айпишники по имени, то я поднял здесь же еще и DNS сервера на левых портах (531  и 532)

Служат они как раз для того, чтобы клиенты внутри сети резолвили IP адрес отличный от того, который отдается остальным.
Т.е. запрос, приходящий на knot-resolver, будет проанализирован и отправлен либо в мои DNS, либо во внешние.

Настраивается это в конфиге knot-resolver. Например:
[root@noc01 ~]# cat /etc/knot-resolver/kresd.conf
-- SPDX-License-Identifier: CC0-1.0
-- vim:syntax=lua:set ts=4 sw=4:
-- Config file example usable for ISP resolver
-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/

-- Network interface configuration
net.listen('0.0.0.0', 53, { kind = 'dns' })
net.listen('127.0.0.1', 8453, { kind = 'webmgmt' })
net.ipv6 = false
-- net.listen('::1', 53, { kind = 'dns'})
-- net.listen('127.0.0.1', 853, { kind = 'tls' })
-- net.listen('::1', 853, { kind = 'tls' })

-- Refer to manual for optimal cache size
cache.size = 10 * GB

-- load modules
modules = {
    'view',
    'stats',
    'policy',
    'http'
}

http.config({
    tls = false,
})

http.prometheus.namespace = 'resolver_'


-- Local Policy

int_domains = policy.todnames(
    {
        'local.com.ua.'
    })

policy.add(policy.suffix( policy.FLAGS({'NO_CACHE'}), int_domains ))


int_nets = { '127.0.0.1/8', '192.168.0.0/16', '172.16.0.0/16', '10.0.0.0/8' }

int_policy = policy.suffix(policy.STUB('127.0.0.1@532'), {todname('local.com.ua.')})
for index,int_net in ipairs(int_nets) do
    view:addr(int_net, int_policy)
end

for index,int_net in ipairs(int_nets) do
    view:addr(int_net, policy.all(policy.PASS))
end

-- drop everything that hasn't matched
view:addr('0.0.0.0/0', policy.all(policy.DROP))

-- verbose(true)
-- cache.clear()

Сам конфиг - это lua скрипт. Комментарии начинаются с двух тире "--"
Здесь показано, что для сетей int_nets применяется политика int_policy. Сама политика - это отправка всех для получения IP для домена local.com.ua на DNS сервер, который находится по адресу 127.0.0.1 на порту 532

На порту 8453 висят метрики для Prometheus.
Если пром находится на другом сервере, то добавляем правило в firewall:
[root@noc01 ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.33" port port=8453 protocol="tcp" accept'
success
В данном случае трафик статистики бегает в своем VLAN, поэтому шифрования нету. Если это всё будет бегать по открытой сети, то нужно будет пользоваться ssl, благо поддерживается.

Получилась вот такое в графане
Один из графиков, вообще их там много. Можно алерты повесить, чтобы при большом количестве неправильных ответов что-то происходило.

Dashboard положил тут https://grafana.com/grafana/dashboards/12743
На всякий случай продублирую и здесь Knot-resolver DNS-1596394214540.json

Полезное чтение: https://knot-resolver.readthedocs.io/en/stable/config-overview.html
Ajar
2020-08-05 11:00:06
Avatar
Спасибо !  Я как раз планирую уйти с unbound 
a_n_h
2020-08-05 11:49:57
Avatar
Спасибо !  Я как раз планирую уйти с unbound 

чем unbound не нравится?
Ajar
2020-08-05 16:01:57
Avatar
Спасибо !  Я как раз планирую уйти с unbound 

чем unbound не нравится? 
Ajar
2020-08-05 16:03:25
Avatar
Для сравнения кпд резолверов. 
~Tornado~
2020-09-28 13:23:38
Avatar
Добрый день,подскажите,как будет выглядеть политика для нескольких доменных имен,так-как 

int_policy = policy.suffix(policy.STUB('127.0.0.1@532'), {todname('local.com.ua.', 'example.com.')})
второй домен отдается с мировым ай пи и перенаправление на внутренний днс не происходит (
~Tornado~
2020-09-28 13:41:05
Avatar
Ответ найден,
int_policy = policy.suffix(policy.STUB('127.0.0.1@531'), int_domains)
 
Ви маєте увійти під своїм обліковим записом

loading