102 lines
4.7 KiB
Markdown
102 lines
4.7 KiB
Markdown
# Архитектура
|
||
|
||
## Scope
|
||
|
||
Текущий продукт — Android + desktop. iOS исключён. macOS не собирается в первом MVP;
|
||
если платформа вернётся, на ней разрешён только proxy-only до отдельного native review.
|
||
|
||
В приложении две верхние вкладки: `VPN` и `Белые списки`.
|
||
|
||
- `VPN` использует `SignBox` как один движок для стратегий `Основная` (VLESS) и
|
||
`Усиленная` (AmneziaWG 3.1).
|
||
- `Белые списки` использует отдельный `FreeTurn` runtime. FreeTurn не является
|
||
VPN-стратегией SignBox.
|
||
|
||
## Boundaries
|
||
|
||
```text
|
||
Flet/Python
|
||
models, profiles, UI, theme, payment banner, settings registry
|
||
|
|
||
| versioned idempotent commands
|
||
v
|
||
Flet service extension / MethodChannel
|
||
|
|
||
v
|
||
Android native services (separate lifetime from Activity)
|
||
VpnRuntimeService (VpnService + foreground)
|
||
ProxyRuntimeService (foreground + proxy/hotspot)
|
||
|
|
||
+-----+--------------------+
|
||
| SignBox/libbox adapter | FreeTurn mobile adapter
|
||
| TUN/proxy/stats | Start/StartTunnel/Stop/Captcha
|
||
```
|
||
|
||
Python does not start an Android subprocess and does not own VPN lifetime. On desktop,
|
||
the SignBox adapter may own a configured executable with `asyncio` process management;
|
||
FreeTurn desktop is explicitly unsupported.
|
||
|
||
Android state is authoritative in native `SharedPreferences`. Reopening the Flet UI must
|
||
call `get_runtime_state`; missing Python state never implies that a service is stopped.
|
||
The current native bridge already has this contract, but the engine AAR API still must
|
||
be pinned before the adapter can report `RUNNING`.
|
||
|
||
## Engine abstraction
|
||
|
||
`app/core/interface.py` defines the common lifecycle. `BackendRegistry` and
|
||
`EngineManager` select adapters by registry and enforce one active engine. Capabilities
|
||
are checked before start. Unsupported combinations raise `UnsupportedEngineError` and
|
||
are rendered as `Недоступно`, not as connected.
|
||
|
||
Internals remain different:
|
||
|
||
- Once the exact native artifact is supplied, SignBox can expose VLESS and AmneziaWG
|
||
packet/TUN plus local SOCKS/HTTP. The current adapter deliberately reports
|
||
`UNSUPPORTED` until that API is pinned and implemented.
|
||
- FreeTurn uses its own mobile binding and event/CAPTCHA lifecycle. Its `Start` API is
|
||
not a generic SOCKS5/HTTP listener; standard sharing remains unsupported until a
|
||
separately implemented listener reports actual bound addresses.
|
||
- `VOID` is an Android VPN data-path policy and must be enforced before an engine or
|
||
direct fallback. It must never be implemented as `addDisallowedApplication`, because
|
||
Android then sends that app directly.
|
||
|
||
## Modes and sharing
|
||
|
||
Desktop is proxy-only in the first release. Android supports `TUN`, `Proxy`, and
|
||
`Both` only when the selected native artifact advertises the matching capability.
|
||
|
||
Proxy defaults to `127.0.0.1`; Wi-Fi sharing uses `LocalOnlyHotspot`, discovers its
|
||
actual interface address, and binds listeners only after the hotspot callback. It never
|
||
assumes `192.168.43.1`, does not use `0.0.0.0` as a user default, and does not use
|
||
system tethering/NAT. SOCKS5 and HTTP CONNECT share one optional credential pair.
|
||
|
||
## Backend and devices
|
||
|
||
The backend has separate operator and device authentication:
|
||
|
||
- operator CRUD uses one configured admin Bearer token;
|
||
- each device gets a UUID4 and a separate random credential, stored server-side only
|
||
as SHA-256 hash;
|
||
- enrollment is one-time via an admin-created URL; the first request must use
|
||
`vpnapp/vMAJOR.MINOR/DEVICE_UUID` and binds that User-Agent;
|
||
- subsequent requests use `X-Device-Token` over HTTPS and the same bound User-Agent;
|
||
- UUID/User-Agent alone are not secrets and cannot authenticate.
|
||
|
||
Secrets in SQLite are Fernet-encrypted with `VPNAPP_SECRET_KEY`. The admin HTML never
|
||
lists secret fields after creation. A stronger future option is a hardware-backed key
|
||
and signed requests with replay protection.
|
||
|
||
## Theme and UI
|
||
|
||
The accent is derived from active top-level/strategy context: neutral gray for FreeTurn,
|
||
light blue for Basic, red for Enhanced, while `ThemeMode.SYSTEM` respects the device
|
||
light/dark mode. Screens register their settings sections in `SettingsRegistry`, so the
|
||
settings screen can grow without a universal nullable profile.
|
||
|
||
## Deliberate non-goals
|
||
|
||
- iOS, Personal Hotspot automation and iOS per-app routing.
|
||
- Android application routing (`DIRECT`/`VOID`) until native UID ownership and the
|
||
fail-closed packet drop path are implemented and tested on real devices.
|
||
- bundled native cores without pinned source, license, ABI and API evidence.
|
||
- management/debug listeners exposed by SignBox.
|