Приветствую!
Как вы поняли из названия, сегодня мы установим и запустим локальный DNS сервер Unbound в связке с блэкджеком.. блокировщиком рекламы посредством DNS запросов – Pi-hole, с помощью docker. Все управление этим хозяйством будет производиться через удобный веб GUI программы Pi-hole. Ну и соответственно, мы подключим этот локальный DNS к нашему VPN серверу на базе OpenConnect, который мы настроили ранее. Будет интересно и не сложно, честно)
Присоединяйтесь к нашему каналу в телеграм: t.me/r4ven_me, уведомления о новых постах приходят туда в день публикации. А если у вас есть вопросы или просто желание пообщаться по тематике – заглядывайте в чат: t.me/r4ven_me_chat.
Все действия были протестированны в среде дистрибутивов Debian 12 и Ubuntu 22.04.
Короткое введение
Unbound — это Open source продукт от компании NLnet Labs, представляющий собой удостоверяющий, рекурсивный и кэширующий DNS сервер. Распространяется под лицензией BSD.
Pi-hole — это Linux приложение для блокировки рекламы и интернет-трекеров на сетевом уровне, которое действует как DNS-sinkhole и, опционально, как DHCP-сервер. Обычно используется в частных сетях. Также имеет открытый код и распространяется под лицензией EUPL.
Прошу обратить внимание, что данная статья не ставит целью разобрать все тонкости работы системы доменных имён и в частности сервера Unbound. Мы лишь разворачиваем личные сервисы ;) Подразумевается, что у вас есть минимальное представление о данной технологии.
Подготовка
Для развертывания сервисов нам требуется установленный Docker engine. Если он еще не установлен, то инструкция воть: Установка Docker engine на Linux сервер под управлением Debian
Теперь выполним некоторые подготовительные действия:
- получаем привилегии root и создаём директории и файлы проекта:
sudo -s
mkdir -p /opt/pihole/{pihole_data,unbound_data} && cd /opt/pihole
touch ./unbound_data/{a,srv,forward}-records.conf
Создание пустых файлов *-records.conf необходимо для сервиса unbound, который не запуститься без них)
- далее создадим отдельную сеть docker для объединения контейнеров из разных сервисов:
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
Открываем новый файл на редактирование любым удобным консольным редактором. Мои читатели знают, что в качестве такового я предпочитаю Vim/Neovim.
Не премину сообщить, что у меня на сайте есть цикл статей про данный редактор. Найдёте иху старого дубапо соответствующему тегу ;)
vim docker-compose.yml
И вставляем в него следующее содержимое файл из моего GitHub.
Кратко пробежимся по содержимому. На всякий ссылку на справку по наполнению файлов compose оставлю тут и в конце статьи.
В блоке networks мы определяем сетевые параметры среды наших сервисов. Тут все стандартно, кроме параметра external: true из-за которого мы и создавали нашу сеть на этапе подготовки. Без предварительного создания сети, сервисы 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.
Ах да, еще один момент. В переменной WEBPASSWORD: "" можно задать пароль админа при входе в GUI pihole. Если оставить его пустым, вход будет, как очевидно, без авторизации.
Теперь сохраняем файл и переходим к запуску контейнеров.
Запуск Pihole + Unbound
В директории проекта запускаем наши контейнеры такой командой:
docker compose up -d && docker compose logs -f
Вы увидите нечто подобное:
Если все запустилось корректно, выходим из режима просмотра вывода контейнеров нажмитем Ctrl+c.
Для просмотра статуса запущенных контейнеров воспользуемся командой:
docker compose ps
Всё работает, всё корректно. Сразу настроим автозапуск.
Настройка автозапуска с systemd
Создаём файл сервиса:
vim /etc/systemd/system/pihole.service
Наполняем его содержимым другого файла с моего GitHub.
Останавливаем запущенные вручную сервисы и активируем {авто}запуск уже с помощью systemd:
docker compose down
systemctl enable --now pihole
systemctl status pihole
docker compose ps
На вид рабочее) мы молодцы, переходим к веб GUI.
Подключение к веб GUI
Если вы разворачивали DNS сервер на машине, с которой и работаете, то просто перейдите по адресу http://localhost/admin.
Если ваш DNS сервер находится удаленно, то с учётом того, что наш GUI слушает порт 80 на локальном порту сервера, необходимо настроить перенаправление портов с помощью SSH. Делается это для безопасного доступа к веб интерфейсу.
На клиенте открываем терминал и выполняем:
ssh -L 8080:localhost:80 user@example.com
Где:
- -L – ключ перенаправления локального порта;
- 8080 – порт, который будет слушать клиентская машина и перенаправлять его на 80 порт сервера;
- localhost – адрес сервера, на котором он слушает порт;
- 80 – соответственно порт, на который перенаправляем;
- user@example.com – пользователь и адрес сервера SSH.
В моём примере команда такая:
Теперь открываем браузер и переходим по адресу: http://localhost:8080/admin
И попадаем в наш веб GUI:
Интерфейс, как это принято говорить, интуитивно понятен. Нас тут интересует локальные записи DNS и списки блокировки рекламных доменов.
Записи DNS расположены в разделе Local DNS ;) Для теста добавим несколько новых:
К слову, основной конфиг файл сервера Unbound лежит по пути /opt/pihole/unbound_data/unbound.conf.
Списки доменов для блокировки задаются в разделе Adlists. Они представляют собой ссылку на текстовый файл с самим списком в формате hosts: ip_address domain_name
Блокировка достигается простым перенаправлением нежелательного доменного имени на адрес-заглушку 0.0.0.0. Всё гениальное – просто)
Как видно на скриншоте, в Pi-hole уже добавлен один публичный список. Вы можете с легкостью добавлять сюда свои:
Или в файле /opt/pihole/pihole_data/adlists.list.
Переходим к настройкам DNS на клиентах.
Настройка DNS на клиентах
В мире Linux существует множество способов настройки DNS на клиентах, что только запутывает многих пользователей. Я разберу лишь самые популярные способы.
Файл resolv.conf
Самый классический способ настройки DNS в Linux – это файл resolv.conf. Открываем его на редактирование:
vim /etc/resolv.conf
И добавляем запись. Важно чтобы она была выше уже существующих параметров nameserver:
nameserver 10.10.11.100
Сохраняем, закрываем. Настройки подхватываются на лету.
Systemd-resolved
Во многих современных дистрибутивах Linux для управления DNS используется один из модулей systemd – systemd-resolved.
Для редактирования параметров DNS открываем файл конфигурации:
vim /etc/systemd/resolved.conf
И изменяем (или дополняем) директиву DNS=:
Сохраняем и перезапускаем службу + очищаем кэш DNS:
systemctl restart systemd-resolved
resolvectl flush-caches
По опыту, в случае systemd-resolved предпочтительным будет перезапустить систему целиком)
reboot
NetworkManager
А на десктопных линуксах, сетью, в т.ч. и параметрами DNS, управляет NetworkManager. Тут придется покликать мышкой.
Заходим в сетевые соединения через апплет на рабочем столе или через меню приложений:
Далее выбираем наше основное физическое соединение:
Переходим на вкладку настроек IPv4 и задаём адрес DNS сервера:
Готово)
Проверка
Для проверки корректности настроек DNS в случае resolve.conf и NetwrokManager выполняем:
nslookup google.ru
Имя резолвится через локальный DNS, то, что нужно.
А в случае systemd-resolved команды такие:
resolvectl dns
resolvectl query google.ru
Отлично.
Теперь проверим добавленные ранее в веб интерфейсе Pi-hole DNS записи:
ping -c3 dns.r4ven.me
ping -c3 localhost.r4ven.me
Работает!
Теперь перейдем к настройке DNS параметров на VPN сервере (если он у вас есть).
Настройка DNS в конфиге OpenConnect (ocserv)
Если вы настраивали ocserv по моей статье, то после добавления в схему DNS сервера, она будет выглядеть так:
И так, для настройки связки ocserv c pihole+unbound первым делом необходимо добавить в compose файл проекта:
vim /opt/openconnect/docker-compose.yml
Определение сети:
А в параметры контейнеров добавьте директиву networks:
Добавив значение параметра dns (первого):
Теперь необходимо отредактировать конфиг файл самого сервера ocserv:
vim /opt/openconnect/data/ocserv.conf
После необходимо перечитать конфиг или перезапустить сервис OpenConnect любым способом:
# перечитывание конфига
docker exec -it openconnect occtl reload
# перезапуск контейнера
docker restart openconnect
# или
systemctl restart openconnect
А также переподключиться на клиентах и готово.
Заключение
Вот мы и настроили наш локальный DNS сервер на базе Unbound + Pi-hole. А также сконфигурировали обращение к нему клиентов. Дополнительно мы задали адрес DNS сервера в конфиге OpenConnect сервера, тем самым получив завершённое VPN решение.
Конечно мы с вами рассмотрели далеко не все возможности данного стека. Но повторюсь, такой цели и не ставилось. Pi-hole из коробки имеет множество интересных функций, например DHCP сервер, с настройкой в веб GUI и пр. Но это уже выходит за рамки данной статьи. Все источники на документацию вы найдёте ниже.
Подписывайтесь на наш канал в телеграм @r4ven_me чтобы не пропустить новые посты на сайте Вороний блог)
А если остались вопросы, добавляйтесь в наш чат там же: @r4ven_me_chat. Я стараюсь всегда отвечать в нём, в своё свободное время.
Спасибо, что читаете! Успехов вам в резолвинге имён ;)
Полезные источники
Мои ссылки:
- Мой основной сайт - r4ven.me
- Мой телеграм - t.me/r4ven_me