Debian.pro

Блог для пользователей и администраторов Debian


Unbound: локальный резолвер на сервере — честный, с форвардингом и с зашифрованным форвардингом.

Для начала поговорим о том, для чего нужен локальный dns-резолвер. Вообще, полезен он и на сервере, и на вашем ноутбучке (только для разного, пожалуй), а написать эту статью меня вынудил именно новый провайдер (самизнаетепочему).
Локальный резолвер позволяет получать мгновенный ответ от dns (кроме случая, когда мы впервые спрашиваем определенную запись). Резолверы провайдера/хостера бывают перегружены, запрос в них в любом случае занимает какие-то миллисекунды, да и протокол UDP весьма не надежен, если говорить про один конкретный запрос — от этого мы спасаемся резолвером без форвардинга, выигрывая пару миллисекунд на любом обращении к dns. Вкупе с опцией prefetch — ответ всегда будет мнгновенным, потому что unbound будет самостоятельно в фоне (без запросов на резолв от системы) обновлять отдельные записи, когда их ttl в кэше будет подходить к концу.

Защищает локальный резолвер и от того, что провайдер знает и логгирует все записи, которые мы спрашиваем у его dns-сервера. Таким образом провайдер узнаёт, какие именно https-сайты вы посещаете (можно и из заголовка SNI узнать, но не весь софт шлёт этот заголовок). Бывают и хреновые случаи — когда провайдер перехватывает весь dns-трафик с нашего компа/сервера и заворачивает его в свой резолвер (фильтруя и подменяя записи), но от этого спасёт использование форварда в tls-резолвер (в статье будут приведены для примера публичные, но и свой поднять в доверенной сети никто не мешает).

Свой резолвер защищает и от самодурства администраторов чужого — некоторые провайдеры и хостеры выставляют у себя опцию min-ttl большую (тем самым, повышая минимальный ttl в своём кэше, снижая нагрузку — в отдельных упоротых случаях мне встречался min-ttl в 30 дней), подменяют записи, ломают DNSSEC, дропают CAA записи, да много чего делают. Если при этом они не заворачивают весь трафик по 53-му порту во всей сети в свой резолвер — то и от этого защитимся (а если заворачивают — привет, dns over tls).

Ещё один плюс — вы сами контролируете (если не используете forward, или используете forward в свой сервер) сброс кэшей на резолвере. Например, ваши сервера ходят в какое-то API бэкэнда. У вас появилась необходимость переключить запись для этого бэкэнда. Меняем запись в dns, рестартим все резолверы, вуаля — на всех уже новая запись. Очень удобно.

Почему именно unbound. Не буду чего-то придумывать — в unbound опция prefetch появилась давно, а в bind — только в десятой версии (которая до сих пор не доехала до стабильных дистрибутивов в базовых репозиториях). Unbound есть во всех поддерживаемых убунтах и дебианах, не нужно подключать сторонние репозитории. Других причин, в целом, нет.

Для начала ставим пакет с unbound:

root@server:~# apt-get install unbound

Редактируем файл /etc/unbound/unbound.conf
Полностью он у нас будет выглядеть так:

# эта строчка есть в дефолтном конфиге, оставляем её.
include: "/etc/unbound/unbound.conf.d/*.conf"

# открываем секцию server
server:
    # разрешаем подключения только с localhost-а
    access-control: 127.0.0.0/8 allow
    # слушать внешние интерфейсы смысла тоже нет.
    interface: 127.0.0.1
    # запись с ttl больше 14400 секунд в кеш записываем с ttl равным 14400
    cache-max-ttl: 14400
    # запись с ttl меньше 60 секунд записываем в кэш с ttl равным 60 секунду
    cache-min-ttl: 60
    # Скрываем то, что у нас unbound и его версию.
    hide-identity: yes
    hide-version: yes
    # если в них нет необходимости, то unbound убирает из своего ответа информацию о NS-серверах домена. Чуть увеличивает скорость и уменьшает трафик (если в unbound ходим по сети).
    minimal-responses: yes
    # Эта опция включает обновление записей в кэше в фоне, ради неё мы всё и затеяли.
    prefetch: yes
    # снижаем количество информации, которую unbound отправляет на чужие NS в своих исходящих запросах.
    qname-minimisation: yes
    # unbound будет отдавать записи одного типа (если их несколько, т.н. round-robin) в случайном порядке.
    rrset-roundrobin: yes
    # приводит все ответы сервера (и записи в кэше) к нижнему регистру
    use-caps-for-id: yes
    # включает хождение наружу по tcp. Я пытался использовать её совместно с "do-udp no", но без форварда вместе они работать не будут. Но для примера пусть полежит.
    do-tcp: yes

Если нам всё же хочется использовать форвард в другой dns-сервер (при этом стоит понимать, что unbound всё ещё будет делать prefetch для записей в кэше, даже при включенном форварде), то добавляем в конфиг такие буквы (сторонние сервера, само собой, можете указать другие):

forward-zone:
    name: "."
    forward-addr: 8.8.4.4
    forward-addr: 8.8.8.8

Если же вам хочется dns загнать через tls, то добавляем кусок конфига ниже (вместо куска конфига выше, само собой). Все коннекты к этим серверам (а значит, и все записи, которыми вы обмениваетесь) будут зашифрованы. Это ещё не dnscrypt, который вовсе не подвержен MItM, но и не plain-dns, который спуфят все, кому ни лень.
Я привожу рабочий список tls-серверов, но они «чьи-то». Вы скрываете свой dns-трафик от провайдера, но дарите его кому-то ещё, имейте в виду.

forward-zone:
    name: "."
    forward-addr: 9.9.9.9@853 # quad9.net primary
    forward-addr: 149.112.112.112@853 # quad9.net secondary
    forward-addr: 145.100.185.15@853 # dnsovertls.sinodun.com US
    forward-addr: 145.100.185.16@853 # dnsovertls1.sinodun.com US
    forward-addr: 184.105.193.78@853 # tls-dns-u.odvr.dns-oarc.net US
    forward-addr: 185.49.141.37@853 # getdnsapi.net US
    forward-addr: 199.58.81.218@853 # dns.cmrg.net US
    forward-addr: 146.185.167.43@853 # securedns.eu Europe
    forward-addr: 89.233.43.71@853 # unicast.censurfridns.dk Europe

После операций с конфигом, само собой, рестартим unbound

root@server:~# /etc/init.d/unbound restart

Потестируем наш резолвер (если команды host нет — поставьте пакет bind9-host) на записи, которая уже в кеше локально:

root@server:~# time host debian.pro 127.0.0.1
....
real 0m0,006s
user 0m0,004s
sys 0m0,000s

Сравним с 8.8.8.8:

root@server:~# time host debian.pro 8.8.8.8
...
real 0m0,090s
user 0m0,004s
sys 0m0,000s

И это — при RTT в 5ms до адреса 8.8.8.8. Экономия — 80мс.

Остаётся самая малость, заставить систему использовать наш резолвер. Для начала выясняем, является ли /etc/resolv.conf симлинком куда-то там:

root@server:~# file /etc/resolv.conf
/etc/resolv.conf: symbolic link to ...

Если видим такую надпись — делаем так:

root@server:~# unlink /etc/resolv.conf

Тем самым мы запрещаем всяким NetworkManager-ам менять этот файл. Ну а сам файл создаём и приводим к такому виду:

nameserver 127.0.0.1

Если беспокоимся о том, что unbound упадёт и резолв сломается, то оставляем резервом другие резолверы:

nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4

Если у вас systemd (ubuntu 16+, debian 8+), то resolv.conf нужно «применять» перезапуском сервиса resolvconf:

root@server:~# service resolvconf restart

Ну а почитать все возможные опции советую на официальном сайте — https://www.unbound.net/documentation/unbound.conf.html, может там ещё что интересное валяется.


Комментарии (1):

  1. karavan :

    Для клиентов в администрируемой сети (а локалхост точно из этих) следующий параметр:

    access-control: 127.0.0.0/8 allow

    лучше заменить на:

    access-control: 127.0.0.0/8 allow_snoop

    Это помогает в дебаге:
    До:

    dig @127.0.0.1 +trace http://www.ru
    
    ; <> DiG 9.10.3-P4-Debian <> @127.0.0.1 +trace http://www.ru
    ; (1 server found)
    ;; global options: +cmd
    ;; Received 12 bytes from 127.0.0.1#53(127.0.0.1) in 0 ms

    После:

    dig @127.0.0.1 +trace http://www.ru
    
    ; <> DiG 9.10.3-P4-Debian <> @127.0.0.1 +trace http://www.ru
    ; (1 server found)
    ;; global options: +cmd
    .			517934	IN	NS	f.root-servers.net.
    .			517934	IN	NS	h.root-servers.net.
    .			517934	IN	NS	j.root-servers.net.
    .			517934	IN	NS	m.root-servers.net.
    .			517934	IN	NS	g.root-servers.net.
    .			517934	IN	NS	d.root-servers.net.
    .			517934	IN	NS	i.root-servers.net.
    .			517934	IN	NS	a.root-servers.net.
    .			517934	IN	NS	k.root-servers.net.
    .			517934	IN	NS	l.root-servers.net.
    .			517934	IN	NS	e.root-servers.net.
    .			517934	IN	NS	c.root-servers.net.
    .			517934	IN	NS	b.root-servers.net.
    .			517934	IN	RRSIG	NS 8 0 518400 20180216050000 20180203040000 41824 . kOqTTn/Jta3jkelCsfXGvtEdrqtAYjthpaWeRqdzKdAeb18SPg2v+qRQ yerp1pxZFHJWlh/07UKAxVvv82HLaD2tiHb3zGuwNeKkOq8zKh3+17jY vFS3VZ/M2u1sycho1kGa5rpXtuBJa6xFnFrVSRpz4G1cAmUp8gv+vM6J oVEbeoPGiZp37dvdd139g7uY0v8C0hSjrN2pRlHhRgZDEuxT8Lzt2+zD FGDwqMZGrQq3+DU14PmG6VjeHm1++v5qa5bRxUh052mAIOEviIroUAk/ uVdnSZcm0dX2lAfjs+f1IeMjfCucVS0ch3P5AIDWXF/VJpQkbwuHxWin 7Qtnug==
    ;; Received 1097 bytes from 127.0.0.1#53(127.0.0.1) in 0 ms
    
    ru.			172800	IN	NS	b.dns.ripn.net.
    ru.			172800	IN	NS	e.dns.ripn.net.
    ru.			172800	IN	NS	d.dns.ripn.net.
    ru.			172800	IN	NS	f.dns.ripn.net.
    ru.			172800	IN	NS	a.dns.ripn.net.
    ru.			86400	IN	DS	33094 8 2 7228B0DCE8E4DEDA575C7DB69CBF55C43FCCC4BB60FBCC717DDABED1 D17338E1
    ru.			86400	IN	RRSIG	DS 8 1 86400 20180216050000 20180203040000 41824 . BYql6ca2IPMv2ZtyMRUyk/wMp0nCyDoLDt5FjYVqslwVRPJg63dHBh/E X88P5XVJEl3n/njgODqqDLglYov8T9xA1DuU93E0RXvfceFURGH8BExZ WKq+HDE3U1Sofk5/5aFGdPipVl82gbF87CePR7ceCBBH0YeSnbIlIuH4 n5Pf6N7vfi5CEFNpVWZQhQ+Cu4pru28QlKFFtzVkh/AANrp1S9ZMrRcy DzURrnjc2uGDJu/LCKGvi1QRUQc/YL6vP7aOLhb8pklv3yS4ABdXAutF /wXazD5qp0+e1uQyeiHkbllDhdI0ntp0me0ZoyV2pv7Nnexn3yqWgRXG 1YJHrg==
    ;; Received 682 bytes from 2001:7fe::53#53(i.root-servers.net) in 40 ms
    
    http://WWW.RU.			345600	IN	NS	ns2.valuehost.RU.
    http://WWW.RU.			345600	IN	NS	ns1.valuehost.RU.
    http://WWW.RU.			345600	IN	NS	ns3.valuehost.RU.
    TDUI9D4JKUDS8B9T86GJ39PGFLCNLGM5.RU. 3600 IN NSEC3 1 1 3 00FF TEGFE4HCE6I000OFKHF21ET33KU8RGJM NS SOA RRSIG DNSKEY NSEC3PARAM
    TDUI9D4JKUDS8B9T86GJ39PGFLCNLGM5.RU. 3600 IN RRSIG NSEC3 8 2 3600 20180301193358 20180118043040 5448 ru. aTVP+fllBwi1EDpGcwJzmy9hS+Fb2VFiQeN+q+Dm+WzfMHZPhlRnOXdE aXMiBc1haqNhpVPsKHZ6EEz28G4vWYlsbx1/sWedz+955lS252GXRaiG uX0c5C71fgIcJT6Jv01EpkJqIygm3YLshtXraDvAoDGTzA4jMZxtQOIk DV0=
    2J7VCG14BBL5B5BBJVPBL4B0IETJ8HIR.RU. 3600 IN NSEC3 1 1 3 00FF 2M2IHV1UKI4KATRFSJ2HSA0EPPRS00K0 NS DS RRSIG
    2J7VCG14BBL5B5BBJVPBL4B0IETJ8HIR.RU. 3600 IN RRSIG NSEC3 8 2 3600 20180314120440 20180203063348 5448 ru. Njy3+a9i/eQDRSDuLHiIH63JgDXi7z14Mmk5AlSX4mTMH5B3IdAX72bG U7D+x5JAtP0xUJ62tMFeIb3mvU0eL1ssySRxH8Sm/lctbS/t3CfMbrVY JHRzqm3gM7HHtA+lTZBEZfYE+y18RGTBikWNfgwNrfH5ix2tsstkZC6O RoY=
    ;; Received 662 bytes from 193.232.156.17#53(f.dns.ripn.net) in 119 ms
    
    http://www.ru.			1800	IN	A	217.112.35.75
    http://www.ru.			1800	IN	NS	ns2.valuehost.ru.
    http://www.ru.			1800	IN	NS	ns1.valuehost.ru.
    http://www.ru.			1800	IN	NS	ns3.valuehost.ru.
    ;; Received 163 bytes from 217.112.35.107#53(ns2.valuehost.RU) in 9 ms

    Инфа от сюда: https://www.unbound.net/pipermail/unbound-users/2010-November/001489.html

Написать комментарий