Сегодня мы рассмотрим мое “домашнее решение” для блокировки рекламы в интернете на базе блокировки по DNS-именам. В принципе его можно экстраполировать и на уровень небольшой компании. Итак, зачем все это нужно? Просто сейчас браузеры наподобие хрома как-то очень уж плохо работают с AD Block и вообще бытует мнение, что реклама все же запускается, но ее вам не показывают. Это конечно паранойя какая-то, но если вы не параноик это не значит, что за вами не следят.
DNS-блокировщик рекламы
Для работы в качестве DNS-сервера мы не будем использовать тяжеловесные решения и нам понадобится только Proxy. Для этих целей нам подойдет проект dnsproxy от AdguardTeam который мы можем найти на GitHub по адресу https://github.com/AdguardTeam/. Технически мы можем собрать его из исходных кодов, но мы не будем этим заниматься и просто скачаем последний стабильный релиз.

Подготовка первого DNS-прокси сервера
Разворачивать буду на своих VPS в Cloud.ru и просто скачаем и распакуем в /usr/local/bin/.
~# wget https://github.com/AdguardTeam/dnsproxy/releases/download/v0.75.2/dnsproxy-linux-amd64-v0.75.2.tar.gz
# tar -xvf ./dnsproxy-linux-amd64-v0.75.2.tar.gz
# mv ./linux-amd64/dnsproxy /usr/local/bin/
Если мы попытаемся провести тестовый запуск с апстримом к Google DNS.
# dnsproxy -u 8.8.8.8:53
То мы получим ошибку.
ARN binding prefix=dnsproxy attempt=1 err="listen tcp 0.0.0.0:53: bind: address already in use"
2025/03/28 05:05:29.588369 ERROR running dnsproxy err="starting dnsproxy: configuring listeners: listening on tcp addr 0.0.0.0:53: listening to tcp socket: listen tcp 0.0.0.0:53: bind: address already in use"
И это вполне логично, так как порт 53 занят процессом systemd-resolve.
# netstat -tulpn | grep 53
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 605/systemd-resolve
udp 0 0 127.0.0.53:53 0.0.0.0:* 605/systemd-resolve
Немного усложним запуск добавив ряд дополнительных параметров.
# dnsproxy -l 10.0.0.7 -l 10.100.1.1 -u 8.8.8.8:53
Можно конечно отказаться от использования systemd-resolve и задать файл данные напрямую в resolv.conf, но мы этого делать не будем и зададим необходимые интерфейсы через параметр -l.
Проверяем, что наш прокси работает.
# dig @10.0.0.7 google.com
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> @10.0.0.7 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20057
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 121 IN A 108.177.122.139
google.com. 121 IN A 108.177.122.113
google.com. 121 IN A 108.177.122.100
google.com. 121 IN A 108.177.122.101
google.com. 121 IN A 108.177.122.138
google.com. 121 IN A 108.177.122.102
;; Query time: 348 msec
;; SERVER: 10.0.0.7#53(10.0.0.7) (UDP)
;; WHEN: Fri Mar 28 05:23:22 UTC 2025
;; MSG SIZE rcvd: 135
Добавляем апстрим на dns.adguard-dns.com по протоколу quic и теперь рекламные сайты и сайты отслеживания у нас должны отбраковываться возвращая адрес 0.0.0.0, что мы сейчас и проверим.
# dig @10.0.0.7 mc.yandex.ru
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> @10.0.0.7 mc.yandex.ru
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61222
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;mc.yandex.ru. IN A
;; ANSWER SECTION:
mc.yandex.ru. 3600 IN A 0.0.0.0
;; Query time: 52 msec
;; SERVER: 10.0.0.7#53(10.0.0.7) (UDP)
;; WHEN: Fri Mar 28 05:28:17 UTC 2025
;; MSG SIZE rcvd: 57
Прекрасно, у нас все работает и можем приступать к написанию сервиса, для чего в файле /usr/lib/systemd/system/dnsproxy.service создаем примерно такого вида сервис.
[Unit]
Description=DNS proxy
After=network.target
Before=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/dnsproxy -l 10.0.0.7 -l 10.100.1.1 -u "quic://dns.adguard-dns.com"
Restart=on-failure
RestartSec=30
StartLimitBurst=10
[Install]
WantedBy=user.target
Сервис запускаем, активируем и проверяем статус. Тут ничего нового.
# systemctl enable dnsproxy.service
# systemctl start dnsproxy.service
# systemctl status dnsproxy.service
Единственное, что в моем случае вышло боком, это использование параметра -l, так-как при перезагрузке меняется адрес интерфейса виртуальной машины так-как он серый и придется немного пошаманить с systemd-resolved и запретить ему использовать встроенный в него DNS, а использовать наш прокси.
Отключаем systemd-resolved и убираем параметры -l у сервиса.
# systemctl disable systemd-resolved
# systemctl stop systemd-resolved
Соответственно сервис у нас теперь выглядит вот так.
[Unit]
Description=DNS proxy
After=network.target
Before=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/dnsproxy -v -o /var/log/dnsproxy.log -u "quic://dns.adguard-dns.com"
Restart=on-failure
RestartSec=30
StartLimitBurst=10
[Install]
WantedBy=multi-user.target
Перезагрузимся и посмотрим, что у нас получилось с портом 53 и состоянием /etc/resolv.conf.
Порт 53 теперь занят dnsproxy.
# netstat -tulpn | grep 53
tcp6 0 0 :::53 :::* LISTEN 640/dnsproxy
udp6 0 0 :::53 :::* 640/dnsproxy
А вот с resolv.conf произошла неприятность.
# cat /etc/resolv.conf
cat: /etc/resolv.conf: No such file or directory
И нам необходимо создать его вручную.
# rm /etc/resolv.conf
# echo "nameserver 8.8.8.8" > /etc/resolv.conf
Проверяем.
# dig @127.0.0.1 mc.yandex.ru
# dig @127.0.0.1 google.ru
# dig @10.0.0.7 google.ru
Если все в порядке, то создаем группу сетевой безопасности, для того чтобы наш DNS-сервер был доступен из интернета.

Проверяем доступность сервера из интернета.
# dig @192.144.15.39 mc.yandex.ru
; <<>> DiG 9.18.30-0ubuntu0.22.04.2-Ubuntu <<>> @192.144.15.39 mc.yandex.ru
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34224
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;mc.yandex.ru. IN A
;; ANSWER SECTION:
mc.yandex.ru. 3600 IN A 0.0.0.0
;; Query time: 64 msec
;; SERVER: 192.144.15.39#53(192.144.15.39) (UDP)
;; WHEN: Fri Mar 28 06:42:47 UTC 2025
;; MSG SIZE rcvd: 57
Подготовка первого DNS-прокси сервера
Второй DNS-сервер подготавливается аналогично первому
Проверяем его доступность из интернета.
# dig @213.171.26.110 mc.yandex.ru
Проверяем, что оба DNS-сервера доступны (два сервера для отказоустойчивости).
# dig @213.171.26.110 mc.yandex.ru
# dig @192.144.15.39 mc.yandex.ru
Соответственно у нас сейчас есть два DNS-сервера в интернете с блокировкой рекламы.
- 213.171.26.110
- 192.144.15.39
Так как на AdGuard есть лимит на количество запросов, то лучше прикрыть этот сервис при помощи Firewall.
Настройка роутера
Здесь все просто. Укажите в настройках роутера в разделе DNS эти два сервера и все будет работать.
