В отличие от Podkop и ему подобных, этот способ позволяет более точно заворачивать трафик посредством снифинга целевого домена и подключать внешние списки заблокированных сайтов с автоматическим обновлением.
Не нашёл хороших русскоязычных руководств по этой теме, настроил у себя и решил написать инструкцию.
Требования к оборудованию
OpenWrt 24.10.0 или новее.
Не менее 256 МБ ОЗУ.
Не менее 64 МБ ПЗУ (я не проверял на 64 МБ — зависит от того, сколько занимает система для вашего роутера; 128 МБ точно хватит). В теории можно упаковать исполняемый файл sing-box с помощью UPX, но это может увеличить расход оперативной памяти.
На Filogic 820 примерная пропускная способность — 600–800 Мбит/с. На MT7621 должно получиться не менее 100 Мбит/с, возможно больше.
Перенаправление трафика в sing-box. OpenWrt-Momo
Большинство руководств, которые я видел, предполагают использовать софт, в котором маршрутизация происходит до sing-box (например, Podkop или RuAntiBlock).
Если пользователь хочет проводить всю маршрутизацию силами sing-box или xray, обычно предлагается самостоятельно создавать все необходимые правила перенаправления трафика, как в этом руководстве. Это сложно и неудобно (что если вы не хотите направлять весь трафик, а только от определённых клиентов локальной сети или на определённые порты?). Я пробовал настраивать это вручную ещё в 2024 году, у меня ничего не получилось и я надолго забросил эту идею.
Недавно обнаружил, что китайские разработчики сделали пакет для OpenWrt, который делает ровно то, что нужно: направляет трафик в sing-box, позволяя ограничить перенаправляемый трафик по целевым портам и по источникам в локальной сети. Также этот софт может получать настройки из внешнего источника (получает файл конфига по ссылке; для безопасности можно использовать HTTP Basic Authorization).
Итак, рассмотрим интерфейс китайского пакета Momo для OpenWrt:
Главная страница.
Здесь есть кнопки для перезагрузки конфигурации и полного перезапуска сервиса.

Choose Profile: выбрать из настроенных профилей.
Start Delay: задать задержку запуска после старта устройства.
Scheduled Restart: создать cron-задачу для перезапуска сервиса по расписанию (основное назначение - очистка лога sing-box, поскольку он сбрасывается только после перезапуска сервиса).
Test Profile: перед запуском профиля выполняет
sing-box checkдля проверки корректности конфига.Fast Reload: при изменении конфига вместо перезапуска sing-box заставляет текущий процесс перечитать конфиг.
Core Only: отключает все функции перенаправления и просто запускает sing-box.
Загрузка файлов конфига с устройства, их удаление или добавление подписки.

Интерфейс для добавления подписки.

Вкладка, дающая возможность редактировать конфиги прямо из интерфейса.

Вкладка с логами самого Momo и sing-box.

Главная функциональная вкладка для настройки перенаправления трафика в sing-box.

IPv4 DNS Hijack и IPv6 DNS Hijack: перехват IPv4/IPv6 DNS-запросов и их направление в sing-box. Авторы рекомендуют включать оба, если вы планируете обрабатывать DNS силами sing-box: даже если у вас нет IPv6-интернета, локальные компьютеры всё равно могут делать DNS-запросы к роутеру по IPv6 (через link-local).
IPv4 Proxy и IPv6 Proxy: перенаправление IPv4 и IPv6 трафика в sing-box. IPv6 можно выключить, если у вас его нет.
Fake-IP Ping Hijack: в sing-box есть механизм выдачи вместо реальных IP адресов адресов из заданного диапазона (fake-IP) для доменов, которые нужно обрабатывать внутри sing-box. На слабых устройствах можно выдавать адреса из этого диапазона и перенаправлять только запросы к этим адресам в sing-box. Эта опция позволяет возвращать реальный ping до конечного адреса, а не 1 мс до самого роутера. Если вы не настраивали Fake-IP, вам это не нужно, далее я не буду касаться настройки Fake-IP.
TCP Mode: режим перенаправления для TCP-трафика. Нам нужен TPROXY, т.к. TUN гораздо более затратен по CPU для sing-box.
UDP Mode: режим перенаправления для UDP-трафика. Также предпочитаем TPROXY по тем же причинам.
Позволяет по различным критериям включить или отключить перенаправление трафика, источником которого является сам роутер в sing-box. Я просто выключил.

Позволяет по IPv4 / IPv6 / MAC клиента включить или отключить для него перенаправление трафика или перехват DNS-запросов.

Приоритет правил - от первого к последнему, таким образом, если вы хотите включить для всех, кроме какого-то хоста, делайте так:

А если только для определённого хоста то так:

Помимо локальной сети можно добавить другой интерфейс, например гостевой или интерфейс клиентов VPN.

Bypass China Mainland IP: опция, не нужная нам (не направляет трафик к китайским подсетям в sing-box).
Destination TCP Port to Proxy: направление в sing-box только части целевых TCP-портов. Используется, чтобы не нагружать sing-box торрент-трафиком (для большого количества соединений требуется много ОЗУ; при 256 МБ ОЗУ может перестать хватать примерно на ~2000 соединений).
Порты, которые я добавил:20, 21 FTP
80, 443, 8080–8880 HTTP/HTTPS
110, 143, 465, 587, 993, 995 почта
2000–2099 есть информация, что используются для Discord
Destination UDP Port to Proxy перенаправление UDP-портов в sing-box:
443 QUIC
19294–19344, 50000–50032 Discord
Bypass DSCP пропуск трафика с определённой DSCP-меткой.
Настройки портов, куда перенаправляется трафик, в Momo нет, он читает их из конфигурации sing-box.
Составление конфигурации sing-box
Sing-box использует JSON-формат конфига, описанный на официальном сайте. Здесь упомяну только то, что нам потребуется.
Каркас конфигурации
{ "log": {}, "dns": {}, "endpoints": [], "inbounds": [], "outbounds": [], "route": {}, "experimental": {} }
Раздел log
Задаёт уровень логов, файл для вывода и т.д.
https://sing-box.sagernet.org/configuration/log/
"log": { "level": "warn" },
Раздел dns
Позволяет задать DNS-серверы, на которых будет происходить обработка запросов, и выбирать DNS-сервер в зависимости от домена.
https://sing-box.sagernet.org/configuration/dns/
"dns": { "servers": [ { "type": "udp", "tag": "yandex-dns", "server": "77.88.8.8", "detour": "direct-out" }, { "type": "udp", "tag": "NSDI-dns", "server": "195.208.5.1", "detour": "direct-out" }, { "type": "https", "tag": "cloudflare-dns", "server": "1.1.1.1", "detour": "direct-out" }, { "type": "https", "tag": "google-dns", "server": "8.8.8.8", "detour": "direct-out" }, { "type": "https", "tag": "Quad9-dns", "server": "dns.quad9.net", "domain_resolver": "yandex-dns", "detour": "direct-out" } ], "rules": [ { "rule_set": "geosite-category-ru", "server": "NSDI-dns" }, { "rule_set": "refilter_domains", "server": "Quad9-dns" } ] },
Quad9 используется, поскольку этот сервис не передаёт IP клиента, запросившего адрес (были случаи, когда зарубежные DNS намеренно отдавали некорректный адрес при запросе с русского IP).
Раздел endpoints
Позволяет задавать WireGuard и Tailscale-соединения.
https://sing-box.sagernet.org/configuration/endpoint/
"endpoints": [ { "type": "wireguard", "tag": "warp", "detour": "direct-out", "system": false, "mtu": 1280, "address": [ "172.16.0.2/32", "*:*:*/128" ], "private_key": "*", "peers": [ { "address": "162.159.192.1", "port": 2408, "public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", "allowed_ips": [ "0.0.0.0/0", "::/0" ], "persistent_keepalive_interval": 30, "reserved": "dHbH" } ], "amnezia": { "jc": 120, "jmin": 23, "jmax": 911 } } ],
Внимание: amnezia доступна только при использовании форка.
Раздел inbounds
Здесь настраиваются способы получения трафика.
https://sing-box.sagernet.org/configuration/inbound/
"inbounds": [ { "type": "tproxy", "tag": "tproxy-in", "listen": "::", "listen_port": 12345, "tcp_fast_open": true }, { "type": "direct", "tag": "dns-in", "listen": "::", "listen_port": 5354 } ],
Важно: блоки tproxy-in и dns-in надо называть именно так, Momo ищет их при чтении файла, чтобы получить порт. Можно дополнительно создать mixed-прокси, для которого весь трафик будет идти в туннель.
Раздел outbounds
Выходы для трафика: нужно настроить прокси, через который будет выводиться заблокированный трафик. При использовании форка доступны дополнительные типы, включая XHTTP.
https://sing-box.sagernet.org/configuration/outbound/
"outbounds": [ { "type": "direct", "tag": "direct-out", "connect_timeout": "20s", "domain_resolver": { "server": "yandex-dns", "strategy": "ipv4_only" } }, { "type": "urltest", "tag": "block-check", "outbounds": [ "warp", "tunnel" ], "url": "http://cp.cloudflare.com/generate_204", "interval": "1m" }, { "packet_encoding": "xudp", "server": "*", "server_port": 443, "uuid": "*", "type": "vless", "tag": "tunnel", "tcp_fast_open": true, "tcp_multi_path": true, "reuse_addr": true, "flow": "xtls-rprx-vision", "tls": { "enabled": true, "server_name": "*", "utls": { "enabled": true, "fingerprint": "firefox" }, "reality": { "enabled": true, "public_key": "*", "short_id": "*" } }, "domain_resolver": { "server": "Quad9-dns", "strategy": "prefer_ipv6" } } ],
directотправляет трафик напрямую.urltestпозволяет выбрать наиболее быстрый/рабочий outbound (поддерживает endpoints).Для каждого outbound можно задать, какой DNS-сервер использовать и как выбирать IP (стратегии:
ipv4_only,prefer_ipv6и т.д.).
Раздел route
Один из ключевых разделов: определяет, какой трафик куда пойдёт. Также позволяет подключать rule_set, подготовленные другими людьми.
https://sing-box.sagernet.org/configuration/route/
Я вижу два основных подхода:
Направить все соединения к российским ресурсам напрямую; остальное в туннель.
Направлять в туннель только то, что есть в списках заблокированного; всё остальное напрямую.
Также можно сочинить множество собственных правил (например, для блокировки рекламы). Я знаю два возможных источника списков заблокированного:
antizapret-sing-box: огромный список; с большой вероятностью там будет любой заблокированный ресурс, но из-за отсутствия аккуратной очистки там много мёртвых доменов, что негативно влияет на производительность и потребление памяти.
Re-filter-lists: попытка создать более чистый список (была статья на Хабре). Минусы: автор редко обновляет список (раз в пару месяцев или реже) и принимает решения о добавлении доменов по своим критериям. (Личный пример: я предложил три аниме-сайта с подтверждением блокировки с сайта Роскомнадзора, включая известный MyAnimeList; все три предложения были отклонены без объяснения. Другие предложения, в том числе мои, обрабатывались нормально.)
В примерах ниже использую Re-filter.
Вариант направления по спискам
"route": { "rules": [ { "action": "sniff" }, { "protocol": "dns", "action": "hijack-dns" }, { "inbound": "dns-in", "action": "hijack-dns" }, { "ip_is_private": true, "outbound": "direct-out" }, { "protocol": "bittorrent", "outbound": "direct-out" }, { "rule_set": "refilter_domains", "outbound": "block-check" }, { "action": "resolve", "strategy": "ipv4_only" }, { "rule_set": "refilter_ipsum", "outbound": "block-check" } ], "rule_set": [ { "tag": "refilter_domains", "type": "remote", "format": "binary", "url": "https://github.com/1andrevich/Re-filter-lists/releases/latest/download/ruleset-domain-refilter_domains.srs" }, { "tag": "refilter_ipsum", "type": "remote", "format": "binary", "url": "https://github.com/1andrevich/Re-filter-lists/releases/latest/download/ruleset-ip-refilter_ipsum.srs" } ], "auto_detect_interface": true, "default_domain_resolver": "google-dns" },
Объяснение правил:
sniffпозволяет sing-box определить протокол трафика. Без него нельзя узнать, что трафик DNS, bittorrent и т.д.hijack-dnsперенаправляет обработку DNS во внутренний DNS sing-box. Отдельно дляdns-inпотому что у меня был случай, когда трафик не распознавался как DNS, и тысячи UDP-соединений забили память роутера.ip_is_privateесли на tproxy попали соединения на локальные IP, их нужно отправить напрямую (Momo, по идее, не должен их заворачивать, но перестраховка не лишняя).bittorrentесли торрент-трафик оказался на портах, которые мы заворачиваем на sing-box, лучше направить его напрямую (включая соображения возможных проблем от хостера).refilter_domainsиrefilter_ipsumразделены, т.к. туннель может иметь IPv6-адрес при отсутствии такового у провайдера; при попадании на соответствующий outbound разрешение будет происходить по правилам этого outbound.resolveменяем в зависимости от наличия или отсутствия IPv6 у домашнего провайдера.
Вариант: российские ресурсы напрямую, остальное в туннель
"route": { "rules": [ { "action": "sniff" }, { "protocol": "dns", "action": "hijack-dns" }, { "inbound": "dns-in", "action": "hijack-dns" }, { "ip_is_private": true, "outbound": "direct-out" }, { "protocol": "bittorrent", "outbound": "direct-out" }, { "rule_set": "geosite-category-ru", "outbound": "direct-out" }, { "action": "resolve", "strategy": "ipv4_only" }, { "rule_set": "geoip-ru", "outbound": "direct-out" } ], "rule_set": [ { "tag": "geosite-category-ru", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geosite-category-ru.srs" }, { "tag": "geoip-ru", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geoip-ru.srs" } ], "auto_detect_interface": true, "default_domain_resolver": "google-dns", "final": "block-check" },
final sing-box по умолчанию отправляет трафик в первый outbound; с помощью final можно переопределить выход по умолчанию.
Раздел experimental
Позволяет управлять хранением кэша rule_set и включить внешний мониторинг.
https://sing-box.sagernet.org/configuration/experimental/
"experimental": { "cache_file": { "enabled": false }, "clash_api": { "external_controller": "[::]:9090" } }
Здесь я отключаю кэш, чтобы приложение лишний раз не записывало в постоянную память роутера. Мониторинг можно посмотреть через YACD
Внимание: если открыть HTTPS-версию вместо HTTP, современные браузеры могут разрешать доступ только к localhost, это ограничение браузеров ради безопасности (чтобы сайты не могли сканировать локальную сеть).
Пример окна мониторинга:


Дополнительно
Для перенаправления на TPROXY требуются пакеты
kmod-nf-tproxyиkmod-nft-socket.Если у вас, как и у меня, не работает китайский репозиторий (у меня он заблокирован и даже через европейский прокси не работает), просто скачайте из релизов пакеты под вашу архитектуру и установите, например:
momo_2025.08.11-r3_aarch64_cortex-a53.ipkиluci-app-momo_1.0.5-r1_all.ipk.Рекомендую установить
kmod-tcp-bbr, он даёт преимущества BBR для всех tcp соединений, которые будут идти через sing-box.Чтобы уменьшить шанс падения при нехватке памяти при неожиданно большом количестве соединений, можно поставить
zram-swap.После установки sing-box отключите его сервис, дальше его будет запускать Momo. Внимание: OpenWrt отключает автозагрузку только после перезапуска.
Можно попробовать избежать падений, добавив в init.d-файл Momo значение переменной окружения
GOMEMLIMITс нужным лимитом. Это заставит sing-box раньше вызывать сборщик мусора, но замедлит его в эти моменты. Для 256 МБ памяти без использования zram-swap разумный лимит около 100 МБ.
Методы установки DSCP метки
transmission поддерживает установку меток через параметр peer_socket_tos. Исходный код
qBittorrent имеет параметры peer-tos и peer-dscp но по информации от 23 года добавляет метку не изначально а уже после установления соединения с пиром что мешает обработке соединений правилами.
в Windows можно любому приложению задать DSCP групповой политикой или через powershell команды.
New-NetQosPolicy -Name "qb" -AppPathNameMatchCondition "qbittorrent.exe" -PolicyStore GPO:localhost -DSCPAction 8 Get-NetQosPolicy Remove-NetQosPolicy -Name "qb"
