Для начала поговорим о том, для чего нужен локальный 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:
Редактируем файл /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 через TLS (см.
список серверов ниже)
ssl-upstream: yes
Если нам всё же хочется использовать форвард в другой dns-сервер (при этом стоит понимать, что unbound всё ещё будет делать prefetch для записей в кэше, даже при включенном форварде), то добавляем в конфиг такие буквы (сторонние сервера, само собой, можете указать другие):
name: "."
forward-addr: 8.8.4.4
forward-addr: 8.8.8.8
Если же вам хочется dns загнать через tls, то добавляем кусок конфига ниже (вместо куска конфига выше, само собой). Все коннекты к этим серверам (а значит, и все записи, которыми вы обмениваетесь) будут зашифрованы. Это ещё не dnscrypt, который вовсе не подвержен MItM, но и не plain-dns, который спуфят все, кому ни лень.
Я привожу рабочий список tls-серверов, но они «чьи-то». Вы скрываете свой dns-трафик от провайдера, но дарите его кому-то ещё, имейте в виду.
name: "."
forward-addr: 1.1.1.1@853 # CloudFlare
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
Потестируем наш резолвер (если команды host нет — поставьте пакет bind9-host) на записи, которая уже в кеше локально:
....
real 0m0,006s
user 0m0,004s
sys 0m0,000s
Сравним с 8.8.8.8:
...
real 0m0,090s
user 0m0,004s
sys 0m0,000s
И это — при RTT в 5ms до адреса 8.8.8.8. Экономия — 80мс.
Остаётся самая малость, заставить систему использовать наш резолвер. Для начала выясняем, является ли /etc/resolv.conf симлинком куда-то там:
/etc/resolv.conf: symbolic link to ...
Если видим такую надпись — делаем так:
Тем самым мы запрещаем всяким NetworkManager-ам менять этот файл. Ну а сам файл создаём и приводим к такому виду:
Если беспокоимся о том, что unbound упадёт и резолв сломается, то оставляем резервом другие резолверы:
nameserver 8.8.8.8
nameserver 8.8.4.4
Если у вас systemd (ubuntu 16+, debian 8+), то resolv.conf нужно «применять» перезапуском сервиса resolvconf:
Ну а почитать все возможные опции советую на официальном сайте — https://www.unbound.net/documentation/unbound.conf.html, может там ещё что интересное валяется.
Для клиентов в администрируемой сети (а локалхост точно из этих) следующий параметр:
лучше заменить на:
Это помогает в дебаге:
До:
После:
Инфа от сюда: https://www.unbound.net/pipermail/unbound-users/2010-November/001489.html