vpn/README.md
2026-09-23 19:07:33 +00:00

85 lines
3.6 KiB
Markdown

# VPN App
Private Android/Desktop client built as a small monorepo:
- `app/` — Flet/Python UI, profiles, settings, runtime state and common business logic.
- `native/android/` — Flet service extension and Kotlin service boundary. VPN lifecycle,
TUN, foreground service, hotspot and mobile libraries belong here, not in Python.
- `backend/` — deliberately small FastAPI + SQLite operator API and device subscription
endpoint.
- `docs/` — architecture, upstream research, implementation status and device test plan.
The current product scope is Android first and desktop proxy-only. iOS is intentionally
not in this repository. macOS is not a target of the first build; if added later it will
be proxy-only unless a separate native implementation is approved.
## Current product model
The app has two top-level tabs:
- **VPN** — `Основная` (VLESS) and `Усиленная` (AmneziaWG 3.1), both through the
`SignBox` adapter contract.
- **Белые списки** — FreeTurn, with stream presets `1..4`, CAPTCHA handling and
optional stability mode.
The Python engine manager is real and tested. Desktop `SignBox` proxy mode can launch a
configured local executable when one is supplied. Android native lifecycle and command
protocol are implemented; FreeTurn is integrated from a pinned local AAR during the
build, while SignBox remains `UNSUPPORTED` until the exact signed artifact and API are
supplied. Engine AARs are intentionally not checked into git. The UI never treats an
unsupported result as a successful connection.
The exact remaining functional blockers are tracked in
[`docs/implementation-status.md`](docs/implementation-status.md); an APK build alone
is not evidence that the missing VPN data path works.
## Quick start
```bash
uv sync
uv run flet run
uv run pytest
```
Run the backend locally:
```bash
export VPNAPP_ADMIN_TOKEN='replace-this-in-a-secret-shell'
uv run uvicorn backend.main:app --reload --port 8080
```
The backend deliberately requires HTTPS in deployment. `VPNAPP_ADMIN_TOKEN` is an
operator credential only. Devices use a separate random bearer credential; UUIDs and
User-Agent strings are not authentication.
## Build scripts
```bash
./scripts/fetch-engine-artifacts.sh # fetches pinned libbox + verifies SHA256SUMS
./scripts/build-android.sh # flet build apk (requires Android SDK/Flutter)
./scripts/build-desktop.sh linux # flet build linux
./scripts/run-backend.sh # local backend
```
For Android, the fetch script downloads `Leadaxe/sing-box-lx` at the pinned version.
`REQUIRE_NATIVE_ARTIFACTS=1 ./scripts/build-android.sh` then builds an arm64 APK.
Artifacts stay ignored; versions and hashes live in `native/android/libbox.version` and
`THIRD_PARTY_NOTICES.md`.
The current Android APK is libbox-first. FreeTurn is not packaged alongside it because
the independently generated gomobile AARs contain incompatible global runtime classes;
see `docs/implementation-status.md`.
## Security posture
The default proxy bind is localhost. Wi-Fi sharing is explicit, binds to the discovered
LocalOnlyHotspot address, and requires authentication by default. Management/debug APIs
are disabled by default. Secrets are redacted from logs. Application routing models
distinguish `PROXY`, `DIRECT`, and `VOID`; DIRECT excludes the package from VpnService,
while VOID fails startup until its native fail-closed classifier is shipped.
## License and upstreams
This repository's original code is MIT-licensed; see `LICENSE`. Upstream components,
versions, URLs and license obligations are recorded in `THIRD_PARTY_NOTICES.md`.
Do not copy the GPL Android reference application's UI or source into this project.