- Process presets: Telegram, Discord, Browsers, Spotify (proxy), Windows System, Defender, Update, OneDrive (direct) - 8 presets, 53 exe total — no manual path browsing needed - Windows system services (svchost, explorer, dwm, etc.) bypass VPN by default to reduce server load - Default tun_default_outbound changed to "direct" - Fixed route.final to properly reflect tun_default_outbound in both hybrid and native modes (was always "proxy" before) - Documented zapret + sing-box sniff incompatibility Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
15 KiB
sing-box TUN на Windows: проблемы и попытки
Цель
Заменить tun2socks на sing-box TUN для поддержки маршрутизации по процессам (process_name).
tun2socks перехватывает весь трафик и пересылает на xray SOCKS — xray видит все соединения от tun2socks.exe, определение процесса невозможно.
Хронология попыток
Попытка 1: SOCKS bridge (sing-box TUN → SOCKS → xray)
Архитектура:
App → TUN (sing-box) → SOCKS:11808 → xray → xhttp → VPS
xray.exe bypass через process_name → direct
Проблемы найденные и исправленные:
sniff/sniff_override_destinationв TUN inbound — удалены в sing-box 1.13.0. Мигрировано на{"action": "sniff"}в route rules.auto_detect_interfaceломает SOCKS → localhost — bind к физическому NIC вместо loopback. Исправлено черезinet4_bind_address: "127.0.0.1".- Нет
hijack-dnsв hybrid config — DNS не перехватывался. Добавлено. - Нет sniffing на xray SOCKS inbound — xray не видел домены, domain routing не работал. Добавлен sniffing с
routeOnly: true.
Результат: Частично работало ("вроде работает"). Но:
- Много ошибок xhttp (connection upload closed) — нормальное поведение xhttp транспорта
- claude.exe (node.js) не работал через TUN — DNS через proxy chain (DoH → SOCKS → xray → xhttp) слишком медленный
process_name: xray.exe → direct— хрупкий механизм
Попытка 2: DNS через direct (без detour)
Сменили DNS на {"type": "udp", "server": "8.8.8.8"} без detour.
Проблема: FATAL: start dns/udp[direct-dns]: detour to an empty direct outbound makes no sense — sing-box 1.13 отвергает detour к пустому direct outbound.
Убрали detour полностью → DNS пакеты идут через OS default route → TUN → hijack-dns → DNS module → снова к 8.8.8.8 → ROUTING LOOP (700+ connections/sec).
Попытка 3: dialerProxy (v2rayN-style архитектура)
Архитектура:
App → TUN (sing-box) → SS(chacha20):PORT_A → xray → xhttp → VPS
xray outbound → dialerProxy → SS:PORT_B → sing-box tun-protect → direct
Проблемы:
method: "none"несовместим между sing-box 1.13 и xray 26.2 —failed to read 50 bytes. Сменили наchacha20-ietf-poly1305.- sing-box direct outbound НЕ МОЖЕТ выйти в интернет когда TUN активен (даже для трафика от tun-protect inbound):
auto_detect_interface: true— не работаетdefault_interface: "Ethernet"— не работаетstack: "system"— не работаетstack: "mixed"— не работает- Все попытки подключения через direct outbound дают
i/o timeout - Это значит трафик из tun-protect inbound → direct outbound → ловится TUN обратно → loop
Вывод: dialerProxy архитектура невозможна на данной системе из-за бага sing-box direct outbound на Windows.
Попытка 4: Возврат на SOCKS bridge + TCP DNS через proxy
Вернулись на SOCKS bridge. DNS: {"type": "tcp", "server": "8.8.8.8", "detour": "proxy"} — TCP DNS через SOCKS → xray → xray резолвит.
Результат: Тот же routing loop (700+ connections/sec). 5.28.195.2:443 via outbound/direct[direct]: i/o timeout. Даже 192.168.1.180:80 via direct: i/o timeout — LAN тоже недоступен. DNS fix не помог — проблема не в DNS, а в sing-box direct outbound на этом Windows.
Итоговый вердикт
sing-box direct outbound сломан на Windows 10 IoT LTSC 2021 (build 19044) с sing-box 1.13.3. Ни одна из попыток (auto_detect_interface, default_interface, stack types, DNS strategies) не решила routing loop. Проблема фундаментальная: direct outbound не может отправить трафик через физический NIC когда TUN активен — трафик ловится TUN обратно и зацикливается.
Решение: tun2socks по умолчанию + sing-box как экспериментальная опция.
Ключевые проблемы sing-box на Windows
1. direct outbound не работает для non-TUN inbound трафика
Когда трафик приходит через SS/SOCKS inbound (не TUN), direct outbound не может отправить его в интернет — auto_detect_interface не привязывает сокет к физическому NIC. Трафик ловится TUN и зацикливается.
Но: direct outbound РАБОТАЕТ для трафика из TUN inbound с process_name match (xray.exe → direct). Причина неясна — возможно разный code path в sing-box для TUN-initiated vs inbound-initiated connections.
2. DNS routing loop
Без detour на DNS сервере: DNS пакеты → TUN → hijack-dns → DNS module → отправка к DNS серверу → TUN → loop. Нужен обязательный detour: "proxy" для DNS.
3. Deprecated/removed поля в 1.13
sniff,sniff_override_destinationв TUN inbound удалены. Нужны route rule actions.detourк пустому direct outbound запрещён.
4. SS method "none" несовместимость
method: "none" между sing-box 1.13 и xray 26.2 даёт failed to read 50 bytes. Нужен реальный cipher (chacha20-ietf-poly1305).
5. Нестабильность xhttp через double-proxy
Цепочка TUN → SOCKS → xray → xhttp → VPS нестабильна. xhttp создаёт множество параллельных стримов, часть обрывается. Для приложений с агрессивным timeout (node.js/claude) это критично.
Сравнение tun2socks vs sing-box TUN
| Фича | tun2socks | sing-box TUN |
|---|---|---|
| Стабильность | Высокая | Низкая (Windows) |
| Process routing | Нет | Да (process_name) |
| DNS routing | Нет (xray handles) | Проблемная (loop risks) |
| Routing loop prevention | Маршруты через netsh | process_name / dialerProxy (не работает) |
| Совместимость с xhttp | Хорошая (прямой SOCKS) | Проблемная (double-proxy) |
| Настройка | Простая | Сложная (много подводных камней) |
Попытка 5: dialerProxy с sing-box 1.14.0-alpha.5 (2026-03-24)
Предпосылки:
- Анализ исходного кода v2rayN показал архитектуру "protect SS канала" через
dialerProxy - Скачан sing-box 1.14.0-alpha.5 (pre-built binary)
- Цель: проверить исправлен ли баг SS inbound → direct outbound (не работал на 1.13.3)
Архитектура v2rayN (эталон):
App → TUN (sing-box) → relay outbound → xray SOCKS inbound
xray → proxy outbound → dialerProxy → "tun-protect-out" SS outbound → sing-box SS inbound → direct → internet
process_name: [xray.exe, sing-box.exe] → direct (защита от routing loop)
Тест 1: SS inbound → direct outbound (chacha20-ietf-poly1305)
Конфиг sing-box:
{
"inbounds": [
{"type": "tun", "tag": "tun-in", "interface_name": "test_tun",
"address": ["172.19.0.1/30"], "auto_route": true, "strict_route": true, "stack": "mixed"},
{"type": "shadowsocks", "tag": "tun-protect", "listen": "127.0.0.1",
"listen_port": 19200, "method": "chacha20-ietf-poly1305", "password": "testpassword123"}
],
"outbounds": [{"type": "direct", "tag": "direct"}],
"route": {
"auto_detect_interface": true,
"rules": [
{"action": "sniff"},
{"process_name": ["sing-box.exe"], "outbound": "direct"},
{"inbound": ["tun-protect"], "outbound": "direct"},
{"ip_is_private": true, "outbound": "direct"}
]
}
}
Конфиг xray (SS outbound → sing-box SS inbound):
{
"inbounds": [{"protocol": "socks", "listen": "127.0.0.1", "port": 11808,
"settings": {"auth": "noauth", "udp": true}}],
"outbounds": [{"protocol": "shadowsocks", "settings": {"servers": [
{"address": "127.0.0.1", "port": 19200, "method": "chacha20-ietf-poly1305", "password": "testpassword123"}
]}}]
}
Тест:
curl -x socks5h://127.0.0.1:11808 http://httpbin.org/ip
# Результат: {"origin": "109.252.184.208"}
РЕЗУЛЬТАТ: ✅ РАБОТАЕТ! SS inbound → direct outbound на sing-box 1.14.0-alpha.5 исправлен. IP 109.252.184.208 — реальный IP провайдера (не proxy), трафик выходит через physical NIC минуя TUN.
Тест 2: method:none совместимость (xray 26.2 ↔ sing-box 1.14)
Тот же тест, но с "method": "none", "password": "" на обеих сторонах.
curl -x socks5h://127.0.0.1:11808 http://httpbin.org/ip
# Результат: curl: (7) Failed to connect to httpbin.org port 80 via 127.0.0.1 after 2036 ms
РЕЗУЛЬТАТ: ❌ НЕ РАБОТАЕТ. Баг method:none между xray и sing-box по-прежнему присутствует.
Тот же симптом что в Попытке 3 — xray отправляет пакет, sing-box не может его прочитать.
Вывод:
- Баг direct outbound для inbound-initiated трафика ИСПРАВЛЕН в sing-box 1.14 (не работал на 1.13.3)
method:noneпо-прежнему сломан между xray и sing-box — используемchacha20-ietf-poly1305- Overhead шифрования на localhost пренебрежимо мал
- Архитектура v2rayN с dialerProxy + protect SS каналом теперь реализуема
Тест 3: интеграция в приложение — первый запуск
Ошибка sing-box 1.14 при старте:
FATAL: outbound DNS rule item is deprecated in sing-box 1.12.0 and will be removed in sing-box 1.14.0
Причина: DNS rule {"outbound": ["direct"], "server": "bootstrap-dns"} — deprecated в 1.12, удалён в 1.14.
Этот формат позволял назначить DNS сервер для outbound'а через DNS rules. В 1.14 нужно использовать domain_resolver прямо на outbound'е.
Фикс:
- "dns": { "rules": [{"outbound": ["direct"], "server": "bootstrap-dns"}] }
+ // Вместо DNS rule — field на самом outbound:
+ direct_out = {"type": "direct", "tag": "direct", "domain_resolver": "bootstrap-dns"}
+ // + default_domain_resolver в route:
+ "route": { "default_domain_resolver": "proxy-dns", ... }
ВАЖНО для совместимости с sing-box 1.14+:
- НЕ использовать
outboundкак match condition в DNS rules - Использовать
domain_resolverfield на outbound'ах - Использовать
default_domain_resolverв route config
Тест 4: полная интеграция в приложение (после фиксов)
После исправления 3 багов:
outboundDNS rule → заменён наdomain_resolverна outbound'ах- outbound tag
relay→proxy(совпадает с routing rules) - Убран debug лог
РЕЗУЛЬТАТ: ✅ РАБОТАЕТ! Полная цепочка dialerProxy подтверждена:
outbound/socks[proxy]— весь трафик приложений идёт через proxy- protect канал:
tun-protect → 46.17.101.82:30443 → direct— xray достигает VPS - TLS sniff: определяет домены из SNI → domain routing работает
- DNS hijack: перехватывает DNS → proxy-dns через TCP
- QUIC sniff: определяет QUIC → routing по доменам
- Telegram (AyuGram.exe): подключается через proxy, сообщения ходят
Тест 5: process routing — default=direct + Telegram.exe→proxy
Конфиг: tun_default_outbound = "direct", process rule Telegram.exe → proxy.
РЕЗУЛЬТАТ: ✅ РАБОТАЕТ! Telegram идёт через VPN, остальной трафик напрямую.
Итого подтверждённые режимы:
- Default=proxy (весь трафик через VPN) ✅
- Default=direct + exe→proxy (только выбранные приложения через VPN) ✅
- Process routing по exe файлам ✅
- Protect канал (dialerProxy + SS chacha20) ✅
Ключевые баги при интеграции (исправлены):
outboundDNS rule deprecated в sing-box 1.12, удалён в 1.14 → FATAL при старте. Фикс:domain_resolverна outbound'ах- outbound tag mismatch: routing rules генерируют
outbound: "proxy", а outbound назывался"relay"→outbound not found: proxy. Фикс: переименовать в"proxy" - Google service routes (
google.com → direct) потенциально перехватывают Telegram MTProto (фейковый TLS SNI)
Известные ограничения: 4. Запрет (DPI bypass) + sing-box sniff несовместимы. Запрет фрагментирует TLS ClientHello → sing-box sniff не может определить SNI/протокол → routing застревает на sniff action → соединение таймаутит. Решение: отключить запрет при использовании sing-box TUN (VPN и так обходит DPI).
Рекомендация (обновлено 2026-03-24)
- tun2socks по умолчанию — стабильный, проверенный, работает с xhttp
- sing-box TUN с dialerProxy — теперь рабочий на sing-box ≥ 1.14, поддерживает process routing
- Обязательно: sing-box 1.14+ (1.13.3 имеет баг direct outbound для inbound-initiated трафика)
- Protect канал:
chacha20-ietf-poly1305(method:none сломан между xray и sing-box) - НЕ использовать
outboundDNS rule items — deprecated в 1.12, удалены в 1.14. Вместо этого:domain_resolverна outbound'ах
Тестовая среда
- Windows 10 IoT Enterprise LTSC 2021 (build 19044)
- xray-core 26.2.6
- sing-box 1.13.3 → 1.14.0-alpha.5 (обновлено)
- Транспорт: VLESS + xhttp + Reality
- Прокси сервер: 46.17.101.82:30443