Files
harbor-net/docs/windows-client-product-tech-brief.md

22 KiB
Raw Blame History

Windows Proxy Client: Product And Technology Brief

Дата: 2026-07-03

Цель документа: описать, как должно выглядеть и работать Windows-приложение для управления proxy/VPN-маршрутизацией приложений, и какой стек лучше использовать для реализации.

Этот документ можно отдать другой модели или команде как исходное ТЗ.

Коротко

Нужно Windows-приложение, которое разделяет систему на три независимые части:

  1. Control App: маленькое desktop-приложение для настройки, статуса, профилей, логов и запуска операций.
  2. Proxyfier Layer: отдельный компонент, который заставляет выбранные Windows-приложения ходить через SOCKS5/HTTP proxy, даже если они сами не умеют proxy.
  3. Local sing-box: опциональный локальный VPN/proxy runtime. Его можно установить, не устанавливать, остановить, заменить внешним proxy target.

Главный принцип: пользователь не обязан ставить все сразу. Если у него уже есть proxy, ему нужны только Control App + Proxyfier. Если нужен локальный VPN-клиент, он отдельно ставит sing-box.

Как это должно выглядеть

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

Главный экран:

  • верхняя строка: общий статус маршрута;
  • три карточки компонентов: Control App, Proxyfier, Local sing-box;
  • список активных профилей;
  • кнопка Apply changes;
  • короткая лента последних событий.

Пример главного статуса:

Selected apps -> ProxiFyre -> Local sing-box 127.0.0.1:1080 -> VPN

или:

Selected apps -> ProxiFyre -> Existing proxy 192.168.50.111:8080

Если sing-box не установлен, это не ошибка. Карточка должна показывать:

Local sing-box
Not installed
Install if you want this PC to run its own local VPN proxy.

Если Proxyfier не установлен, профили можно редактировать, но apply должен быть заблокирован:

Proxyfier is required to route selected apps.
Install Proxyfier

Основные экраны

1. Overview

Показывает:

  • текущий route line;
  • статус Control App;
  • статус Proxyfier;
  • статус Local sing-box;
  • активный proxy target;
  • сколько приложений сейчас включено в routing;
  • последние 5-10 событий.

Действия:

  • restart Proxyfier;
  • restart local sing-box, если установлен;
  • open logs;
  • copy diagnostics.

2. Profiles

Профиль - главный объект настройки.

Профиль содержит:

  • название;
  • enabled/disabled;
  • proxy target;
  • протоколы: TCP, UDP;
  • список приложений.

Типы элементов:

  • process: имя процесса, например Discord, Telegram, Code;
  • folder: папка, приложение сканирует .exe внутри;
  • exe: конкретный путь к .exe.

UI профиля:

  • слева список профилей;
  • справа детали выбранного профиля;
  • поле выбора target;
  • кнопки добавления: Process, Folder, EXE;
  • preview resolved apps;
  • Save;
  • Apply changes.

Важно: пользователь должен видеть понятные исходные элементы, а не только сгенерированный конфиг Proxyfier.

3. Targets

Proxy target - это куда Proxyfier отправляет трафик выбранных приложений.

Типы targets:

  • Local sing-box: 127.0.0.1:1080, доступен только если local sing-box установлен и запущен;
  • Existing SOCKS5 proxy: например 127.0.0.1:8080 или 192.168.50.111:8080;
  • Existing HTTP proxy, если выбранный proxyfier поддерживает HTTP.

На экране targets:

  • список targets;
  • проверка соединения;
  • имя, host, port, protocol;
  • статус last checked;
  • кнопка set default.

4. Components

Отдельный экран или часть Overview.

Компоненты:

  • Control App;
  • Proxyfier;
  • Local sing-box.

Для каждого:

  • installed / not installed;
  • running / stopped;
  • version;
  • path;
  • service/task status;
  • actions.

Actions должны быть явными:

  • Install;
  • Repair;
  • Start;
  • Stop;
  • Restart;
  • Open folder;
  • View logs.

Нельзя делать скрытую установку sing-box при сохранении профиля.

5. Logs / Diagnostics

Должно быть две зоны:

  • activity: действия пользователя и результат apply;
  • runtime logs: proxyfier logs, sing-box logs, helper logs.

Кнопка Copy diagnostics должна собирать:

  • версии компонентов;
  • paths;
  • running status;
  • активные profiles;
  • targets без секретов;
  • последние ошибки;
  • путь к сгенерированному proxyfier config.

Пользовательские сценарии

Сценарий A: у пользователя уже есть proxy

  1. Пользователь устанавливает Control App.
  2. Открывает приложение.
  3. Видит, что Proxyfier не установлен, а sing-box отсутствует.
  4. Нажимает Install Proxyfier.
  5. Добавляет target 192.168.50.111:8080.
  6. Создает профиль Discord.
  7. Добавляет process Discord.
  8. Нажимает Apply changes.
  9. Приложение генерирует config для Proxyfier и перезапускает proxyfier service.

Результат: Discord ходит через внешний proxy. Local sing-box не нужен.

Сценарий B: пользователь хочет локальный VPN proxy

  1. Пользователь устанавливает Control App.
  2. Устанавливает Proxyfier.
  3. Устанавливает Local sing-box.
  4. Вводит subscription/VLESS link.
  5. Выбирает сервер.
  6. Local sing-box поднимает SOCKS5/HTTP endpoint на 127.0.0.1:1080.
  7. Профили используют target Local sing-box.

Результат: выбранные приложения ходят через локальный sing-box.

Сценарий C: временно отключить VPN

  1. Пользователь открывает профиль.
  2. Меняет target с Local sing-box на внешний proxy или Direct/Disabled.
  3. Нажимает Apply changes.

Результат: Proxyfier перегенерирован, local sing-box можно остановить отдельно.

Рекомендуемый стек

Desktop shell: Tauri 2

Рекомендация: Tauri 2 + React + TypeScript + Rust backend.

Почему:

  • Tauri ориентирован на маленькие desktop-приложения и использует системный web renderer, поэтому приложение легче Electron.
  • Можно писать UI на обычном web stack: React/TypeScript/Vite.
  • Backend-часть на Rust хорошо подходит для Windows APIs, файлов, процессов, sidecar binaries и безопасных команд.
  • Tauri поддерживает sidecar binaries, но требует явно выдать permissions на запуск sidecar, что полезно для security boundary.

Frontend:

  • React;
  • TypeScript;
  • Vite;
  • TanStack Query для загрузки/кэша status/API;
  • Zustand или Jotai для локального UI state;
  • Zod для валидации JSON-моделей;
  • CSS modules или Tailwind. Для этой утилиты лучше сдержанный Windows-like UI, без тяжелой дизайн-системы.

Backend внутри Tauri:

  • Rust commands для простых операций;
  • отдельный core crate с доменной логикой;
  • отдельный windows-helper binary для elevated/privileged действий.

Не рекомендую начинать с Electron, если нет жесткой причины. Electron проще для web-команды, но тяжелее по размеру и памяти. Для маленькой системной утилиты Tauri подходит лучше.

Privileged helper

Нужно отделить обычное приложение от операций администратора.

Рекомендуемая модель:

Tauri UI
  -> Rust app backend
    -> unprivileged status/read operations
    -> explicit elevated helper for install/repair/service operations

Privileged helper может быть:

  • Rust CLI, который запускается elevated только для конкретной операции;
  • Rust Windows service/helper, если нужен постоянный privileged agent;
  • PowerShell scripts только как thin installer layer, не как основная бизнес-логика.

Для MVP можно сделать проще:

  • installers запускаются отдельно от имени администратора;
  • Control App работает обычным пользователем;
  • service start/stop/restart идет через helper command;
  • helper возвращает JSON, UI не парсит текст PowerShell.

Контракт helper:

{
  "action": "proxyfier.apply",
  "payload": {
    "configPath": "C:\\Tools\\ProxiFyre\\app-config.json",
    "config": {}
  }
}

Ответ:

{
  "success": true,
  "action": "proxyfier.apply",
  "changed": true,
  "message": "Proxyfier config applied and service restarted"
}

Ошибки:

{
  "success": false,
  "action": "proxyfier.apply",
  "error": "Proxyfier service is not installed",
  "details": {}
}

Service/runtime management

Для sing-box как background runtime:

  • использовать sing-box check перед применением config;
  • хранить config отдельно;
  • запускать как Windows service или scheduled task;
  • для service wrapper можно использовать WinSW, если не хочется писать собственный Windows service wrapper.

Практичный вариант:

  • v1: WinSW wraps sing-box.exe;
  • v2: собственный Rust service/helper, если понадобится полный контроль.

Control App не должен напрямую владеть процессом sing-box. Он должен управлять service/task через helper.

Local sing-box

sing-box - опциональный runtime.

Его роль:

  • принять subscription/VLESS/sing-box config;
  • поднять локальный mixed SOCKS/HTTP inbound;
  • слушать только 127.0.0.1, например 127.0.0.1:1080;
  • маршрутизировать трафик через выбранный outbound.

Config генерируется из source state приложения и проверяется:

sing-box check -c C:\Tools\VpnProxy\sing-box\config.json

Local sing-box не должен быть обязательным. Если profile target указывает на внешний proxy, sing-box может отсутствовать.

Proxyfier layer

Рекомендуемый стартовый backend: ProxiFyre.

Почему:

  • open-source;
  • Windows-focused;
  • маршрутизирует TCP и UDP;
  • работает per-application;
  • использует app-config.json;
  • может работать как Windows Service.

Важное ограничение: ProxiFyre лицензируется как AGPL-3.0. Если продукт должен быть закрытым коммерческим приложением, нужно заранее решить юридический вопрос или сделать adapter layer, чтобы можно было заменить engine на:

  • коммерческий Proxifier;
  • ProxyBridge;
  • собственный WinDivert/NDIS/WFP-based engine;
  • другой per-app proxy router.

Интерфейс должен называться не ProxiFyreConfig, а шире:

ProxyRouterAdapter

Первый adapter:

ProxiFyreAdapter

Это позволит поменять engine без переделки UI и профилей.

Data storage

Для MVP лучше использовать простые JSON-файлы с schema validation.

Причина:

  • настройки легко читать и бэкапить;
  • можно быстро отлаживать;
  • config portable;
  • подходит для profile/target/source state.

Рекомендуемые файлы:

C:\ProgramData\VpnProxy\config\profiles.json
C:\ProgramData\VpnProxy\config\targets.json
C:\ProgramData\VpnProxy\config\components.json
C:\ProgramData\VpnProxy\state\activity.json
C:\ProgramData\VpnProxy\state\last-status.json
C:\ProgramData\VpnProxy\generated\proxifyre-app-config.json
C:\ProgramData\VpnProxy\generated\sing-box-config.json

Если нужна большая история событий, статистика трафика или сложные миграции, тогда добавить SQLite:

  • rusqlite или sqlx в Rust;
  • миграции;
  • таблицы activity, component_status, traffic_events.

Но source of truth для профилей можно оставить JSON даже при наличии SQLite.

Installer strategy

Нужны три явных installer entrypoints:

Install Control App
Install Proxyfier Layer
Install Local sing-box

Они могут быть кнопками в UI, но каждая операция должна быть отдельной и понятной.

CLI/script names:

install-control-app.ps1
install-proxyfier.ps1
install-singbox.ps1

Или в packaged app:

VpnProxySetup.exe /component control-app
VpnProxySetup.exe /component proxyfier
VpnProxySetup.exe /component sing-box

Каждый installer:

  • idempotent;
  • делает backup перед overwrite;
  • не удаляет чужие файлы без подтверждения;
  • проверяет admin rights;
  • пишет machine-readable install result;
  • не трогает остальные компоненты без явного выбора.

Security model

Правила:

  • UI работает без admin rights.
  • Admin elevation только для install/repair/service/config apply, если это реально нужно.
  • Local API, если будет, слушает только 127.0.0.1.
  • Лучше использовать Tauri commands / named pipe, чем открытый HTTP port.
  • Если нужен loopback HTTP, включить token или origin check.
  • Секреты subscription URLs не показывать в diagnostics.
  • Generated configs не редактируются вручную из UI.
  • Every apply creates backup.

Архитектура

+-------------------------------+
| Tauri Control App              |
| React/TypeScript UI            |
+---------------+---------------+
                |
                v
+-------------------------------+
| Rust App Backend               |
| profiles, targets, validation  |
| component status aggregation   |
+-------+---------------+-------+
        |               |
        v               v
+---------------+   +-------------------+
| Proxy Router  |   | Local sing-box     |
| Adapter       |   | Adapter            |
| ProxiFyre v1  |   | config + service   |
+-------+-------+   +---------+---------+
        |                     |
        v                     v
+---------------+   +-------------------+
| ProxiFyre     |   | sing-box.exe       |
| Windows svc   |   | Windows svc/task   |
+---------------+   +-------------------+

Модель данных

Profile

{
  "id": "discord",
  "name": "Discord",
  "enabled": true,
  "targetId": "local-singbox",
  "protocols": ["TCP", "UDP"],
  "items": [
    { "type": "process", "value": "Discord" },
    { "type": "folder", "value": "%LOCALAPPDATA%\\Discord", "recursive": true },
    { "type": "exe", "value": "C:\\Games\\Game\\game.exe" }
  ]
}

Target

{
  "id": "local-singbox",
  "name": "Local sing-box",
  "type": "local",
  "protocol": "socks5",
  "host": "127.0.0.1",
  "port": 1080,
  "requiresComponent": "singbox"
}

External target:

{
  "id": "home-gateway",
  "name": "Home gateway",
  "type": "external",
  "protocol": "socks5",
  "host": "192.168.50.111",
  "port": 8080
}

Component status

{
  "id": "proxyfier",
  "name": "Proxyfier",
  "installed": true,
  "running": true,
  "version": "2.3.0",
  "path": "C:\\Tools\\ProxiFyre",
  "serviceName": "ProxiFyreService",
  "problems": [],
  "actions": ["restart", "repair", "openLogs"]
}

Apply behavior

Apply должен делать одно понятное действие:

  1. Прочитать profiles.
  2. Прочитать targets.
  3. Проверить, что выбранные targets доступны.
  4. Проверить, что Proxyfier установлен.
  5. Разрешить folder/exe в process names.
  6. Сгенерировать proxyfier config.
  7. Сделать backup старого config.
  8. Записать новый config.
  9. Перезапустить Proxyfier service.
  10. Записать activity entry.

Если profile использует local-singbox, дополнительно:

  • проверить, что sing-box установлен;
  • проверить, что service running;
  • проверить, что 127.0.0.1:1080 отвечает.

Если local-singbox не установлен, но profile target внешний, apply должен работать.

Что не делать

  • Не делать глобальную смену Windows proxy settings.
  • Не делать sing-box обязательным.
  • Не смешивать installer и profile apply.
  • Не хранить generated ProxiFyre config как source of truth.
  • Не привязывать UI напрямую к ProxiFyre, нужен adapter layer.
  • Не запускать privileged операции без явного согласия пользователя.
  • Не делать большой dashboard с лишней статистикой в первой версии.

MVP

Самый правильный первый slice:

  1. Tauri app shell.
  2. Profiles UI.
  3. Targets UI.
  4. Component status UI.
  5. ProxiFyre adapter.
  6. External SOCKS5 target.
  7. Apply profile -> generate ProxiFyre config -> restart service.

В MVP sing-box может быть только карточкой Not installed / Install.

После этого добавить:

  1. Local sing-box installer.
  2. Subscription import.
  3. Server selection.
  4. Generate sing-box config.
  5. Start/stop/restart local sing-box service.

Acceptance criteria

Приложение считается успешным, если:

  • можно установить только Control App;
  • можно установить Proxyfier отдельно;
  • можно не устанавливать sing-box;
  • можно добавить внешний SOCKS5 target;
  • можно создать профиль для Discord;
  • можно применить профиль;
  • generated ProxiFyre config не редактируется пользователем вручную;
  • UI показывает, что local sing-box отсутствует, но это не ломает внешний proxy flow;
  • после установки sing-box появляется target Local sing-box;
  • пользователь может переключить профиль с внешнего target на local sing-box.

Prompt For Another AI

Build a Windows desktop proxy management app.

Use Tauri 2 with React, TypeScript, Vite, and a Rust backend. The app must manage three independent components: the Control App, a proxyfier layer, and optional local sing-box. Do not make sing-box mandatory.

The UI must be a compact Windows utility with these screens: Overview, Profiles, Targets, Components, Logs. Profiles contain process/folder/exe entries and choose a proxy target. Targets can be local sing-box or external SOCKS5/HTTP proxies. Proxyfier is the layer that routes selected apps through the chosen target.

Start with ProxiFyre as the first proxy router adapter, but design an adapter boundary so it can later be replaced. Store source configuration as JSON with schema validation. Generated ProxiFyre and sing-box configs are derived artifacts, not source truth.

Privileged operations must be isolated in an explicit helper/installer flow. The main UI should run without admin rights. Install Control App, Install Proxyfier, and Install Local sing-box must be separate operations. Applying a profile must not silently install missing components.

MVP: external SOCKS5 target + ProxiFyre profile apply. Then add optional local sing-box installation, subscription import, server selection, and local sing-box service control.

References