notby.NET Logo

Безопасный DNS сервер Unbound в FreeBSD 14.1

Использовать собственный DNS сервер для локальной сети или своего VPN сервера в режиме переадресации запросов на публичный DNS сервер через защищенный протокол DoT (DNS-over-TLS) полезно и эффективно для кэширования запросов и сокращения их количества, блокировки рекламных доменов, повышения безопасности и защищенности пользователей внутри локальной сети и самого DNS сервера. Для всех этих задач идеально подойдет DNS сервер Unbound.

По умолчанию прокол DNS использует 53 порт, и весь трафик передается в открытом незащищенном виде. Если указать на устройстве в качестве DNS сервера публичный DNS сервер (например 1.1.1.1), то трафик будет передаватся в открытом виде используя 53 порт. Интернет провайдеры, операторы связи или злоумышленник (MITM-атака) будут лицезреть к какому домену произошло обращение и смогут подменить запрос по какому IP-адресу обращается к сайту или сервису.

Для решения этой проблемы безопасности были разработаны защищённые DNS протоколы DoH (DNS-over-HTTPS), DoT (DNS-over-TLS). Данные протоколы можно настроить на части устройств (телефоны, компьютеры), а на некоторых устройствах (телевизоры и TV-приставки) настройка затруднительна или вовсе невозможна. Логичнее и проще использовать свой DNS сервер Unbound, который будет переадресовывать DNS запросы локальной сети, своего VPN и самого сервера FreeBSD на публичные DNS сервера по защищенному протоколу. Дополнительно можно настроить блокировку рекламы.

1. Установка Unbound

Устанавливаем через пакеты

pkg install unbound
Установка Unbound версии 1.22.0 через пакеты FreeBSD при помощи команды pkg install unbound

Или устанавливаем из портов, с нужными опциями

cd /usr/ports/dns/unbound/ && make install clean
Установка Unbound версии 1.22.0 из портов FreeBSD, выбор параметров сборки

Дожидаемся окончания установки.

2. Установка ca_root_nss

Для проверки подлинности сертификата сервера DoT, необходимо установить пакет корневых сертификатов Mozilla. В FreeBSD он называется ca_root_nss.

Устанавливаем через пакеты

pkg install ca_root_nss

Или устанавливаем из портов

cd /usr/ports/security/ca_root_nss/ && make install clean
Установлены корневые сертификаты ca_root_nss, выведено сообщение с информацией после их установки

Дожидаемся окончания установки.

После установки корневых сертификатов, файл с ними будет находится по адресу

/usr/local/share/certs/ca-root-nss.crt

На него также будет несколько символьных ссылок

/etc/ssl/cert.pem
/usr/local/etc/ssl/cert.pem
/usr/local/openssl/cert.pem

3. Настройка и конфигурация Unbound

Основной файл конфигурации unbound.conf находится по адресу /usr/local/etc/unbound/unbound.conf

Открываем файл конфигурации и редактируем его

nano /usr/local/etc/unbound/unbound.conf

В данной конфигурации будут описаны основные параметры для настройки своего DNS сервера Unbound внутри локальной сети в режиме переадресации запросов через DNS-over-TLS на публичный DNS сервер.

Строки относящиеся к своему VPN серверу, настройки выдачи IP адресов для домена, черный список доменов показаны как пример возможной настройки и их указывать необязательно, если нечего из этого не планируется использовать.

### Настройка DNS сервера Unbound ###
server:
	# Интерфейсы прослушивания DNS сервером Unbound. По умолчанию localhost (127.0.0.1 и ::1)
	# Для прослушивания всех интерфейсов необходимо указать 0.0.0.0 и ::0
	# IP-адрес localhost (127.0.0.1)
	interface: 127.0.0.1
	# IP-адрес сетевой карты локальной сети (192.168.0.1 в моем случае)
	interface: 192.168.0.1
	# Интерфейс VPN сервера (WireGuard в моем случае) или его IP-адрес
	#interface: wg0

	# Разрешаем использовать IPv4. По умолчанию: yes (включено)
	do-ip4: yes
	# Запрещаем использовать IPv6. По умолчанию: yes (включено)
	do-ip6: no

	# Разрешаем доступ к DNS серверу IP-адресам локальной сети (192.168.0.0/24 в моем случае)
	access-control: 192.168.0.0/24 allow
	# Разрешаем доступ к DNS серверу всем клиентам VPN (wg0 в моем случае)
	#access-control: wg0 allow

	# Имя пользователя от которого запускать Unbound
	username: unbound
	# Chroot, рабочий каталог и файл pid
	chroot: /usr/local/etc/unbound
	directory: /usr/local/etc/unbound
	pidfile: /usr/local/etc/unbound/unbound.pid

	# Не отвечать на запросы о сведениях, версии DNS сервера Unbound
	hide-identity: yes
	hide-version: yes
	
	# Исключаем из ответов DNS сервера адреса диапазона частных IP-адресов
	# Это необходимо для защиты от уязвимости "DNS rebinding"
	private-address: 10.0.0.0/8
	private-address: 172.16.0.0/12
	private-address: 192.168.0.0/16
	private-address: 169.254.0.0/16
	private-address: fd00::/8
	private-address: fe80::/10
	private-address: ::ffff:0:0/96
	
	# Путь до корневых сертификатов в системе
	tls-cert-bundle: /usr/local/share/certs/ca-root-nss.crt
	
	# Выдаваем для домена свой IP-адрес (аналог hosts)
	#local-zone: "notby.net." redirect
	#local-data: "notby.net. IN A 192.168.0.1"
	
	# Подключение файла черного списка доменов (подробнее в 8 разделе статьи)
	#include: /usr/local/etc/unbound/blacklist.conf

### Настройка переадресации через протокол DoT на публичный DNS сервер ###
# Настройка зоны переадресации:
forward-zone:
	name: "."			# Все доменные зоны и домены
	forward-tls-upstream: yes	# Использовать DNS-over-TLS
	# Указывать домены через # после 853 порта обязательно!
	# Адрес публичного DNS сервера использующих протокол DoT:
	# CloudFlare DNS
	forward-addr: 1.1.1.1@853#one.one.one.one
	forward-addr: 1.0.0.1@853#one.one.one.one
	# Google DNS
	#forward-addr: 8.8.8.8@853#dns.google
	#forward-addr: 8.8.4.4@853#dns.google
	# Wikimedia DNS
	#forward-addr: 185.71.138.138@853#wikimedia-dns.org

Вносим необходимые измерения и сохраняем файл. На этом основная настройка DNS сервера Unbound завершена.

4. Автозагрузка и запуск Unbound

Добавляем в автозагрузку

sysrc unbound_enable="YES"

Или вручную открываем файл /etc/rc.conf и добавляем строку unbound_enable="YES"

Запускаем Unbound DNS сервер

service unbound start
DNS сервер Unbound добавлен в автозагрузку командой “sysrc unbound_enable=YES” и запущен командой “service unbound start” в FreeBSD

DNS сервер успешно запущен. Если будут ошибки, то они будут выведены в момент запуска и подробно описаны.

Для перезагрузки Unbound используем команду

service unbound restart

5. Проверка DNS сервера Unbound

5.1. Проверка с сервера FreeBSD

На сервер FreeBSD выполняем DNS запрос через утилиту drill

drill @127.0.0.1 notby.net
  • @127.0.0.1 – IP-адрес DNS сервера, который необходимо использовать;
  • notby.net – доменное имя, для которого происходит DNS запрос.
Проверка DNS командой “drill @127.0.0.1 notby.net” в консоли FreeBSD для домена notby.net через DNS сервер 127.0.0.1 (localhost). Получен успешный ответ DNS сервера и отображена информация об DNS зоне домена

Как можно видеть, информация о DNS записях домена успешно выведена.

5.2. Проверка с устройств локальной сети

Теперь необходимо проверить что DNS сервер доступен и отвечает на запросы компьютеров локальной или Wi-Fi сети.

В операционной системе Linux выполняем DNS запрос через утилиту dig

dig @192.168.0.1 notby.net

где 192.168.0.1 – IP-адрес DNS сервера в локальной сети.

Проверка DNS командой “dig @192.168.0.1 notby.net +nocmd +nocomments” в консоли Debian для домена notby.net через DNS сервер локальной сети. Успешный ответ DNS сервера, отображены записи A для домена, а время ответа DNS составляет 0мс

Время ответа DNS сервера для данного запроса получился менее 1мс, так как данные DNS данного домена уже были получены и кэшированы ранее при проверке с сервера FreeBSD.

В операционной системе Windows выполняем DNS запрос через утилиту nslookup

nslookup notby.net 192.168.0.1

При работе через nslookup адрес DNS сервера необходимо писать в самом конце.

6. Настройка DNS клиента в FreeBSD

Теперь необходимо настроить FreeBSD сервер, чтобы он использовал Unbound в качестве DNS сервера.

Открываем файл настройки DNS клиента

nano /etc/resolv.conf

Изменяем значение параметра nameserver на 127.0.0.1

nameserver 127.0.0.1

Сохраняем и закрываем файл.

Проверяем что сервер начал использовать локальный DNS сервер Unbound

drill | grep SERVER

в результате выполнения данной команды должен быть выведен локальный IP-адрес 127.0.0.1

;; SERVER: 127.0.0.1

Аналогично настраиваем устройства локальной сети или Wi-Fi, но в качестве DNS указываем IP-адрес DNS сервера Unbound.

Если в локальной сети используется DHCP сервер, то изменяем его настройки, чтобы он выдавал IP-адрес DNS сервера Unbound.

Читай как настроить DCHP сервер в FreeBSD: Настройка DHCP-сервера ISC-DHCP в FreeBSD

7. Запрет доступа к любым DNS серверам по 53 порту

Для повышения безопасности, анонимности сервера и устройств локальной и Wi-Fi сети можно полностью запретить доступ к любым внешним DNS серверам по открытому незащищенному каналу, то есть заблокировать любой исходящий трафик по 53 порту.

В качестве файрвола и маршрутизатора у меня на сервере используется IPFW, поэтому пример запрета будет показан на основе него.

Читай как настраивать файрвол IPFW и маршрутизацию в FreeBSD: Настройка IPFW + NAT в FreeBSD, Настройка файрвола IPFW в FreeBSD

Выводим список правил IPFW

ipfw list

Правило, блокирующее исходящий внешний DNS трафик на 53 порт по протоколам TCP и UDP, необходимо добавить выше по номеру, чем правила которые разрешают прохождение трафика.

ipfw -q add 250 deny ip from any to any 53 out

где 250 (в моем случае) – номер под которым будет добавлено правило в список IPFW.

Проверяем что доступ к DNS серверу Unbound есть с компьютеров локальной сети и самого сервера

drill -Q notby.net

Проверяем что доступ отсутствует к любому другому DNS серверу (например 1.1.1.1) по открытому протоколу

drill -Q @1.1.1.1 notby.net
DNS запись для домена notby.net через локальный DNS сервер успешно получена командой “drill notby.net” в консоли FreeBSD, а получение тех же DNS записей через сервер 1.1.1.1 закончилось ошибкой Error: error sending query: Error creating socket

Как можно видеть, доступ к внешнему DNS серверу получить не удалось.

Теперь можно добавить правило блокировки DNS в файл конфигурации файрвола IPFW и перезапустить его

nano /etc/ipfw.rules
service ipfw restart

8. Черный список доменов (блокировка рекламы)

Unbound может блокировать выборочно домены или целые доменные зоны. Это может быть полезно если необходимо закрыть доступ до определенных сайтов или заблокировать рекламные домены.

8.1. Файл blacklist.conf

Для удобства создаем отдельный файл blacklist.conf в каталоге /usr/local/etc/unbound/

touch /usr/local/etc/unbound/blacklist.conf

Открываем файл blacklist.conf

nano /usr/local/etc/unbound/blacklist.conf

Например, заблокируем домен example.com и example.net. Для этого добавляем строки:

local-zone: "example.com" always_refuse
local-zone: "example.net" always_refuse

Параметр always_refuse означает, что DNS сервер всегда будет отказывать на запросы IP-адреса домена и другие.

Для каждого домена который нужно заблокировать необходимо использовать отдельную строку.

Вносим необходимый список доменов, которые необходимо заблокировать и сохраняем файл.

8.2. Подключение файла blacklist.conf

Открываем основной конфигурационный файл unbound.conf

nano /usr/local/etc/unbound/unbound.conf

Добавляем строку или раскомментируем её, если использовался конфиг файл с данной статьи

include: /usr/local/etc/unbound/blacklist.conf

Обязательно подключать файл blacklist.conf в разделе server: конфигурационного файла unbound.conf

Очищаем кеш и перезагружаем настройки Unbound

service unbound reload

8.3. Проверка заблокированного домена

Выполняем DNS запрос к заблокированному домену

drill -Q @127.0.0.1 example.com
  • -Q – вывод только IP-адреса домена;
  • @127.0.0.1 – IP-адрес DNS сервера Unbound;
  • example.com – доменное имя, для которого происходит DNS запрос.

При правильной настройке, вывод для команды выше будет пустой.

8.4.  Блокировка рекламы (конвертация hosts файла)

Различные сервисы по блокировке рекламы довольно часто основываются на списке рекламных доменов. Блокировка происходит на уровне доменов. Эти списки в формате hosts файла без проблем можно скачать в интернете и они имеют следующий вид:

0.0.0.0		ads-banner.com
0.0.0.0		ads.banner.net
0.0.0.0		advertise.com

Скачиваем hosts файла со списком заблокированных доменов в удобное место. Теперь необходимо преобразовать hosts файл в понятный формат для Unbound.

Выполняем конвертацию hosts файла в формат DNS сервера Unbound

grep '^0\.0\.0\.0' /tmp/ads_hosts | awk '{print "local-zone: \""$2"\" always_refuse"}' > /usr/local/etc/unbound/blacklist.conf
  • /tmp/ads_hosts – путь до скачанного hosts файла;
  • /usr/local/etc/unbound/blacklist.conf – путь до файла blacklist.conf ранее созданного.

Обрати внимание, что данная команда полностью перезапишет файл blacklist.conf и удалит вручную заблокированные домены. Если это недопустимо, используй разные имена файлов.

После выполнения конвертации, перезагружаем настройки DNS сервера Unbound и проверяем что реклама пропала…

service unbound reload