zapret-kvn/sing-box.md
loop-uh a15055e19d sing-box TUN: dialerProxy + process routing (v2rayN architecture)
Реализована архитектура v2rayN для sing-box TUN с process-based routing:
- dialerProxy: xray → SS protect канал → sing-box direct → internet
- TunConfigBundle: единый объект с sing-box + xray конфигами
- Process routing: configurable default outbound (proxy/direct) + per-exe exceptions
- Protected processes: xray.exe, sing-box.exe, tun2socks.exe auto-bypass
- Service routes bug fix: теперь применяются в sing-box конфиге
- DNS: bootstrap UDP + proxy TCP (совместимо с sing-box 1.14+)
- Hot-swap: node switching без перезапуска TUN адаптера
- UI: TUN default outbound ComboBox + protected process guard

Требует sing-box >= 1.14 (исправлен баг direct outbound для inbound-initiated трафика).
Protect канал: chacha20-ietf-poly1305 (method:none несовместим между xray и sing-box).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:55:46 +03:00

14 KiB
Raw Permalink Blame History

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

Проблемы найденные и исправленные:

  1. sniff / sniff_override_destination в TUN inbound — удалены в sing-box 1.13.0. Мигрировано на {"action": "sniff"} в route rules.
  2. auto_detect_interface ломает SOCKS → localhost — bind к физическому NIC вместо loopback. Исправлено через inet4_bind_address: "127.0.0.1".
  3. Нет hijack-dns в hybrid config — DNS не перехватывался. Добавлено.
  4. Нет 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

Проблемы:

  1. method: "none" несовместим между sing-box 1.13 и xray 26.2 — failed to read 50 bytes. Сменили на chacha20-ietf-poly1305.
  2. 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_resolver field на outbound'ах
  • Использовать default_domain_resolver в route config

Тест 4: полная интеграция в приложение (после фиксов)

После исправления 3 багов:

  1. outbound DNS rule → заменён на domain_resolver на outbound'ах
  2. outbound tag relay → proxy (совпадает с routing rules)
  3. Убран 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, сообщения ходят

Ключевые баги при интеграции:

  1. outbound DNS rule deprecated в sing-box 1.12, удалён в 1.14 → FATAL при старте
  2. outbound tag mismatch: routing rules генерируют outbound: "proxy", а outbound назывался "relay" → outbound not found: proxy
  3. Google service routes (google.com → direct) потенциально перехватывают Telegram MTProto (фейковый TLS SNI с google.com доменом)

Рекомендация (обновлено 2026-03-24)

  1. tun2socks по умолчанию — стабильный, проверенный, работает с xhttp
  2. sing-box TUN с dialerProxy — теперь рабочий на sing-box ≥ 1.14, поддерживает process routing
  3. Обязательно: sing-box 1.14+ (1.13.3 имеет баг direct outbound для inbound-initiated трафика)
  4. Protect канал: chacha20-ietf-poly1305 (method:none сломан между xray и sing-box)
  5. НЕ использовать outbound DNS 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