Свой DNS с блокировкой рекламы: AdGuard Home + MikroTik

Реклама на сайтах бесит — это факт. Ставить блокировщик в каждый браузер и на каждый телефон лень, а хочется, чтобы резалось сразу для всей домашней сети: и ноутбук, и телевизор, и гостевой Wi-Fi.
Решение подсмотрел у ребят из Fatmetal — у них есть разбор, как поднять AdGuard Home на VPS с шифрованным DNS. Идея зашла, но я пошёл чуть дальше: вместо «DNS для телефона в любой сети» сделал «DNS для всей домашней сети через роутер». Дальше — что получилось, на какие грабли наступил и почему результат честно не стопроцентный.
Что вообще за AdGuard Home
Это DNS-сервер с фильтрацией. Он принимает запросы от клиентов, сверяет домены со списками блокировки и возвращает 0.0.0.0 для рекламы и трекеров. Всё, что не заблокировано, форвардит наверх — в моём случае на Quad9.
Работает на уровне сети: не нужно ставить приложения на каждое устройство. Телевизор, лампочки, приставка — всё, что ходит через этот DNS, автоматически получает чистый интернет.
Один бинарник на Go, ~43 MiB RAM в простое, конфиг — один YAML. Очень лёгкий.
Схема у меня
LAN-клиенты (192.168.x.x)
↓ DNS по DHCP = роутер
MikroTik (роутер)
↓ DoH (DNS over HTTPS)
dns.example (Caddy, валидный TLS)
↓ reverse_proxy
AdGuard Home (LXC, 10.0.0.22)
↓ апстрим DoH
Quad9 (9.9.9.9)
Клиенты даже не знают, что существует AdGuard: по DHCP они получают адрес роутера, а роутер уже сам ходит на наш DNS через шифрованный DoH. Одна настройка на роутере — и вся сеть фильтруется.
Как ставил
Шаг 1. AdGuard Home в LXC. У меня Proxmox, поэтому поднял отдельный контейнер: Ubuntu 26.04, один бинарник AdGuard Home v0.107.79 в /opt/AdGuardHome, systemd-сервис.
Первая засада: вручную написанный YAML сервис не принял («cannot construct !!seq into home.clientsConfig») — в свежих версиях схема конфига поменялась. Лечится просто: запустил AdGuard без конфига, он сам поднял мастер на порту 3000, я прошёл его через API — и только потом доправил YAML под себя. Урок: не пишите конфиг руками, дайте сервису сгенерить.
Шаг 2. DoH. По задумке у Fatmetal AdGuard сам терминирует TLS (DoH на 443, DoT/DoQ на 853). Я попробовал так же — и упёрся в то, что самоподписанный сертификат AdGuard отвергает («validating certificate pair: empty certificate»). А выпускать Let's Encrypt на сам AdGuard — лишняя возня, когда у меня уже есть Caddy, который умеет TLS из коробки.
Поэтому схему упростил: TLS терминирует Caddy на поддомене dns.example, а внутри сети гонит plain HTTP на AdGuard (у него есть режим insecure DoH ровно для reverse-proxy). Снаружи клиент видит валидный сертификат, внутри — ничего шифровать не надо.
Шаг 3. MikroTik. На роутере одна команда:
/ip dns set use-doh-server="https://dns.example/dns-query" servers="9.9.9.9,149.112.112.112"
servers оставил как фолбек: если наш DNS ляжет — роутер продолжит резолвить через Quad9 напрямую. DNS — критичный сервис, если он умрёт, «пропадёт интернет» на всех устройствах. Поэтому фолбек обязателен.
Грабли, на которые наступил
Грабля №1: роутер не может ходить на свой же внешний IP. MikroTik резолвил dns.example в свой WAN-адрес, шёл на него сам — и ничего не работало (hairpin NAT для собственного трафика не действует). Решение: статическая запись на роутере, которая ведёт dns.example прямо на Caddy через WireGuard-туннель:
/ip dns static add name="dns.example" address=10.99.0.2 comment="adguard-doh-via-wg"
Грабля №2: allow-remote-requests=no ломает DNS для всей LAN. Я решил «закрыть порт 53 наружу» этой настройкой — и клиенты в локалке перестали резолвить вообще. На RouterOS 7 эта опция отключает ответы DNS-сервера не только снаружи, но и для локальных сетей. Вернул yes, а снаружи порт 53 закрыл штатно — правилом firewall. Урок: на MikroTik не закрывайте DNS через allow-remote-requests, только через firewall.
Грабля №3: белый список внутри фильтра. Домен www.googleadservices.com (это Google Ads) упорно проходил — в самом списке AdGuard DNS filter оказалось whitelist-правило @@||www.googleadservices.com^|. Обычное правило блокировки его не перебивало. Лечится модификатором $important, который имеет приоритет над whitelist:
||www.googleadservices.com^$important
Грабля №4: кэш. После добавления правил реклама всё равно видна — потому что телефон и браузер закешировали реальные IP рекламных доменов ещё до блокировки. Инкогнито помогает от кэша браузера, но не от DNS-кэша ОС. Лечится временем или перезагрузкой устройства.
Что добавил для отечественной рекламы
Базовый список AdGuard DNS filter (178 тысяч правил) — хорошо, но российские рекламные сети в нём покрыты не полностью. Дописал свои правила в user_rules:
ads.adfox.ru,adfox.ru— AdFox, рекламная сеть Яндекса (баннеры на новостных сайтах)an.yandex.ru,yabs.yandex.ru— Яндекс.Директ24smi.net— виджеты и видео 24СМИtop-fwz1.mail.ru— счётчик Mail.rucounter.yadro.ru— счётчик Яндекс.Метрики (спорно: это аналитика, но она же трекинг)wcm.weborama-tech.ru— Weboramaad.adriver.ru— AdRiver
Проверял на живых сайтах: rzn.info, 7info.ru — после правок их рекламные домены резолвятся в 0.0.0.0.
А теперь честно про результат
Работает: вся реклама, которая живёт на отдельных доменах (AdFox, Директ, 24СМИ, Google Ads), режется на уровне DNS для всех устройств в сети разом. Это, кстати, большая часть того, что бесит на новостных сайтах.
Не работает:
– Реклама с CDN самого сайта. Часть баннеров новостники отдают со своих же доменов (cdn1.rzn.info и т.п.). DNS-фильтр не может отличить рекламу от контента на одном домене — иначе сломает весь сайт.
– Яндекс.Директ через yandex.ru/ads. Скрипт грузится с основного домена Яндекса как путь (/ads/system/context.js). Заблокировать весь yandex.ru нельзя — это же сам Яндекс. DNS тут бессилен в принципе.
– Видеореклама на плеерах — если ролик идёт с того же домена, что и само видео, DNS не поможет.
– YouTube — реклама с тех же доменов, что и контент. DNS-фильтр это не берёт, нужен uBlock Origin или подобное.
Итого: DNS-фильтр закрывает, грубо, 70–80% раздражающей рекламы — всю, что на отдельных доменах. Остальное — это либо реклама с контентных CDN, либо встроенная в страницу, где DNS в принципе не может отличить. Для полной чистки в браузере всё равно нужен uBlock Origin.
Вывод
Для домашней сети связка «MikroTik + AdGuard Home через DoH» — это лучший баланс: одна настройка на роутере, вся сеть фильтруется, ничего не надо ставить на устройства. Но честно: это не 100% — DNS-блокировка по определению не режет рекламу с тех же доменов, что и контент.
Подход и первые шаги подсмотрел у Fatmetal — у них хороший разбор, рекомендую. А грабли с MikroTik, whitelist'ом и отечественной рекламой — уже мои, делюсь, чтобы вы не наступали.
А у вас что режет рекламу дома — DNS на роутере, uBlock, или всё вместе?