
Поднимаем свой DNS сервер Unbound и блокировщик рекламы Pihole в docker
Обновлено 26.03.2025
Приветствую!
Как вы поняли из названия, сегодня мы установим и запустим в docker локальный DNS сервер Unbound в связке с блэкджеком.. блокировщиком рекламы посредством DNS запросов – Pi-hole. Все управление этим хозяйством будет производиться через удобный веб GUI программы Pi-hole. А в конце статьи покажу, как этот локальный DNS подключить к нашему VPN серверу на базе OpenConnect, который мы настроили ранее. Будет интересно и не сложно, почти)
Подписывайтесь на наш телеграм @r4ven_me📱, чтобы не пропустить новые публикации на сайте😉. А если есть вопросы или желание пообщаться по тематике – заглядывайте в Вороний чат @r4ven_me_chat🧐.
Все действия были протестированны в среде дистрибутивов Debian 12 и Ubuntu 22.04.
Введение
Unbound — это Open source продукт от компании NLnet Labs, представляющий собой удостоверяющий, рекурсивный и кэширующий DNS сервер. Распространяется под лицензией BSD.
Pi-hole — это Linux приложение для блокировки рекламы и интернет-трекеров на сетевом уровне, которое действует как DNS-sinkhole и, опционально, как DHCP-сервер. Обычно используется в частных сетях. Также имеет открытый код и распространяется под лицензией EUPL.
Те, кто уже знаком с Pihole — знают, что он тоже в своем арсенале имеет легковесный DNS сервер: Dnsmasq. Но он не поддерживает рекурсивные DNS запросы. Т.е. он изначально рассчитан на перессылку запросов на сторонний, рекурсивный DNS сервер, которым в нашем случае будет выступать Unbound, для получения данных об неизвестных адресах. Но Dnsmasq умеет кэшировать ответы и управлять локальными DNS записями.
Вот грубая схема взаимодействия:
Клиентский запрос –> Pihole:
- Адрес есть в локальном кэше –> ответ
- Адреса нет в локальном кэше –> перенаправление запроса в Unbound –> рекурсивный запрос через корневые сервера –> ответ –> сохранение в локальный кэш
Такой процесс работы DNS очень сильно повышает уровень конфиденциальности, т.к. первичный резолвинг выполняется через коренвые сервера напрямую и кэшурется уже на вашем собственном сервере.
Но стоит отметить, что такая схема работы имеет очевидный недостаток в виде задержки при выполнении рекурсивных запросов. Ускорить процесс можно настроив перенаправление на ближайший к вам сторонний публичный DNS сервер. Такой вариант тоже имеет место быть, особенно если шифровать запросы с помощью TLS. Но в таком случае вам придется довериться выбранному публичному DNS резолверу. Тут уже на ваше усмотрение.
Прошу обратить внимание, что данная статья не ставит целью разобрать все тонкости работы системы доменных имён и в частности сервера Unbound. Мы лишь разворачиваем личные сервисы 😉. Подразумевается, что у вас есть минимальное представление о технологии DNS.
Подготовка
Для развертывания сервисов нам требуется установленный Docker engine. Если он еще не установлен, то инструкция воть: Установка Docker engine на Linux сервер под управлением Debian
Теперь выполним некоторые подготовительные действия:
- получаем привилегии root и, в целях безопасности, создаем ограниченные в правах группу и сервисного пользователя —
pihole
для запуска контейнеров Pihole и Unbound:
sudo -s
addgroup --system --gid 14956 pihole
adduser --system --gecos 'Unbound and Pihole DNS service' \
--disabled-password --uid 14956 --ingroup pihole \
--shell /sbin/nologin --home /opt/pihole/data pihole
cd /opt/pihole
adgroup
– команда создания группы;
--system
– помечает группу, как системную и применяет к ней установленные политики;--gid 14956
– указывает явный идентификатор группы (GID) – в данном случае 14956;pihole
– название создаваемой группы;
adduser
– команда создания пользователя
--system
– помечает группу, как системную и применяет к ней установленные политики;--gecos
– позволяет задать описание пользователя;--disabled-password
– отключает пароль у пользователя (в таком случае под ним нельзя авторизоваться в системе с помощью пароля);--uid 14956
– указывает явный идентификатор пользователя (UID) – в данном случае 14956;--ingroup pihole
– добавляет пользователя в созданную ранее группу pihole;--shell /sbin/nologin
– в качестве оболочки пользователя устанавливает nologin – под ней невозможно авторизоваться в системе;--home /opt/pihole/data
– задает (и создает) домашний каталог пользователя, в нашем случае это директория с файлами сервисов pihole и unbound;pihole
– имя создаваемого пользователя.
- далее создадим отдельную внешнюю сеть docker, которая позволяет использовать ее контейнерами из разных docker compose файлов:
docker network create \
--opt com.docker.network.bridge.name=br_vpn \
--driver bridge --subnet 10.10.11.0/24 vpn_network
docker network ls
Как видно, мы создали сеть с адресацией 10.10.11.0/24, названием vpn_network и именем виртуального сетевого устройства-моста (bridge) — br_vpn:
На этом этапе подготовка завершена, приступаем к созданию файла описания сервисов-контейнеров docker.
Создание docker-compose.yml
Находясь в директории /opt/pihole
открываем новый файл на редактирование любым удобным консольным редактором. Мои читатели знают, что в качестве такового я предпочитаю Vim/Neovim.
Не премину сообщить, что у меня на сайте есть цикл статей про данный редактор. Найдёте их
у старого дубапо соответствующему тегу 😉
vim docker-compose.yml
И вставляем в него следующее содержимое:
---
networks:
vpn_network:
external: true
services:
unbound:
image: r4venme/unbound:1.17
container_name: unbound
restart: on-failure
stop_grace_period: 30s
# healthcheck:
# disable: true
deploy:
resources:
limits:
cpus: '0.70'
memory: 512M
reservations:
cpus: '0.2'
memory: 256M
logging: &default_logging
driver: json-file
options:
max-size: "50m"
max-file: "5"
cap_add:
- NET_ADMIN
hostname: "unbound"
environment:
TZ: "Europe/Moscow"
PUID: 14956
PGID: 14956
volumes:
- "./data/unbound/:/etc/unbound/"
expose:
- "53/udp"
- "53/tcp"
# ports:
# - "53:53/udp"
# - "53:53/tcp"
networks:
vpn_network:
ipv4_address: 10.10.11.200
aliases:
- unbound-server
pihole:
# depends_on: [unbound]
container_name: pihole
image: pihole/pihole:2025.03.0
restart: on-failure
stop_grace_period: 30s
deploy:
resources:
limits:
cpus: '0.70'
memory: 512M
reservations:
cpus: '0.2'
memory: 256M
logging: &default_logging
driver: json-file
options:
max-size: "50m"
max-file: "5"
cap_add:
- NET_ADMIN
# - SYS_TIME
# - SYS_NICE
hostname: pihole
dns:
- 10.10.11.200
- 10.10.11.200
environment:
TZ: "Europe/Moscow"
PIHOLE_UID: 14956
PIHOLE_GID: 14956
FTLCONF_webserver_api_password: 'pihole_password'
FTLCONF_dns_listeningMode: 'all'
FTLCONF_dns_upstreams: 10.10.11.200;10.10.11.200
volumes:
- "./data/pihole/:/etc/pihole/"
# - "./data/dnsmasq/:/etc/dnsmasq.d/"
expose:
- "53/tcp"
- "53/udp"
- "80/tcp"
ports:
- "127.0.0.1:8081:80"
# - "53:53/tcp"
# - "53:53/udp"
# - "80:80/tcp"
# - "443:443/tcp"
# - "67:67/udp"
# - "123:123/udp"
networks:
vpn_network:
ipv4_address: 10.10.11.100
aliases:
- pihole-dns
Обратите внимание, что контейнеры, описанные в файле
docker-compose.yml
намеренно ограничены в аппаратных ресурсах на использованиеcpus: '0.70'
иmemory: 512M
, т.е максимально разрешенное использование CPU составляет 70% одного ядра и 512 мб RAM + резерв. А также явно заданы ограничения на хранения логов контейнеров: 5 файлов по 50 мб на контейнер. При необходимости скорректируйте данные параметры в соответствии со своими потребностями. Подробнее про лимиты ресурсов сервисов при использовании docker compose читайте тут, а про логирование тут.
Актуальная версия файла docker-compose.yml
также доступна на GitHub.
Кратко пробежимся по содержимому.
На всякий случай ссылку на справку по наполнению файлов compose оставлю тут и в конце статьи.
- В блоке networks мы определяем сетевые параметры среды наших сервисов. Тут все стандартно, кроме параметра
external: true
, из-за которого мы и создавали нашу сеть на этапе подготовки. Это позволяет объединять сеть контейнеров из разных файлов docker compose.
- Далее идёт блок services. Тут мы описываем параметры наших сервисов-контейнеров DNS сервера Unbound и программы Pi-hole. Здесь желательно ничего не менять, ну кроме возможно вашей адресации и монтируемых volume.
- Важно четко задать IP адрес каждому контейнеру в параметре networks, и указать эти адреса в качестве environment в сервисе pihole. Все это нужно для корректного взаимодействия этих двух контейнеров.
- Обратите внимание, что директивой ports у сервиса pihole мы прокидываем 80 порт (веб GUI) в хостовую систему, которая будет прослушивать его по адресу 127.0.0.1:80, т.е. доступ к GUI будет только из среды самого сервера.
- Если будете настраивать доступ к веб GUI для доступа из локальной сети или из VPN, то замените 127.0.0.1 на существующий адрес сетевого интерфейса хоста. В случае доступа через интернет – настройте перенаправление портов по защищенному каналу, например SSH. Что мы и сделаем чуть позже.
- Если не указывать конкретный адрес, будет использован 0.0.0.0, что автоматически откроет данный порт наружу. А это, как известно, небезопасно, если ваш сервер доступен по внешнему IP.
- В блоке volume монтируются директории
/data/*
, в которых будут храниться служебные файлы сервисов, такие как конфиги сервера и исторические данные.
Ах да, еще один момент. В переменной FTLCONF_webserver_api_password: 'pihole_password'
задается пароль админа при входе в GUI pihole. Если оставить его пустым, то пароль сгенерируется автоматически.
По умолчанию в контейнере unbound механизм проверки работы сервиса реализован в виде резолвинга адреса
opennameserver.org
раз минуту. При желании эту проверку можно отключить с помощью соответствующего параметра вdocker-compose.yml
:healthcheck: disable: true
Теперь сохраняем файл и переходим к запуску контейнеров.
Запуск Pihole + Unbound
В директории проекта запускаем наши контейнеры такой командой:
docker compose up -d && docker compose logs -f
Вы должны увидеть статус запуска Pi-hole и работу процесса разрешения имен проходящих через Unbound:
Если все запустилось корректно, выходим из режима просмотра вывода контейнеров нажмитем Ctrl+c
.
Для просмотра статуса запущенных контейнеров воспользуемся командой:
docker compose ps
Сервисы зааущены, идем дальше.
Немного про конфигурацию Unbound
Внимательный читатель мог заметить, что в compose файле используется мой образ Unbound, про сборку которого я расскажу в отдельной статье.
При первом запуске контейнера Unbound в директории /opt/pihole/data/unbound
создаются файлы, необходимые для его работы:
root.key
— хранит корневой ключ DNSSEC для проверки подписанных ответов от корневых серверов. Он обновляется при каждом запуске контейнера, данные берутся с официального сайта организации IANA (Internet Assigned Numbers Authority): https://data.iana.org/root-anchors/root-anchors.xml;root.hints
— содержит список IP-адресов корневых DNS-серверов для начальной загрузки Unbound. Файл также обновляется при каждом запуске контейнера с официального ресурса организации InterNIC (подконтрольной IANA): https://www.internic.net/domain/named.cache;unbound.conf
— основной конфигурационный файл Unbound, определяющий параметры работы резолвера. По умолчанию в контейнере используется подготовленный мной файл конфигурации, который определяет работу Unbound, как рекурсивного (отправляющий запросы к корневым серверам) и кэширующего DNS сервера. Он хорошо прокомментирован, хоть и на английском. Отредактируйте его в соответствии с вашими нуждами.
Следующие файлы по умолчанию не используются и приведены в качестве примеров. Их можно подключить через директиву include
в основном конфиге unbound.conf
:
forward-records.conf
— пример правил перенаправления запросов запросов на сторонние DNS сервера (например8.8.8.8
) в т.ч. с использованием TLS;srv-records.conf
— пример SRV-записи, указывающие на расположение сервисов в сети;a-records.conf
— пример A-записи, сопоставляющие доменные имена с IPv4-адресами.
Например, чтобы настроить перенаправление всех запросов на сторонний сервер в файле unbound.conf
подключите файл forward-records.conf
:
include: "/etc/unbound/forward-records.conf"
В котором настройте перенаправление. Ниже пример перенаправления на opennameserver.org с использованием шифрования TLS (DOT):
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 217.160.70.42@853#ns1.opennameserver.org
forward-addr: 213.202.211.221@853#ns2.opennameserver.org
Для применения настроек нужно перезапустить контейнер Unbound:
docker compose restart unbound
Проверка работы DNS с локального хоста
Проверить работу DNS с явным указанием резолвера можно с помощью утилиты dig
из пакета dnsutils
:
# установка dig
apt update && apt install dnsutils
# запрос через pihole
dig @10.10.11.100 r4ven.me +short +answer +identify
# запрос через unbound
dig @10.10.11.200 r4ven.me +short +answer +identify

Обратите внимание на время получения ответа от первого запроса и последующего: это работа механизма кэширования DNS.
В логах Unbound должны быть видны запросы от контейнера Pihole (10.10.11.100) и наш прямой запрос с хоста, который до Unbound (10.10.11.200) идет через bridge (10.10.11.1) соединение, которое мы создали ранее:

Если включить подробный уровень логирования Unbound (параметр verbosity: 3
в unbound.conf
), то при первичных запросах вы увидите, как происходят рекурсивные запросы от Unbound к корневым серверам DNS.
Ранее я упоминал, что используемая в этой статье конфигурация Unbound поддерживает работу DNSSEC, которая обеспечивает достоверность получаемых ответов (при наличии соответствующей подписи у домена) с помощью проверки их подписи ключом root.key
.
Проверить, что Unbound использует DNSSEC можно выполнив запрос командой dig
непосредственно через контейнер Unbound. В ответе должен быть флаг ad
(authenticated data):
# нет dnssec (надо бы добавить)
dig @10.10.11.200 r4ven.me +answer +identify +dnssec | grep ';; flags'
# ничего не выведет
dig @10.10.11.200 r4ven.me +short DNSKEY
# есть подпись dnssec
dig @10.10.11.200 opennameserver.org +answer +identify +dnssec | grep ';; flags'
# выведет ключ подписи
dig @10.10.11.200 +short DNSKEY opennameserver.org
Обратите внимание, что DNSSEC не подразумевает шифрование передаваемых данных. За это отвечает механизм передачи DNS over TLS (DOT) или HTTPS (DOH).
Проверка работы DNS с внешних хостов
Если вам необходимо отправлять запросы на ваш DNS сервер извне, например из локальной сети, то раскомментируйте эти строки у сервиса pihole в docker-compose.yml
:
...
ports:
- "53:53/tcp"
- "53:53/udp"
...
И перезапустите сервисы:
docker compose down
docker compose up -d
Теперь к вашему DNS серверу можно обращаться по доступному IP вашего хоста. В моем примере хост, на котором развернут Unbound+Pihole доступен из локальной сети по адресу 192.168.122.192
:
# запрос через pihole
dig @192.168.122.192 r4ven.me +short +answer +identify
Всё работает👌.
Если ваша система, на которой подняты Pihole + Unbound использует systemd-resolved
, то вероятнее всего у вас не получиться забиндить 53 порт, т.к. он уже прослушивается на локальном интерфейсе: 127.0.0.1:53. В таком случае контейнер с pihole не запуститься. Тут у нас есть два варианта:
- отключить systemd-resolved;
- изменить локальный IP адрес прослушивания на внешний и перенаправить systemd-resolved на наш контейнеры с pihole и unbound — рассмотрим этот вариант.
Открываем конфиг:
vim /etc/systemd/resolved.conf
И меняем следующие параметры:
[Resolve]
DNS=10.10.11.100
FallbackDNS=10.10.11.200
DNSStubListenerExtra=192.168.122.192
Где:
- DNS — адрес нашего контейнера pihole;
- FallbackDNS — адрес контейнера unbound в качестве запасного DNS;
- DNSStubListenerExtra — адрес внешнего сетевого интерфейса, доступного из локальной сети.
Перезапускаем службу systemd-resolved
и проверяем изменился ли адрес:
systemctl restart systemd-resolved
ss -tuln | grep 53
Если у вас на сервере установлен фаервол, то необходимо открыть доступ к порту 53.
Также проверяем резолвинг DNS извне:
dig @192.168.122.192 r4ven.me +short +answer +identify
Ответ есть.
Ближе к концу статьи мы рассмотрим способы настройки DNS у клиентов. А пока настроим автозапуск нашего файла compose от сервисного пользователя pihole с помощью системы инициализации Systemd.
Настройка автозапуска с Systemd
Запускать сервисы будем от имени сервисной УЗ, которой предоставим возможность запускать две строго заданные команды от имени привилегированной группы docker.
Создаём файл-юнит сервиса:
vim /etc/systemd/system/pihole.service
И наполняем его:
[Unit]
Description=Pihole and Unbound DNS service
Requires=docker.service
After=docker.service
[Service]
Restart=on-failure
RestartSec=5
User=pihole
Group=pihole
ExecStart=/usr/bin/sudo --group=docker /usr/bin/docker compose -f /opt/pihole/docker-compose.yml up
ExecStop=/usr/bin/sudo --group=docker /usr/bin/docker compose -f /opt/pihole/docker-compose.yml down
[Install]
WantedBy=multi-user.target
Теперь создаем файл с перечнем ограниченных прав sudoers:
visudo -f /etc/sudoers.d/90_pihole
Команда
visudo
позволяет безопасно редактировать файлыsudoers
: в случае ошибки синтаксиса она выведет предупреждение и не позволит сохранить файл.
И наполняем:
Cmnd_Alias PIHOLE_DOCKER = \
/usr/bin/docker compose -f /opt/pihole/docker-compose.yml up, \
/usr/bin/docker compose -f /opt/pihole/docker-compose.yml down
pihole ALL = (:docker) NOPASSWD: PIHOLE_DOCKER
Для лучшего понимания механизма работы
sudo
и файловsudoers
рекомендую к прочтению мою статью: Командная строка Linux, повышение привилегий: команды su, sudo 😌.
Останавливаем запущенные вручную сервисы и активируем {авто}запуск уже с помощью Systemd:
docker compose down
systemctl enable --now pihole
systemctl status pihole
docker compose ps
На вид все рабочее👍 мы молодцы, переходим к веб GUI Pihole.
Подключение к веб GUI Pihole
Если вы разворачивали DNS сервер на машине, с которой и работаете, то просто перейдите по адресу http://localhost/admin
.
Если ваш DNS сервер находится удаленно, то с учётом того, что наш GUI слушает порт 80 на локальном порту сервера, необходимо настроить перенаправление портов с помощью SSH. Делается это для безопасного доступа к веб интерфейсу.
На клиентской машине открываем терминал и выполняем:
# прокидываем порт
ssh -4 -f -N -L 8081:localhost:80 user@example.com
Где:
-4
— использовать только IPv4, отключает попытки привязки к IPv6;-f
— отправляетssh
в фоновый режим после аутентификации;-N
— не выполнять команд на удалённом сервере, только установить туннель;-L
— ключ перенаправления локального порта;8081
– порт, который будет слушать клиентская машина и перенаправлять его на 80 порт сервера;localhost
— адрес сервера, на котором он слушает порт;80
— соответственно порт, на который перенаправляем;user@example.com
— пользователь и адрес сервера SSH.
И проверяем:
ss -tln | grep 8081
В моём примере команда перенаправления порта такая:

Теперь открываем браузер и переходим по адресу: http://localhost:8081/admin
Вводим пароль, заданный в переменной FTLCONF_webserver_api_password
, в моем примере это pihole_password
:
И попадаем в наш веб GUI:
Если в вашей системе отключен IPv6 (как у меня), то вероятно веб-интерфейс у вас не запуститься, а в логах контейнера pihole будут записи:
2025-03-26 10:10:00.913 MSK [51M] ERROR: Start of webserver failed!. Web interface will not be available! 2025-03-26 10:10:00.913 MSK [51M] ERROR: Error: Failed to setup server ports (error code 10.0) 2025-03-26 10:10:00.913 MSK [51M] ERROR: Hint: Check the webserver log at /var/log/pihole/webserver.log # ну а в файле /var/log/pihole/webserver.log: [2025-03-26 10:10:00.898 MSK 51] Initializing HTTP server on ports "80o,443os,[::]:80o,[::]:443os" [2025-03-26 10:10:00.906 MSK 51] cannot create socket (entry 3) [2025-03-26 10:10:00.912 MSK 51] cannot create socket (entry 4) [2025-03-26 10:10:00.912 MSK 51] Failed to setup server ports
Для исправления ситуации необходимо в конфиге pihole отключить использования http портов с IPv6 адреса:
vim /opt/pihole/data/pihole/pihole.toml
В блоке
[webserver]
заменить:# заменить эту строку: port = "80o,443os,[::]:80o,[::]:443os" # на эту: port = "80o,443os"
И перезапустить контейнер:
docker compose restart pihole
После чего вновь попробовать перейти по адресу
http://localhost:8081/admin
на клиенте.
Интерфейс pihole, как это принято говорить, интуитивно понятен. В контексте статьи нас тут интересуют локальные записи DNS и списки блокировки рекламных доменов.
Локальные записи DNS
Записи DNS расположены в разделе Local DNS 😉. Для теста добавим несколько новых:
И сразу проверим работу разрешения имен:
dig @10.10.11.100 pihole.r4ven.me +short +answer +identify
dig @10.10.11.100 unbound.r4ven.me +short +answer +identify
Списки блокировки рекламных доменов
Списки доменов для блокировки задаются в разделе Adlists
. Они представляют собой ссылку на текстовый файл с самим списком в формате hosts: ip_address domain_name
Блокировка достигается простым перенаправлением нежелательного доменного имени на адрес-заглушку 0.0.0.0
. Всё гениальное – просто)
Как видно на скриншоте, в Pi-hole уже добавлен один публичный список. Вы можете с легкостью добавлять сюда свои:
Или в файле /opt/pihole/data/pihole/adlists.list
.

Переходим к настройкам DNS на клиентах.
Настройка DNS на клиентах
В мире Linux существует множество способов настройки DNS на клиентах, что только запутывает многих пользователей. Я разберу лишь самые популярные способы.
Файл resolv.conf
Самый классический способ настройки DNS в Linux – это файл resolv.conf. Открываем его на редактирование:
vim /etc/resolv.conf
И добавляем запись. Важно чтобы она была выше уже существующих параметров nameserver
:
nameserver 192.168.122.192
Сохраняем, закрываем. Настройки подхватываются на лету.
Systemd-resolved
Во многих современных дистрибутивах Linux для управления DNS используется один из модулей systemd – systemd-resolved, о котором мы уже говорили.
Для редактирования параметров DNS открываем файл конфигурации:
vim /etc/systemd/resolved.conf
И в блоке Resolve
изменяем (или дополняем) директиву DNS=
:
[Resolve]
DNS=192.168.122.192
Сохраняем и перезапускаем службу + очищаем кэш DNS:
systemctl restart systemd-resolved
resolvectl flush-caches
По опыту, в случае systemd-resolved предпочтительным будет перезапустить систему целиком)
reboot
NetworkManager
А на десктопных линуксах, сетью, в т.ч. и параметрами DNS, управляет NetworkManager. Тут придется покликать мышкой.
Заходим в сетевые соединения через апплет на рабочем столе или через меню приложений:
Далее выбираем наше основное физическое соединение:
Переходим на вкладку настроек IPv4 и задаём адрес DNS сервера:
Готово)
Итоговая проверка
Для проверки корректности настроек DNS в случае resolve.conf и NetwrokManager выполняем:
nslookup r4ven.me
dig r4ven.me +short +answer +identify
Имя резолвится через локальный DNS, то, что нужно.
А в случае systemd-resolved команды такие:
resolvectl dns
resolvectl query r4ven.me
Отлично.
Теперь проверим добавленные ранее в веб интерфейсе Pi-hole DNS записи:
ping -c3 unbound.r4ven.me
ping -c3 pihole.r4ven.me
Как видим, на разных клиентах имена корректно резолвятся, даже если они недоступны😌.
Теперь перейдем к настройке DNS параметров на VPN сервере (если он у вас есть).
Настройка DNS в конфиге OpenConnect (ocserv)
Если вы настраивали ocserv по моей статье, то после добавления в схему DNS сервера, она будет выглядеть так:
Подразумевается, что openconnect
и pihole
+unbound
развернуты на одной машине. И так, для настройки связки первым делом необходимо добавить в compose файл проекта openconnect
:
vim /opt/openconnect/docker-compose.yml
Определение сети:
networks:
vpn_network:
external: true
А в параметры контейнер openconnect добавьте директиву networks:
...
networks:
- vpn_network
...
Теперь необходимо отредактировать конфиг файл самого сервера ocserv:
vim /opt/openconnect/data/ocserv.conf
Добавив значение параметра dns (первого):
Параметр
tunnel-all-dns
должен бытьtrue
.
После необходимо перечитать конфиг или перезапустить сервис OpenConnect любым способом:
# перечитывание конфига
docker exec -it openconnect occtl reload
# перезапуск контейнера
docker restart openconnect
# или
systemctl restart openconnect
А также переподключиться на клиентах и готово. Тереб все DNS запросы клиентов ocserv будут идти через докальный резолвер, который в свою очередь будет обращьтся к корневым серверам напрямую и формировать собственный кэш.
Заключение
Вот мы и настроили наш локальный DNS сервер на базе Unbound + Pi-hole. А также сконфигурировали обращение к нему клиентов. Дополнительно мы задали адрес DNS сервера в конфиге OpenConnect сервера, тем самым получив завершённое VPN решение.
Конечно мы с вами рассмотрели далеко не все возможности данного стека. Но повторюсь, такой цели и не ставилось. Pi-hole из коробки имеет множество интересных функций, например DHCP сервер, с настройкой в веб GUI и пр. Но это уже выходит за рамки данной статьи. Все источники на документацию вы найдёте ниже.
Подписывайтесь на наш канал в телеграм @r4ven_me чтобы не пропустить новые посты на сайте Вороний блог)
А если остались вопросы, добавляйтесь в наш чат там же: @r4ven_me_chat. Я стараюсь всегда отвечать в нём, в своё свободное время.
Спасибо, что читаете! Успехов вам в резолвинге имён 😉
Полезные источники
- Файлы проекта в моём репо на GitHub
- Официальный сайт проекта Unblound (EN)
- Статья про Unbound на ArchWiki
- Пример docker обараза Unbound (EN)
- Официальный сайт проекта Pi-hole (EN)
- Репозиторий docker образа Pihole (EN)
- Справка по docker-compose.yml (EN)
- Моя статья по настройке VPN сервера OpenConnect (ocserv)
- Установка Docker engine на Linux сервер под управлением Debian
Вопрос из чата в телеграм: “Чем различаются dnsmasq и unbound?”
Отличаются по функционалу. Unbound это полноценное DNS решение, резолвер, рекурсивный, кэширующий сервер и пр. + Поддержка протоколов безопасности, таких как DNSsec. Современный аналог популярного bind сервера.
В тоже время dnsmasq легковесный DNS сервер, но вроде как без резолвинга, только форвардинг и кэш. И включает в себя DHCP сервер. Небольшой комбайн)
Выбрал unbound в качестве сервера DNS, чтобы закрыть все потребности в таком инструменте
Если интересно именно про эту связку, вот статья с оф доки pihole
https://docs.pi-hole.net/guides/dns/unbound/
Unbound напрямую общается с корневыми серверам, в итоге предоставит истинный адрес в ответе. Что повышает конфиденциальность, но за счёт рекурсии, при первичных запросах может быть небольшая задержка. Но после данные все равно сохранятся в кэше.