Блокировка рекламы на уровне роутера (DNS)

Сегодня мы рассмотрим мое “домашнее решение” для блокировки рекламы в интернете на базе блокировки по 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 эти два сервера и все будет работать.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *