217 lines
14 KiB
Markdown
217 lines
14 KiB
Markdown
# ProxyWarden
|
||
|
||
ProxyWarden — standalone Windows desktop-приложение для маршрутизации выбранных программ через SOCKS5-прокси. Оно управляет обязательным ProxiFyre и, при необходимости, локальным `sing-box`, но само не является VPN-драйвером, proxy server или облачным control plane.
|
||
|
||
Все системные действия остаются явными: `apply` только проверяет и применяет конфигурацию; установка, обновление, запуск, остановка, перенос и удаление компонентов выполняются отдельными командами пользователя.
|
||
|
||
## Главное
|
||
|
||
- Tauri 2 + React/TypeScript UI + Rust backend.
|
||
- Маршрутизируются выбранные процессы, папки или `.exe`, а не вся система.
|
||
- Глобальный Windows proxy не меняется.
|
||
- Внешний SOCKS5 работает без Local sing-box.
|
||
- Production runtime не запускает PowerShell: service/install/UAC orchestration принадлежит native Rust.
|
||
- x64 installer содержит проверенные offline payloads компонентов и WebView2 Offline Installer; сеть для baseline-установки не нужна.
|
||
|
||
## Компоненты
|
||
|
||
| Компонент | Роль | Когда нужен |
|
||
| --- | --- | --- |
|
||
| ProxyWarden Control App | UI, storage, validation, config generation и orchestration | Всегда |
|
||
| [ProxiFyre](https://github.com/wiresock/proxifyre) | Перехватывает трафик выбранных приложений и направляет его в SOCKS5 | Для любого per-app routing |
|
||
| [Windows Packet Filter / NDISAPI](https://github.com/wiresock/ndisapi) | Сетевой драйвер ProxiFyre | Устанавливается вместе с ProxiFyre, если отсутствует |
|
||
| [Microsoft Visual C++ Redistributable](https://learn.microsoft.com/cpp/windows/latest-supported-vc-redist) | Runtime-зависимость ProxiFyre | Устанавливается при необходимости |
|
||
| [sing-box](https://github.com/SagerNet/sing-box) | Создаёт локальный SOCKS5 endpoint для выбранного subscription-сервера | Только для Local sing-box flow |
|
||
| [WinSW](https://github.com/winsw/winsw) | Запускает sing-box как Windows-службу | Только для Local sing-box flow |
|
||
|
||
Версии, SHA-256 и лицензии offline payloads зафиксированы в packaged component catalog. Установка Control App не запускает routing-компоненты: нужный компонент устанавливается отдельным действием в UI.
|
||
|
||
В UI и части внутренних DTO ProxiFyre может иметь исторический id `proxyfier`. Это не продукт Proxifier.
|
||
|
||
## Маршруты
|
||
|
||
Внешний SOCKS5:
|
||
|
||
```text
|
||
выбранные приложения -> ProxiFyre -> внешний SOCKS5 proxy
|
||
```
|
||
|
||
Local sing-box:
|
||
|
||
```text
|
||
выбранные приложения -> ProxiFyre -> Local sing-box 127.0.0.1:1080 -> выбранный subscription-сервер
|
||
```
|
||
|
||
Во втором маршруте ProxiFyre по-прежнему отвечает за выбор приложений. Local sing-box только предоставляет локальный SOCKS5 endpoint и соединяется с выбранным сервером.
|
||
|
||
## Установка и системные пути
|
||
|
||
Tauri NSIS installer устанавливает Control App per-machine. Managed runtime-компоненты лежат только под текущим app root:
|
||
|
||
```text
|
||
C:\Program Files\ProxyWarden
|
||
C:\Program Files\ProxyWarden\components\ProxiFyre
|
||
C:\Program Files\ProxyWarden\components\sing-box
|
||
```
|
||
|
||
Службы:
|
||
|
||
```text
|
||
ProxiFyreService
|
||
ProxyWardenSingBox
|
||
```
|
||
|
||
ProxyWarden управляет службой только после точной проверки `PathName`, marker/receipt и canonical component root. Похожее имя службы или найденная папка сами по себе не дают права на start/stop/delete.
|
||
|
||
## Релиз одной командой
|
||
|
||
В PowerShell из корня проекта:
|
||
|
||
```powershell
|
||
.\release.cmd
|
||
```
|
||
|
||
То же действие доступно как `npm run release`. Сценарий показывает изменения Git и предлагает patch/minor/major, произвольную версию или текущую ещё не выпущенную версию. Можно сразу ввести номер вроде `1.2.1`.
|
||
|
||
После выбора он синхронизирует версии в package.json, package-lock.json, tauri.conf.json, Cargo.toml и Cargo.lock, проверяет frontend/Rust/offline bundle, собирает NSIS и готовит папку `releases/proxywarden-vX.Y.Z`. Затем создаёт commit со всеми текущими отслеживаемыми и неигнорируемыми новыми файлами, annotated tag `vX.Y.Z` и одним atomic push отправляет текущую ветку и этот тег в `origin`. При отсутствии изменений новый commit не нужен. Артефакты не попадают в Git.
|
||
|
||
В папке релиза: `artifacts/nsis/ProxyWarden_X.Y.Z_x64-setup.exe`, `SHA256SUMS.txt`, `release-manifest.json` с точным commit/hash и `release-notes.md`. EXE загружается на сайт вручную; GitHub/Gitea release page автоматически не создаётся.
|
||
|
||
Нужны Git с настроенной identity и доступом к origin, Node, установленные frontend-зависимости (`npm ci` один раз), Rust/MSVC/Windows SDK. Сам сценарий сборки использует Node напрямую и не требует npm в PATH. Запуск от администратора не нужен.
|
||
|
||
```powershell
|
||
.\release.cmd -PlanOnly # только JSON-план: без записи, сборки и сети
|
||
.\release.cmd -Version 1.2.1 # версия без вопроса
|
||
.\release.cmd -Version 1.2.1 -Resume # повторить только неудачный push
|
||
.\release.cmd -Version 2.0.0 -Replace # пересобрать ещё не выпущенную версию с заменой тега
|
||
```
|
||
|
||
Не меняйте исходники во время сборки. По умолчанию существующие теги не перезаписываются; при расхождении с удалённой веткой сценарий останавливается до изменения версий. При ошибке сборки изменения версии остаются локально для исправления, commit/tag/push не выполняются. При неудачном push готовая папка и локальный commit/tag сохраняются; `-Resume` проверяет исходники и SHA-256 перед повторной отправкой.
|
||
|
||
Если версия ещё не выложена пользователям, `-Version X.Y.Z -Replace` заново выполняет проверки и сборку с текущими изменениями. После сборки предыдущая папка сохраняется рядом как `proxywarden-vX.Y.Z-replaced-...`, а выбранный тег обновляется локально и в origin. История ветки сохраняется. Отправка использует `--force-with-lease` только для этого тега: если он изменился на сервере с начала операции, замена отклоняется. При сбое отправки используется обычный `-Version X.Y.Z -Resume`, который сохраняет первоначальное условие замены. `-Replace` требует явного номера версии и не совмещается с `-Resume`.
|
||
|
||
Для локальной подготовки без commit/tag/push остаётся `scripts/prepare-release.ps1 -Version X.Y.Z`. Автоматические проверки не заменяют Windows VM/UAC/driver/routing acceptance: в manifest это отмечается отдельно.
|
||
|
||
## Данные и source of truth
|
||
|
||
Настройки и состояние лежат под `C:\ProgramData\ProxyWarden`:
|
||
|
||
```text
|
||
config\profiles.json
|
||
config\targets.json
|
||
config\local-singbox.json
|
||
config\storage-meta.json
|
||
state\activity.json
|
||
state\component-layout.json
|
||
state\component-updates.json
|
||
state\migrations\...
|
||
packages\...
|
||
```
|
||
|
||
`config\components.json` не является текущим источником статуса компонентов. Это только legacy input: migration может проверить, сохранить snapshot/archive и затем перестать использовать его. Фактический install/service/version status читается из native inventory Windows и проверенных receipts.
|
||
|
||
Generated artifacts можно пересоздать:
|
||
|
||
```text
|
||
generated\proxifyre-app-config.json
|
||
generated\sing-box-config.json
|
||
```
|
||
|
||
Не редактируйте generated-файлы как основной источник правды. Subscription URL, userinfo, credentials, proxy password и внутренние migration/job records нельзя выводить целиком в UI, logs или diagnostics.
|
||
|
||
## Миграция старой установки
|
||
|
||
- Startup выполняет только безопасную storage adoption/migration: backup, validation, atomic commit и повторный no-op.
|
||
- Старые component roots и службы сначала обнаруживаются read-only.
|
||
- Перенос компонента — отдельное UAC-действие с exact identity checks, rollback journal и quarantine.
|
||
- Foreign или incomplete installation не управляется автоматически.
|
||
- Пока cutover journal активен, требует recovery или quarantine ещё не подтверждён к удалению, upgrade/uninstall блокируется до безопасного завершения.
|
||
|
||
## Права администратора
|
||
|
||
Без UAC можно редактировать настройки, выбирать приложения и proxy, загружать subscription, смотреть статус и генерировать конфигурацию.
|
||
|
||
UAC требуется для явных действий, которые меняют Windows:
|
||
|
||
- install/update/uninstall ProxiFyre или Local sing-box;
|
||
- установка Windows Packet Filter и VC++ Runtime при необходимости;
|
||
- start/stop/create/delete Windows-служб;
|
||
- подтверждённый legacy component cutover и его cleanup.
|
||
|
||
Elevated mode принимает только заранее записанный typed job ID либо один из фиксированных NSIS modes. UI не передаёт произвольную команду, script text или install path.
|
||
|
||
## Типовые сценарии
|
||
|
||
### Внешний SOCKS5
|
||
|
||
1. Установите ProxiFyre явной кнопкой, если он отсутствует.
|
||
2. На вкладке `VPN / Прокси` выберите внешний proxy и укажите `host:port` или `socks5://host:port`.
|
||
3. Добавьте приложения в ProxiFyre route.
|
||
4. Нажмите `Применить`.
|
||
|
||
Local sing-box для этого сценария не нужен.
|
||
|
||
### Local sing-box с подпиской
|
||
|
||
1. Явно установите ProxiFyre и Local sing-box.
|
||
2. Добавьте subscription URL, загрузите список и выберите сервер.
|
||
3. Добавьте приложения и примените маршрут.
|
||
|
||
## Разработка
|
||
|
||
Целевая платформа — Windows 10/11 x64. Для сборки нужны Node.js/npm, Rust через rustup, Visual Studio Build Tools с MSVC и Windows SDK. PowerShell 7 используется только для build/release/QA tooling; установленному приложению PowerShell не нужен.
|
||
|
||
```powershell
|
||
Set-Location D:\repos\ProxyWarden
|
||
npm ci
|
||
npm run tauri -- dev
|
||
```
|
||
|
||
Browser preview не доказывает работу Tauri commands, UAC или Windows-служб:
|
||
|
||
```powershell
|
||
npm run dev -- --host 127.0.0.1
|
||
```
|
||
|
||
## Проверка
|
||
|
||
Frontend и Rust:
|
||
|
||
```powershell
|
||
npm run format:check
|
||
npm run lint
|
||
npm run typecheck
|
||
npm test -- --run
|
||
npm run build
|
||
|
||
Push-Location src-tauri
|
||
cargo fmt --all -- --check
|
||
cargo clippy --all-targets --all-features -- -D warnings
|
||
cargo test --all-targets
|
||
Pop-Location
|
||
```
|
||
|
||
Build/release/QA boundaries:
|
||
|
||
```powershell
|
||
& .\scripts\check-runtime-powershell-boundary.ps1 -CheckOnly
|
||
& .\scripts\update-component-bundle.ps1 -PlanOnly
|
||
& .\scripts\update-component-bundle.ps1 -CheckOnly
|
||
& .\scripts\audit-windows-smoke.ps1 -Mode PlanOnly
|
||
& .\scripts\prepare-release.ps1 -PlanOnly -SkipBuild
|
||
npm run tauri -- info
|
||
npm run tauri -- build
|
||
```
|
||
|
||
`PlanOnly` и `CheckOnly` возвращают structured JSON с `changed: false`. Обновление packaged component catalog — отдельная release-команда и не является runtime action.
|
||
|
||
Unit tests и build не подтверждают реальный UAC/SCM/driver/routing flow. Для release candidate нужны Windows VM smoke-сценарии: fresh offline install, legacy upgrade/rollback, foreign same-name service refusal и uninstall/reboot behavior.
|
||
|
||
## Ограничения
|
||
|
||
- Основной routing protocol — SOCKS5.
|
||
- Link subscriptions поддерживают только форматы, которые явно принимает текущий parser; неизвестные поля/форматы отклоняются, а не теряются молча.
|
||
- Local sing-box остаётся optional.
|
||
- x86 и ARM64 не входят в текущий release contract.
|
||
- Реальные Windows service, UAC, driver и offline installer сценарии нельзя считать подтверждёнными без VM evidence.
|