---
name: singbox_windows_tun_per_app
description: "Per-app изоляция через sing-box TUN на Windows (CehoProxy/ProxyCage) — обязателен hijack-dns, иначе рвётся DNS всей системы; WinTun залипает после taskkill /F"
metadata: 
  node_type: memory
  type: project
  originSessionId: cf75944b-cc91-4988-aab6-28363391917a
  modified: 2026-08-07T09:07:56.152Z
---

Проверено живьём 2026-08-07 на Windows-ноуте `192.168.0.101` (DESKTOP-GFJR1B7, Win10 19045), подписка `sub.vlessi.cloud`.

**РАБОТАЕТ: настоящая per-app изоляция без системного прокси.** Конфиг sing-box с `inbound tun` (`auto_route: true`, `strict_route: true`, `stack: gvisor`) + `route.rules` с `process_path_regex` по папке. Доказано одновременным замером: контрольный `curl` вне папки → RU 5.18.232.68 и `chatgpt.com` **403**; `curl` из папки → FI 185.42.163.123 и `chatgpt.com` **200**. DNS и HTTPS остальной системы не затронуты. Это то, что нужно для корп-сценария, где системный прокси включать нельзя.

**Гоча 1 (главная): без правила `{"protocol":"dns","action":"hijack-dns"}` рвётся DNS ВСЕЙ системы.** `auto_route` переключает DNS ОС на адрес внутри TUN-подсети (`172.19.0.2`); без hijack-dns sing-box трактует это как обычное соединение и пытается `direct`-ом достучаться до адреса внутри собственной /30 — недостижимо. В логе тысячи `outbound/direct: i/o timeout`, симптом = «не работает вообще ничего, ни туннель, ни прямой трафик». Стоило сессии ложного вывода «TUN-подход нежизнеспособен». Правило добавлено в `SingBoxConfigGenerator.BuildRoute` (`~/Разработки/proxycage`).

**Гоча 2 + РЕШЕНИЕ: `taskkill /F` оставляет WinTun залипшим → следующий старт падает** `configure tun interface: Cannot create a file when that file already exists` (или `set ipv4 address: The object already exists`).
- **Лечится БЕЗ перезагрузки:** `pnputil /remove-device "SWD\WINTUN\{GUID}"`. Найти GUID: `Get-PnpDevice -Class Net | Where FriendlyName -match 'sing-tun'` (у залипшего `Status = Unknown`) либо `pnputil /enum-devices /class Net` и грепать `SWD\WINTUN\`. Проверено: после remove-device sing-box стартует сразу.
- **Правильный дизайн — самолечение ПЕРЕД стартом, а не надежда на корректное завершение.** Некорректное завершение бывает не только от taskkill: краш, BSOD, потеря питания, обрыв сессии. Реализовано в `TunCleanup.RemoveGhostAdapters()` — вызывается в начале `daemon`. Проверено живьём: жёстко убил → адаптер `Unknown` → демон сам снял и поднялся.
- Внимание: `Get-PnpDevice` находит призрак ТОЛЬКО пока он есть; сразу после чистой перезагрузки его нет, поэтому «поиск ничего не дал» ≠ «призрака не бывает».

**Гоча 3: штатная остановка CTRL_BREAK не сработала** ни через AttachConsole+GenerateConsoleCtrlEvent к чужому процессу, ни через свой дочерний с `CREATE_NEW_PROCESS_GROUP` (`SingBoxProcess.Stop()`), когда родитель запущен из SSH — у него нет консоли, GenerateConsoleCtrlEvent некому адресовать. Падает в TerminateProcess. **Но это перестало быть проблемой** после Гочи 2: самолечение на старте важнее graceful stop. Если понадобится настоящий graceful — нужен запуск с реальной консолью или Windows Service (SCM шлёт свой stop).

**MSIX/Store-приложения ИЗОЛИРУЮТСЯ по `process_path_regex`** (проверено на Codex из Microsoft Store, `C:\Program Files\WindowsApps\OpenAI.Codex_<version>_x64__2p2nqsd0c76g0\`). Признак успеха — у соединений процесса `LocalAddress = 172.19.0.1` (адрес TUN), у нетуннелируемых `192.168.0.101`; смотреть `Get-NetTCPConnection ... | Select LocalAddress`. Подмена бинаря/флаг `--proxy-server` для MSIX невозможны (подписанный пакет, активация через брокер), а `HTTP_PROXY` Chromium на Windows не читает — но TUN-маршрут по пути работает поверх всего этого.
- **Версия в пути MSIX меняется при обновлении** (`OpenAI.Codex_26.803.5235.0_...`) → правило обязано матчить префикс без версии, иначе изоляция тихо отвалится после апдейта приложения.

**Гоча 4: `stack: "system"` на Windows не поднялся, `gvisor` — поднялся.** Совпадает с рабочим конфигом `singbox-google-tun` на mini.

**Операционные грабли той машины (не про sing-box):**
- Процессы, запущенные обычной ssh-командой, умирают вместе с сессией (job object). Для фоновых демонов — только Task Scheduler; `/sc onlogon` через `schtasks` НЕ выполняется без интерактивной сессии (встаёт в очередь, «Прошлый результат: 0»), нужен `Register-ScheduledTask` с `-LogonType S4U`.
- PowerShell `Start-Process -RedirectStandardOutput/-Error` для sing-box ненадёжен (процесс тихо исчезает, логи пустые) — заворачивать в `cmd /c "... > out.log 2>err.log"`. И один файл на stdout+stderr `Start-Process` не принимает.
- Скрипты PS с кириллицей без BOM ломают парсер PS 5.1 → писать служебные скрипты на английском.
- macOS AppleDouble-мусор (`._*.cs`) в tar ломает `dotnet build` (`CS2015: is a binary file`).

Связано: [[electron_proxy_loopback_gotcha]], [[proxycage_overview]], [[openai_403_needs_browser_headers]].
