- PVSM.RU - https://www.pvsm.ru -
В отличие от Podkop [1] и ему подобных, этот способ позволяет более точно заворачивать трафик посредством снифинга целевого домена и подключать внешние списки заблокированных сайтов с автоматическим обновлением.
Не нашёл хороших русскоязычных руководств по этой теме, настроил у себя и решил написать инструкцию.
OpenWrt 24.10.0 или новее.
Не менее 256 МБ ОЗУ.
Не менее 64 МБ ПЗУ (я не проверял на 64 МБ — зависит от того, сколько занимает система для вашего роутера; 128 МБ точно хватит). В теории можно упаковать исполняемый файл sing-box с помощью UPX, но это может увеличить расход оперативной памяти.
На Filogic 820 примерная пропускная способность — 600–800 Мбит/с. На MT7621 должно получиться не менее 100 Мбит/с, возможно больше.
Большинство руководств, которые я видел, предполагают использовать софт, в котором маршрутизация происходит до sing-box (например, Podkop [1] или RuAntiBlock [2]).
Если пользователь хочет проводить всю маршрутизацию силами sing-box или xray, обычно предлагается самостоятельно создавать все необходимые правила перенаправления трафика, как в этом руководстве [3]. Это сложно и неудобно (что если вы не хотите направлять весь трафик, а только от определённых клиентов локальной сети или на определённые порты?). Я пробовал настраивать это вручную ещё в 2024 году, у меня ничего не получилось и я надолго забросил эту идею.
Недавно обнаружил, что китайские разработчики сделали пакет [4] для 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 есть информация [5], что используются для Discord
Destination UDP Port to Proxy перенаправление UDP-портов в sing-box:
443 QUIC
19294–19344, 50000–50032 Discord
Bypass DSCP пропуск трафика с определённой DSCP-меткой.
Настройки портов, куда перенаправляется трафик, в Momo нет, он читает их из конфигурации sing-box.
Sing-box использует JSON-формат конфига, описанный на официальном сайте [6]. Здесь упомяну только то, что нам потребуется.
{
"log": {},
"dns": {},
"endpoints": [],
"inbounds": [],
"outbounds": [],
"route": {},
"experimental": {}
}
Задаёт уровень логов, файл для вывода и т.д.
https://sing-box.sagernet.org/configuration/log/ [7]
"log": {
"level": "warn"
},
Позволяет задать DNS-серверы, на которых будет происходить обработка запросов, и выбирать DNS-сервер в зависимости от домена.
https://sing-box.sagernet.org/configuration/dns/ [8]
"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).
Позволяет задавать WireGuard и Tailscale-соединения.
https://sing-box.sagernet.org/configuration/endpoint/ [9]
"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 доступна только при использовании форка [10].
Здесь настраиваются способы получения трафика.
https://sing-box.sagernet.org/configuration/inbound/ [11]
"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-прокси, для которого весь трафик будет идти в туннель.
Выходы для трафика: нужно настроить прокси, через который будет выводиться заблокированный трафик. При использовании форка [10] доступны дополнительные типы, включая XHTTP.
https://sing-box.sagernet.org/configuration/outbound/ [12]
"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 и т.д.).
Один из ключевых разделов: определяет, какой трафик куда пойдёт. Также позволяет подключать rule_set, подготовленные другими людьми.
https://sing-box.sagernet.org/configuration/route/ [13]
Я вижу два основных подхода:
Направить все соединения к российским ресурсам напрямую; остальное в туннель.
Направлять в туннель только то, что есть в списках заблокированного; всё остальное напрямую.
Также можно сочинить множество собственных правил (например, для блокировки рекламы). Я знаю два возможных источника списков заблокированного:
antizapret-sing-box [14]: огромный список; с большой вероятностью там будет любой заблокированный ресурс, но из-за отсутствия аккуратной очистки там много мёртвых доменов, что негативно влияет на производительность и потребление памяти.
Re-filter-lists [15]: попытка создать более чистый список (была статья на Хабре). Минусы: автор редко обновляет список (раз в пару месяцев или реже) и принимает решения о добавлении доменов по своим критериям. (Личный пример: я предложил три аниме-сайта с подтверждением блокировки с сайта Роскомнадзора, включая известный MyAnimeList [16]; все три предложения были отклонены без объяснения. Другие предложения, в том числе мои, обрабатывались нормально.)
В примерах ниже использую 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 можно переопределить выход по умолчанию.
Позволяет управлять хранением кэша rule_set и включить внешний мониторинг.
https://sing-box.sagernet.org/configuration/experimental/ [17]
"experimental": {
"cache_file": {
"enabled": false
},
"clash_api": {
"external_controller": "[::]:9090"
}
}
Здесь я отключаю кэш, чтобы приложение лишний раз не записывало в постоянную память роутера. Мониторинг можно посмотреть через YACD [18]
Внимание: если открыть 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 МБ.
transmission поддерживает установку меток через параметр peer_socket_tos. Исходный код [19]
qBittorrent имеет параметры peer-tos и peer-dscp но по информации [20] от 23 года добавляет метку не изначально а уже после установления соединения с пиром что мешает обработке соединений правилами.
в Windows можно любому приложению задать DSCP групповой политикой или через powershell команды.
New-NetQosPolicy -Name "qb" -AppPathNameMatchCondition "qbittorrent.exe" -PolicyStore GPO:localhost -DSCPAction 8
Get-NetQosPolicy
Remove-NetQosPolicy -Name "qb"
Автор: abubaca4
Источник [21]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/openwrt/439391
Ссылки в тексте:
[1] Podkop: https://github.com/itdoginfo/podkop
[2] RuAntiBlock: https://github.com/gSpotx2f/ruantiblock_openwrt
[3] этом руководстве: https://xtls.github.io/ru/document/level-2/tproxy_ipv4_and_ipv6.html
[4] пакет: https://github.com/nikkinikki-org/OpenWrt-momo
[5] информация: https://www.reddit.com/r/discordapp/comments/1kp3n4k/rtc_connecting_error_new_udp_port_1541_requirement/
[6] сайте: https://sing-box.sagernet.org/configuration/
[7] https://sing-box.sagernet.org/configuration/log/: https://sing-box.sagernet.org/configuration/log/
[8] https://sing-box.sagernet.org/configuration/dns/: https://sing-box.sagernet.org/configuration/dns/
[9] https://sing-box.sagernet.org/configuration/endpoint/: https://sing-box.sagernet.org/configuration/endpoint/
[10] форка: https://github.com/shtorm-7/sing-box-extended
[11] https://sing-box.sagernet.org/configuration/inbound/: https://sing-box.sagernet.org/configuration/inbound/
[12] https://sing-box.sagernet.org/configuration/outbound/: https://sing-box.sagernet.org/configuration/outbound/
[13] https://sing-box.sagernet.org/configuration/route/: https://sing-box.sagernet.org/configuration/route/
[14] antizapret-sing-box: https://github.com/savely-krasovsky/antizapret-sing-box
[15] Re-filter-lists: https://github.com/1andrevich/Re-filter-lists
[16] MyAnimeList: https://myanimelist.net/
[17] https://sing-box.sagernet.org/configuration/experimental/: https://sing-box.sagernet.org/configuration/experimental/
[18] YACD: http://yacd.metacubex.one/#/
[19] Исходный код: https://github.com/transmission/transmission/blob/9a792046f393252d93344e9fbf69f3eec3e32166/libtransmission/net.h#L668
[20] информации: https://github.com/daeuniverse/dae/discussions/295
[21] Источник: https://habr.com/ru/articles/977950/?utm_source=habrahabr&utm_medium=rss&utm_campaign=977950
Нажмите здесь для печати.