ITDog
4.06K subscribers
7 photos
2 videos
8 files
78 links
Download Telegram
Channel created
Давно было пора завести свой канал.

Я автор этой статьи https://habr.com/ru/post/440030/
Видео по ней https://youtu.be/GMvEF0PXN-w
И ansible плейбука https://github.com/itdoginfo/domain-routing-openwrt с помощью которого это настраивается за пару минут

За 3.5 года существования этой статьи я добавлял, исправлял, удалял лишнее из статьи и плейбука. 3.5 года я держу эту тему актуальной. И конечно не просто так, помимо меня, этим пользуются много людей. Я постоянно нахожу ссылки и упоминания на форумах и в других статьях или же просто узнаю свои конфиги. А в репе на гитхабе 15 звёздочек! Вообщем, в этом канале я буду выкладывать апдейты по этой теме. Это будет не часто, но будет полезно для тех кто пользуется
И так, много проблем доставил переход на nftables, не работали списки. Потому что использовался ipset, который является придатком iptables. Сейчас в стабильной версии 22.03 ipset работает. Это уже не ipset конечно, а nftable sets, но название параметра пока оставлено, видимо, для совместимости.
Когда 22 версия была в dev, sets не было реализовано и многие люди просто не могли пользоваться списками. Накатывайте последний стабильный OpenWrt и пройдитесь по вашей конфигурации, для ipset нужно убрать options:
- storage
- maxelem
- hashsize
Но даже с ними будет работать, просто выкидывать warning.

Ну а если под ваш роутер нет официальной прошивки, то накатывайте последнюю сборку

Changelog:
- Конфиги ipset для версии 22
- Добавил community.lst от antifilter.download - оч классная инициатива, попробуйте. Расскажу о ней попозже
- Была проблема, что в каких-то случаях при запуске роутера, когда уже отрабатывал скрипт hivpn, curl не мог сразу выкачать файлы. Добавил проверки в скрипт
- Заменил DNSCrypt v1 на DNSCrypt v2. Он более простой "из коробки" и более продуманный. Отказоусточивость идёт прям из коробки
https://habr.com/ru/post/440030/
https://itdog.info/tochechnaya-marshrutizaciya-na-routere-s-openwrt-wireguard-i-dnscrypt/
https://github.com/itdoginfo/domain-routing-openwrt
В версии 22.03.2 обнаружена проблема с nftables sets
Firewall restart
Killed
/dev/stdin:112:19-19: Error: syntax error, unexpected end of file, expecting comma or '}'
185.60.216.0/22
^
The rendered ruleset contains errors, not doing firewall restart.
Syntax: /etc/init.d/hirkn [command]
Появляется при рестарте фаервола, когда применяются sets.
Что-то они сломали в этой версии, надо разбираться.

Используйте 22.03.0 и 22.03.1 - на них всё ок

UPD: Исправлено в новом пакете, обновите firewall4 или все пакеты сразу
opkg update
opkg list-upgradable | cut -f 1 -d ' ' | xargs -r opkg upgrade
Последнее видео довольно тяжелое для восприятия, если смотреть целиком. Я сделал его для дополнения к тексту, если непонятно как делать - смотришь кусок видео. Добавил тайм-коды, чтоб было удобнее искать нужный раздел:
00:00 Введение
02:20 Как понять, что трафик к ресурсам идёт через туннель на роутере
04:16 Как выключить машрутизацию
07:41 Проблемы с DNS
12:45 Разбираемся с WireGuard
36:06 Что-то не отработало в скрипте
41:00 Не хватает памяти на роутере
42:50 Проблемы на роутерах, которые официально не поддерживаются OpenWRT
45:27 Проблема c firewall на версии 22.03.2
47:08 Заключение
Как сделать маршрутизацию определённых доменов?

На данный момент это работает только для OpenWrt 21. За наводку по реализации спасибо viloncool

Логика работы такая:
- Мы запрашиваем ip адрес у dns сервера роутера, по умолчанию на Openwrt это dnsmasq
- Dnsmasq отдаёт нам адрес и видит, что мы хотим, чтоб этот адрес он добавил в ipset
- Добавляет этот адрес в указанный ipset
- Весь трафик, который идёт через ip адреса, находящиеся в ipset, теперь идёт через wg0 интерфейс

Необходим пакет dnsmasq-full.
Чтобы его установить, нужно удалить стандартный dnsmasq. Но если его удалить, не будет работать DNS на роутере, и не будут резолвится адреса репозитория openwrt, и не сможем установить dnsmasq-full.
Поэтому немного заморочимся:
opkg update
cd /tmp/ && opkg download dnsmasq-full
opkg install libc librt libpthread libnettle8 kmod-ipt-ipset libnetfilter-conntrack3
opkg remove dnsmasq
opkg install dnsmasq-full --cache /tmp/ && rm -f /tmp/dnsmasq-full*.ipk

Если что-то пошло не так, и вы остались без dnsmasq, то, соответственно, не сможете установить пакеты из репозитория. Узнайте ip downloads.openwrt.org с вашего компьютера
dig downloads.openwrt.org

Откройте /etc/hosts на роутере и вставьте туда строку с полученным ip
168.119.138.211 downloads.openwrt.org
Теперь opkg будет работать. Не забудьте убрать\закомментировать строку, как почините dnsmasq.

Устанавливаем пакет, который будет преобразовывать домены в ip адреса для связки dnsmasq+ipset
opkg install resolveip

Добавляем ещё один ipset и правило в /etc/config/firewall
config ipset
option name 'vpn_domains'
option match 'dst_net'
option storage 'hash'

config rule
option name 'mark_domains'
option src 'lan'
option dest '*'
option proto 'all'
option ipset 'vpn_domains'
option set_mark '0x1'
option target 'MARK'
option family 'ipv4'

После этого нужен рестарт
/etc/init.d/firewall restart

Добавляем необходимые домены в /etc/config/dhcp

В секцию dnsmasq добавляем
        list ipset '/itdog.info/vpn_domains'

Если нужно несколько доменов, их нужно перечислять через /. Запись будет выглядеть так
        list ipset '/graylog.org/terraform.io/openai.com/vpn_domains'

Или можно так
        list ipset '/graylog.org/vpn_domains'
list ipset '/terraform.io/vpn_domains'
list ipset '/openai.com/vpn_domains'

После добавления записей, нужно рестартовать dnsmasq
/etc/init.d/dnsmasq restart

Проверим, что ip адреса добавляются в ipset. На 21ой версии это делается так
ipset list vpn_domains


Имейте в виду, чтоб ip появился в списке, к dnsmasq должен прийти запрос. Зафорсить можно так
dig graylog.org @192.168.1.1

В выводе после Members должны быть ip адреса ресурсов
root@OpenWrt:/tmp# ipset list vpn_domains
Name: vpn_custom
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 768
References: 1
Number of entries: 5
Members:
188.114.99.224
188.114.98.224
76.76.21.21

Для работы с nftables нужна версия dnsmasq 2.87. Сейчас на Openwrt 22.03.2 версия 2.86. Ждём Openwrt 22.03.3
Использование OpenVPN заместо Wireguard на OpenWrt

Суть та же. Есть интерфейс, в который пересылается часть трафика, но настройка немного отличается.

Устанавливаем
opkg update
opkg install openvpn-openssl

Конфиг клиента openvpn копируем в /etc/openvpn/client.conf
В клиентские файлы конфигурации обычно складываются сразу настройки подключения, сертификаты и ключи. Проверьте, что там это всё есть.

Так же обычно openvpn серверы, которые используются для перенаправления трафика полностью (например VPN в общественном понимании), прописывают дефолтные маршруты при подключении к ним. Чтоб весь трафик шёл через туннель. Вот, например
root@OpenWrt:~# ip r
0.0.0.0/1 via 10.8.0.1 dev tun0

Для выборочного роутинг это не нужно, поэтому в конфиге клиента добавляем строку
pull-filter ignore redirect-gateway

В моём конфиге это выглядит так
verb 3
pull-filter ignore redirect-gateway
<ca>
-----BEGIN CERTIFICATE-----

А если в клиентском конфиге присутствует redirect-gateway, то нужно выпилить эту директиву.

Стартуем openvpn
/etc/init.d/openvpn start

Проверяем, что интерфейс поднялся и что трафик идёт
ip a
ping -I tun0 itdog.info

В /etc/config/firewall необходимо добавить зону для интерфейса openvpn и разрешить forwarding из lan зоны
config zone
option name 'tun'
option forward 'REJECT'
option output 'ACCEPT'
option input 'REJECT'
option masq '1'
option mtu_fix '1'
option device 'tun0'
option family 'ipv4'

config forwarding
option name 'lan-tun'
option dest 'tun'
option src 'lan'
option family 'ipv4'

Логика точно такая же, как для wg, но есть одно но. Для wg мы указываем интерфейс через опцию network, потому что wg интерфейс определен в /etc/config/network. А для openvpn указываем device, потому что openvpn сам создаёт этот интерфейс, и в network его нет.

Ну и последний штрих. В файле /etc/hotplug.d/iface/30-vpnroute меняем интерфейс с wg0 на tun0.

У меня при тестах не всегда поднимался маршрут при рестарте роутера. Это означает, что интерфейс openvpn поднимался после того, как отрабатывал hotplug. Решается это простой задержкой
#!/bin/sh

sleep 10
ip route add table vpn default dev tun0


После этого рестартуем сеть и роутинг теперь осуществляется через openvpn
/etc/init.d/network restart
А что, если Wireguard и OpenVPN заблочат? А? Поднимаем Shadowsocks на OpenWRT

Пакет shadowsocks есть в репах openwrt, но:
- На 22-й версии openwrt ss у меня не завёлся
- Что бы управлять трафиком, нужно делать конфигурацию, которая будет перенаправлять трафик на порт ss (127.0.0.1:1100). То есть, у нас нет сетевого интерфейса, на который можно направить трафик на уровне таблицы маршрутизации, как я это делал с wg и openvpn

Проблемы эти решает пакет tun2socks. Он цепляется к сетевому интерфейсу и переводит трафик в прокси. Что только не сделаешь, чтобы обойти китайский firewall.

Установка

Пакета tun2socks нет в репозиториях openwrt, поэтому его нужно скачивать с гитхаба проекта. Благо он собирается под множество архитектур.

Глянуть архитектуру процессора на вашем роутере
cat /proc/cpuinfo

В большинстве случаев будет написано просто MIPS. Скорее всего, вам нужна будет либо mipsle, либо mips.
Например, у моего Xioami mi3g архитектура mipsle.

Скачиваем на компьютер, разархивируем и перекидываем на роутер
wget https://github.com/xjasonlyu/tun2socks/releases/download/v2.4.1/tun2socks-linux-mipsle-softfloat.zip
unzip tun2socks-linux-mipsle-softfloat.zip
scp tun2socks-linux-mipsle-softfloat root@192.168.70.2:/tmp/

После этого заходим на роутер и проверяем, что точно скачали нужный бинарник
root@OpenWrt:~# /tmp/tun2socks-linux-mipsle-softfloat --help
Usage of ./tun2socks-linux-mipsle-softfloat:
-config string

Help вывелся, значит, всё ок. Но если выводится такая ошибка
/tmp/tun2socks-linux-mips-softfloat: line 1: syntax error: unexpected "("
значит, архитектура выбрана неверно.

Перекидываем в /usr/bin/ и заодно переименовываем
mv tun2socks-linux-mipsle-softfloat /usr/bin/tun2socks

Настройка интерфейса и firewall

tun2socks не создаёт интерфейс сам. Нужно самим создать интерфейс и присвоить ему ip
Добавляем в /etc/config/network
config interface 'tun0'
option device 'tun0'
option proto 'static'
option ipaddr '172.16.250.1'
option netmask '255.255.255.0'
Имейте в виду, что ip a покажет его только при запуске tun2socks.
Учтите, что если у вас настроен какой-нибудь vpn, то tun0 может быть занят. Можно поменять на tun1 тут и далее.

Так же как для wg и openvpn, создаём зону и правило в /etc/config/firewall
config zone
option name 'tun'
option forward 'REJECT'
option output 'ACCEPT'
option input 'REJECT'
option masq '1'
option mtu_fix '1'
option device 'tun0'
option family 'ipv4'

config forwarding
option name 'lan-tun'
option dest 'tun'
option src 'lan'
option family 'ipv4'

Меняем интерфейс в маршруте /etc/hotplug.d/iface/30-vpnroute
ip route add table vpn default dev tun0

Рестартуем сеть
/etc/init.d/network restart

Автозапуск при старте роутера

Накидал простой сценарий, кладём его в /etc/init.d/tun2socks
#!/bin/sh /etc/rc.common

USE_PROCD=1

# starts after network starts
START=40
# stops before networking stops
STOP=89

PROG=/usr/bin/tun2socks
IF="tun0"
PROTO="ss"
METHOD_USER="$METHOD/USER"
PASS="$PASS"
HOST="$HOST"
PORT="$PORT"

start_service() {
procd_open_instance
procd_set_param command "$PROG" -device "$IF" -proxy "$PROTO"://"$METHOD_USER":"$PASS"@"$HOST":"$PORT"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
procd_close_instance
}

Делаем исполняемым
chmod +x /etc/init.d/tun2socks

Делаем автозапуск
ln -s /etc/init.d/tun2socks /etc/rc.d/S90tun2socks

Надо подставить свои переменные, например
METHOD_USER="aes-256-gcm"
PASS="ochslozniyparol"
HOST="tech-domain.club"
PORT="8388"

Стартуем
/etc/init.d/tun2socks start

Потестить без сценария инициализации можно так
tun2socks -device tun0 -proxy ss://aes-256-gcm:ochslozniyparol@tech-domain.club:8388 -loglevel debug
При -loglevel debug выводится трафик, который ходит через tun2socks

Если будет кушать много памяти, то у проекта есть целая страница с описанием флагов, которые можно подкрутить.
Поднимаем socks5/socks4/http прокси на OpenWRT

Для использования socks5 тоже воспользуемся tun2socks, только переменные надо подкорректировать

Для socks5 прокси без пароля так
PROTO="socks5"
#METHOD_USER="aes-256-gcm"
#PASS="ochslozniyparol"
HOST="1.1.1.1"
PORT="46202"

Для socks5 прокси с логином и паролем вот так
PROTO="socks5"
METHOD_USER="user"
PASS="ochslozniyparol"
HOST="1.1.1.1"
PORT="1080"
Переменную METHOD_USER назвал так, потому что для ss - это метод шифрования, а в socks5 - это логин

После редактирования перезапустите tun2socks
/etc/init.d/tun2socks restart


tun2socks также поддерживает http и socks4, логика та же.

Не советую использовать бесплатные публичные прокси. Перенаправлять даже часть своего трафика на такие прокси опасно.
Как сделать роутинг для определённых доменов на OpenWrt 22.03?

Суть работы описывал тут.
Я надеялся, что dnsmasq 2.87 портируют под openwrt 22. Но его портировали только под текущую dev версию, а для 22.03 портировать не стали. Это значит, что ждать его в 22.03 версии не стоит.
Но это openwrt, и мы можем делать то, что захочется. Можно взять этот пакет из dev версии, поставить и попробовать использовать. Сразу предупреждаю, что у вас могут всплыть какие-то проблемы. Я протестировал этот метод только в плане добавления ip адресов в sets, насчёт общей стабильности ничего сказать не могу.

Скачиваем пакет из https://downloads.openwrt.org/releases/23.05.0/packages/

Тут надо опять же знать архитектуру вашего роутера, узнаётся очень просто
root@OpenWrt:~# opkg print-architecture
arch all 1
arch noarch 1
arch mipsel_24kc 10
Это вывод с моего Xiaomi 3g. Идём в каталог mipsel_24kc. Оттуда переходим в base

Нужно два пакета:
- Сам dnsmasq-full
- Его зависимость, которой нет в 22.03, libubox20220927

Нужно устанавливать версию dnsmasq-full не выше 2.89-4. Следующие версии не совместимы с OpenWrt 22.03.

Копируем ссылку, переходим в /tmp и скачиваем. Это лишь пример комманд, у вас будут другие ссылки:
cd /tmp
wget https://downloads.openwrt.org/snapshots/packages/mipsel_24kc/base/dnsmasq-full_2.89-1_mipsel_24kc.ipk
wgethttps://downloads.openwrt.org/snapshots/packages/mipsel_24kc/base/libubox20220927_2022-09-27-ea560134-1_mipsel_24kc.ipk
wget https://downloads.openwrt.org/snapshots/packages/mipsel_24kc/base/libubus20220615_2022-06-15-9913aa61-1_mipsel_24kc.ipk

Теперь поставим зависимости, которые есть в репозитории
opkg update
opkg install libc libnettle8 libnetfilter-conntrack3 nftables-json

Удаляем стандартный dnsmasq и ставим скачанные пакеты
opkg remove dnsmasq
opkg install libubox20220927_2022-09-27-ea560134-1_x86_64.ipk
opkg install dnsmasq-full_2.88-1_x86_64.ipk

Если резолвинг сломался, следуйте инструкции из поста для 21 версии.

Добавляем ещё один ipset и правило в /etc/config/firewall
config ipset
option name 'vpn_domains'
option match 'dst_net'

config rule
option name 'mark_domains'
option src 'lan'
option dest '*'
option proto 'all'
option ipset 'vpn_domains'
option set_mark '0x1'
option target 'MARK'
option family 'ipv4'

После этого нужен рестарт
/etc/init.d/firewall restart

Добавляем необходимые домены в /etc/config/dhcp

Синтаксис, как для 21ой версии не работает, но новый (кстати, в 21ой тоже работет) мне кажется, даже более удобным и структурированным. Добавляется отдельным блоком
config ipset
list name 'vpn_domains'
list domain 'graylog.org'
list domain 'terraform.io'
list domain 'openai.com'

После добавления записей нужно рестартовать dnsmasq
/etc/init.d/dnsmasq restart

Зафорсим запрос на роутер для проверки
dig graylog.org @192.168.1.1

И проверим, что ip добавились в sets
nft list ruleset | grep -A 5 vpn_domains

Будут отображаться в elements
    elements = { 188.114.99.224, 188.114.98.224,
76.76.21.21 }

Если возникнут проблемы и надо сделать "как было раньше", то удаляйте скачанный dnsmasq-full и устанавливайте стабильный из репозитория
opkg remove dnsmasq-full
opkg install dnsmasq
Насчёт OpenWrt 22.03 и её проблем. Переход на nftables многое сломал, и некоторые фичи не работают до сих пор. Я, сидя на 21ой версии, читал отзывы о 22ой, думал "зачем вы там обновляетесь вообще? Она же сырая".
Люди, конечно, в большинстве своём не обновлялись, а просто ставили 22.03, потому что 21ой версии под их новые роутеры не было.

Я это всё к чему, 21.02 - отличная прошивка. Если она вас устраивает, и задумываетесь: "а может обновиться до 22 прост?", советую не обновляться. Тем более, обновления для неё выходят до сих пор. Последняя минорная версия была в октябре 2022.

Кстати, 19ая обновлялась до апреля 2022. Респект разработчикам OpenWrt. Редкий производитель роутеров может похвастаться трёхлетней поддержкой прошивок.
Выкатил обновление с поддержкой списка доменов
- Добавил поддержку списка доменов от https://community.antifilter.download/. Убедился, что dnsmasq из dev работает корректно и можно публиковать этот метод. Это резолвинг с вашего роутера, о котором писал ранее
- В скрипте сделал логику преобразования списка доменов в конфиг dnsmasq (позже расскажу об этом подробнее)
- В Ansible playbook сделал выбор списков. Если вы хотите использовать только домены, то ставьте list_domains: true, а остальное в false. Более того, если сначала вы раскатали с true (или конфигурация для списков у вас была ранее), то поставив false, ansible удалит всё связанное с этим списком
- Также в скрипте переписал проверку загрузки списков. Изначально не хотел усложнять этим скрипт, но столкнулся с этим сам и понял, что нужно сделать
- Оптимизировал рестарт служб при прогоне плейбука. Если накатываете плейбук повторно, будут рестартится только необходимые службы, которых касаются изменения
- Ещё кучка мелких правок

Обновлена основная статья
https://itdog.info/tochechnaya-marshrutizaciya-na-routere-s-openwrt-wireguard-i-dnscrypt/
https://habr.com/ru/post/440030/

И репозиторий на Github
https://github.com/itdoginfo/domain-routing-openwrt
dnsmasq-full_2.89-1_mipsel_24kc.ipk
182.6 KB
Мне написали, что в https://downloads.openwrt.org/snapshots/packages/mips_24kc/base/ отсутствует пакет dnsmasq-full. Видимо, у openwrt где-то сломался CI для этой архитектуры. Для остальных он присутствует. Думаю, они починят в ближайшее время. А пока как времянку прикладываю пакет, который недавно выкачивал для своего Xiaomi mi3g.
Как я запилил работу со списком доменов. Конфигурация Dnsmasq и конвертация

Есть список доменов, которые надо преобразовать в конфиг dnsmasq, чтоб когда был запрос на получение ip адреса, dnsmasq добавлял эти ip в sets.
Но давайте сначала про конфиги dnsmasq в openwrt. Как они вообще сделаны?
Есть основной конфиг /etc/config/dhcp. Как и все конфиги в /etc/config это UCI like формат openwrt. Что касается именно dhcp конфига и dnsmasq, при старте службы запускается специальный конвертор, который берёт файл /etc/config/dhcp, преобразует его в формат конфигурации dnsmasq и кладёт его в /var/etc/dnsmasq.conf.cfg$N и dnsmasq работает уже с конфигурацией из этого файла.

В данном контексте нас интересует, как конвертируется блок ipset.
Из
config ipset
list name 'vpn_domains'
list domain 'graylog.org'

Получается
nftset=/graylog.org/4#inet#fw4#vpn_domains


Я столкнулся с тем, что у dnsmasq (по крайней мере на openwrt) на количество доменов в директиве nftset/ipset есть ограничения, где-то в районе 70. Если сделайте большой список в /etc/config/dhcp, при рестарте dnsmasq получите ошибку:
Thu Mar 16 19:50:05 2023 daemon.crit dnsmasq[1]: bad option at line 43 of /var/etc/dnsmasq.conf.cfg01411c
Thu Mar 16 19:50:05 2023 daemon.crit dnsmasq[1]: FAILED to start up


Имея в виду это и что редактировать скриптом на постоянке /etc/config/dhcp не очень хорошая идея, лучше использовать директорию, куда можно положить отдельным файлом конфиг. В openwrt для dnsmasq такая существует - /tmp/dnsmasq.d/.
Тут момент в том, что это уже не конфигурация формата UCI, а формат dnsmasq.

Осталось понять, как лучше конвертировать. Из-за существующих ограничений на количество доменов в nftset/ipset, в одну строчку все домены с antifilter не уместить. Разбивать по 50 штук - усложнение скрипта и непонятно имеет ли это вообще смысл в плане быстродействия.

Конвертацию я сделал с помощью sed, который есть в openwrt из коробки. К каждой строке в файле подставляется приставка и окончание. Выглядит так:
sed "s/.*/nftset=\/&\/4#inet#fw4#vpn_domains/" $dir/domains.lst > /tmp/dnsmasq.d/domains


Для 21 версии то же самое, только с ipset:
sed "s/.*/ipset=\/&\/vpn_domains/" $dir/domains.lst > /tmp/dnsmasq.d/domains


Теперь при запуске скрипта получаем:
root@OpenWrt:~# cat /tmp/dnsmasq.d/domains 
nftset=/graylog.org/4#inet#fw4#vpn_domains
nftset=/terraform.io/4#inet#fw4#vpn_domains
nftset=/openai.com/4#inet#fw4#vpn_domains

Ещё меня интересовала производительность. Я сделал тест при следующих условиях:
- nftsets включены для всего списка доменов из community
- Роутер настроен на отдельный DNS сервер в локальной сети, на котором переопределена A запись для тестового домена. Это нужно, чтобы не было погрешности измерений, когда роутер будет работать с внешними DNS серверами
- Кэш Dnsmasq отчищал после первого замера

Когда домен был включён в nftsets, время отдачи составляло 115-150 msec. Когда исключён из конфига - 4-8 msec.
Прирост, в сравнении, огромный, но такая прибавка только для доменов из списка. У меня в среднем обычный DNS запрос занимает 250 msec и уже на фоне этого такой результат очень даже неплохой.

Ну и самое приятное. В этот же set можно добавить домены, которых не хватает лично вам. В /etc/config/dhcp добавляем
config ipset
list name 'vpn_domains'
list domain 'graylog.org'
list domain 'terraform.io'


Как и при любом редактировании dhcp, нужен рестарт dnsmasq.
Всё, теперь ip этих доменов тоже будут складываться set vpn_domains, и трафик к ним будет направляться через туннель.
Блокировка рекламы на роутере с помощью Dnsmasq

Идея блокировки рекламы на роутере не нова. Для openwrt существуют специальные пакеты. Один более сложный в настройке, второй попроще. Оба базируются на блокировке доменов по спискам. Да-да, такой личный роскомнадзор, только в ваших интересах.
Я расскажу про ещё один способ. Он проще для понимания, установка дополнительных пакетов не требуется, т.к. используется dnsmasq.

Как это работает?
Возьмём самый простой пример. Есть баннер на веб-странице, его URL https://ads.domain/banner. Чтобы получить этот баннер, браузеру нужно зарезолвить домен и сходить по полученному IP адресу к рекламному серверу.
Мы просим dnsmasq: если наш браузер придёт к тебе с запросом адреса ads.domain, отдавай ему пустоту.
И когда мы открываем страницу с рекламным баннером: dnsmasq не отдаёт IP -> браузер не может зарезолвить домен -> баннер мы не видим.

Список oisd.nl
Существует много списков с доменами, один из самых больших и популярных это https://oisd.nl/downloads
Это огромный список, состоящий из множества разнообразных списков. На этой странице можно ознакомиться со всем составом.

Скачать этот список можно в разных форматах для разных программ, в том числе для dnsmasq.
Для dnsmasq есть два формата:
- Для версий до 2.86 - https://big.oisd.nl/dnsmasq
- Начиная с 2.86 - https://big.oisd.nl/dnsmasq2

С 2.86 внедрён параметр local, он увеличивает производительность, подробности можно изучить в changelog
Таким образом, конфиг до 2.86 выглядит так
server=/ads.domain/

Начиная с 2.86 так
local=/ads.domain/

Включаем блокировку вручную
Складывать конфиг будем в директорию /tmp/dnsmasq.d/, в неё можно складывать конфиги и dnsmasq будет их подхватывать.
Конфиг с сайта уже готовый и его можно сразу применять
cd /tmp/dnsmasq.d/
wget https://big.oisd.nl/dnsmasq2
/etc/init.d/dnsmasq restart

Проверим, что работает. Берём первый домен из списка
head -n 10 dnsmasq2

копируем и пробуем зарезолвить, отправляя запрос к DNS серверу роутера

dig ad.domain @192.168.1.1
Должно выдать отсутствие IP. Для сравнения можно запросить то же самое с какого-нибудь публичного DNS сервера.

Автоматизация
База c доменами обновляется раз в сутки. Всё что нужно - это обновлять список раз в день и рестартить dnsmasq.
Есть такой репозиторий https://github.com/lynxthecat/adblock-lean
Это служба с описанным выше + всякие проверки, start, stop.
Устанавливаем и запускаем
wget https://raw.githubusercontent.com/lynxthecat/adblock-lean/main/adblock-lean -O /etc/init.d/adblock-lean
chmod +x /etc/init.d/adblock-lean
service adblock-lean enable
service adblock-lean start

Добавляем в cron (в README проекта ещё добавлена команда enable, но я не вижу в этом смысла)
0 5 * * * export RANDOM_DELAY="1" && /etc/init.d/adblock-lean start

Stop службы удаляет файл и рестартит dnsmasq, т.е. выключает блокировку рекламы.
service adblock-oisd stop

Эта служба сделана для 22.03, на 21.02 версии с полпинка у меня не завелось. Нужно править скрипт или написать свой, не забудьте про разные ссылки, т.к. в 21ой версия dnsmasq 2.85.

Насколько полезно
Начнём с памяти, у меня на openwrt 22.03.3 эти списки в dnsmasq занимают 10МБ оперативной памяти. Это хороший результат, если сравнивать с требованиями adblock, в доке, которого указано, что роутер должен иметь минимум 128МБ RAM.

Про эффективность блокировки. Тут надо понимать, что реклама - это огромный рынок, которым кормятся корпорации и много компаний поменьше. И они делают так, чтобы подмена DNS не заглушала их рекламу. Ну и домены для рекламы бывает обновляются и в списки попадают не сразу.

Сложно оценить результат в браузере на ноутбуке, из-за включённого на постоянке блокировщика. Но я специально включал инкогнито и дёргал рубильник на роутере, оставалась самая хитрая реклама как раз от корпораций.
Также потестил на Android и iOS. Тут заметнее, на Android у меня режется большая часть рекламы, а вот на iOS только в каких-то очень популярных приложениях и то не вся.

Решение больше для смартфонов, планшетов, телевизоров итд. Полностью блокировки всей рекламы не ждите, но результат будет заметен.
Пример работы: два скрина с одним и тем же приложением на Android. Слева я открыл приложение через мобильный интернет, и баннер предлагает послушать Король и Шут. Справа приложение загружается через роутер с настроенным dnsmasq и баннер не зарезолвился.