infosave2007/aivpn

▲ 49 stars today★ 744⑂ 65

AI-VPN that makes your traffic invisible to deep packet inspection

About infosave2007/aivpn

infosave2007/aivpn is an open-source project on GitHub, mainly written in Rust. AI-VPN that makes your traffic invisible to deep packet inspection It currently holds 744 stars and 65 forks with 14 open issues, and was last pushed on 2026-10-28 (repository created 2026-03-26).

Project Overview

Git Homed tracks it on the Today's Trending board, currently at rank #84 with 49 new stars today.

GitHub Repository Details

Repository infosave2007/aivpn · default branch master · size 468422 KB · watchers 19 · source: GitHub REST API and repository README

README

Experimental Project. AIVPN is an engineering research project exploring network protocols and methods of protecting data in transit. It does not guarantee the ability to bypass network restrictions, anonymity, or protection against detection and blocking. The project has no political objectives.
The project is not intended for unlawful use. Users must comply with the laws applicable where they are located and use the software at their own risk. The author does not endorse unlawful use of the project.
Third-party claims about the project's guaranteed effectiveness or political purpose do not represent the author's position.

🌐 Русский | 中文

AIVPN

CI Crates.io Server Crates.io Client Rust Platforms

---

Overview

AIVPN combines UDP tunnel encryption with traffic masking. Masks define the outer protocol, packet sizes and send intervals. Being recognized as STUN or QUIC does not by itself prove statistical indistinguishability from a specific application.

Key technical properties:

---

Architecture

Workspace layout

crates/aivpn-common/     — shared crypto, protocol, mask profiles (no I/O)
crates/aivpn-server/     — Linux-only VPN gateway and management CLI
crates/aivpn-client/     — cross-platform VPN client (Linux / macOS / Windows)
crates/aivpn-android-core/ — JNI bridge for Android (Rust → Kotlin via C FFI)
crates/aivpn-ios-core/   — iOS Rust staticlib (C FFI), linked by PacketTunnelProvider
crates/aivpn-windows/    — Windows GUI (egui/eframe 0.31, manages aivpn-client.exe subprocess)
crates/aivpn-linux/      - Linux GUI (Iced 0.14, wraps aivpn-client subprocess)
platforms/android/       — Android Kotlin app (MVVM: MainViewModel + RecyclerView)
platforms/ios/           — iOS SwiftUI app + NetworkExtension PacketTunnelProvider
platforms/macos/         — macOS SwiftUI menu bar app + privileged helper daemon
platforms/aivpn-web/     — Web management panel (Hono 4 + SvelteKit 2, SQLite/PostgreSQL)
platforms/linux/         — Linux desktop packaging (AppImage, .desktop)
platforms/linux-kernel/  — optional in-kernel data-path module (out-of-tree)
platforms/openwrt/       — OpenWrt package
platforms/mikrotik/      — MikroTik RouterOS container
assets/masks/            — bundled traffic mimicry JSON profiles
assets/brand/            — icons and brand material
deploy/                  — server installer, systemd unit, Dockerfiles
deploy/ci/               — CI gates run by the Makefile (see make help)

Key modules

| Module | Location | Purpose | |--------|----------|---------| | crypto.rs | aivpn-common | X25519 key exchange, ChaCha20-Poly1305 AEAD, BLAKE3/HMAC, resonance tag generation | | protocol.rs | aivpn-common | Wire format: [8-byte tag][pad_len][inner_header][encrypted payload][poly1305 tag] | | mask.rs | aivpn-common | MaskProfile — traffic shaping: header templates, FSM states, IAT distributions | | gateway.rs | aivpn-server | Central event loop: UDP receive, session dispatch, NAT forwarding, neural checks | | session.rs | aivpn-server | SessionManager — DashMap-based O(1) tag lookup, 256-entry replay window, 500-session cap | | neural.rs | aivpn-server | Neural Resonance: per-mask MLP 64→16→64 / fallback 64→128→64, MSE threshold 0.35, auto mask rotation | | client.rs | aivpn-client | State machine: Unprovisioned → Connecting → Connected, key exchange, reconnection | | tunnel.rs | aivpn-client | Cross-platform TUN: /dev/net/tun (Linux), utun (macOS), Wintun (Windows) | | mimicry.rs | aivpn-client | MimicryEngine — applies MaskProfile to outbound packets |

Initial exchange and accelerator compatibility

Starting with 1.2.0, the initial exchange uses InitialV2. It is incompatible with 1.1.0 and earlier 1.2.0 development builds. Update servers, pool/site/chain nodes and all clients together, including embedded mobile cores. The connection key format and the inter-server management protocol are unchanged. The initial AEAD uses XChaCha20-Poly1305 with a random 24-byte nonce and the connection context in the AAD; the established channel keeps the existing ChaCha20-Poly1305 format and kernel ABI 7.

The Linux module requires compatible Rust-for-Linux APIs, kernel headers built with CONFIG_RUST=y and the matching Rust toolchain. A kernel version number alone does not guarantee support. Before registering /dev/aivpn, the module checks file_operations.owner in the real miscdevice vtable and fails with ENODEV if the API does not pin the module code to the open descriptor. This check cannot be bypassed; without the accelerator, userspace TUN is used.

Mask state and outer traffic validation

The QUIC mask runs bidirectional QUIC v1/TLS 1.3: it keeps CIDs and packet numbers and handles ACKs, loss, timers and connection close. The engine runs inside the shared mask layer on top of the existing UDP/DatagramTransport. A cold Initial carries an empty Token. The initial AIVPN packet travels inside an encrypted HTTP DATAGRAM after TLS, HTTP/3 SETTINGS and CONNECT-UDP; until then payload data waits in a bounded queue. When the local buffer is full, the client waits for free space while it keeps processing ACKs and control messages. The logical UDP peer terminates inside the mask; no proxy sockets are opened. A plain GET and an unrelated CONNECT-UDP receive HTTP 403. CONNECT-UDP is not equivalent to ordinary HTTP/3 requests to Avito or VK Video and does not by itself prove similarity to them. Before inner authentication the server keeps a separate bounded TLS state that grants no VPN access and cannot replace an active session. Up to 128 such states are allowed globally, at most two per UDP peer, with at most ten seconds to complete setup; processing is charged to a shared CPU budget. Until the address is validated, responses are limited to three times the received traffic. TLS verifies the handshake signature and possession of the certificate key, but not the public PKI: trust in the server comes from the inner signed AIVPN exchange. 0-RTT and connection migration are disabled.

The pre-authentication inbound packet limit is set by the server's --per-ip-pps-limit / AIVPN_PER_IP_PPS_LIMIT, 5000 packets per second per IP by default. The current QUIC generation with an admitted PFS session has a separate finite limit, --per-ip-authenticated-pps-limit / AIVPN_PER_IP_AUTHENTICATED_PPS_LIMIT, 100000 by default. Queues and counters for the two classes are bounded independently; pending TLS, plain and RTC traffic keep the first limit. The CID selects the route and quota but does not authenticate the packet: Quinn AEAD and the inner AIVPN checks remain mandatory, including for a known CID.

Seven profiles open the exchange with an aligned optional STUN Binding Indication attribute. After PFS, the protected MaskState message binds the outer protocol parameters to the profile and connection generation. Zoom and webrtc_yandex_telemost_v1 use ICE/DTLS/SRTP; SberJazz and Telegram calls add TURN Allocate, Permission, ChannelBind and ChannelData. WhatsApp uses ICE/SRTP without DTLS, with separate per-direction keys from the protected exchange. Keys, ICE credentials and certificates are created anew for each generation. All states run in the shared mask layer on top of the existing UDP socket; queues and setup time are bounded. VK Teams and Salute still use a limited STUN carrier. Mask names and a correct outer protocol do not guarantee indistinguishability from a specific application. Older external signed profiles with a 20-byte header must be reissued; the client does not modify signed data automatically.

The telegram_calls_v1 profile targets Telegram UDP calls, not MTProto. The former telegram_mtproto_v1, which wrongly used QUIC, is removed from the catalog. Explicit mask selections must replace its ID; the old ID is not an alias of the new one. TURN/ICE/DTLS/SRTP reproduce the observed media-channel stages, but not Telegram's signaling protocol.

The yandex_alice_v1 profile is temporarily excluded from the bundled catalog and installation bundle. The voice RPC of the verified Alice mobile app uses TLS/TCP rather than the current STUN/UDP carrier. The smart speaker protocol has not been verified separately.

The client picks size and IAT as one pair and schedules data without blocking control messages. The server uses a separate bounded queue per session and the reverse profile parameters when one is defined. In both directions IP flows are interleaved while each flow keeps its packet order: a large background transfer does not fill the whole queue ahead of DNS and new connections.

adaptive is the default. For QUIC, the protocol's own congestion control and pacer set the rate; no second per-IP-packet IAT timer is added. For other masks, light load keeps the profile intervals; persistent queueing delay gradually raises the rate, which returns to the original once the backlog clears. The controller tracks the age of the oldest packet and the minimum of that age over a 100 ms window. A delay above 5 ms raises the rate 1.5x per window; below 1 ms the rate returns toward the original with a factor of 0.8. Acceleration is capped at 4096x. Short accelerated intervals are merged into a 1 ms quantum limited to 64 original IP packets; after a delay, old quanta give no credit. Fragmentation may produce more outer frames. An expired deadline is processed immediately; a future one keeps waiting. A profile change resets the controller. This is local queue regulation, not a measurement of physical link capacity.

full mode keeps the original intervals under any load. Client off disables pauses while keeping padding and the mask format. Server off also disables padding, as before; server light caps the delay at two milliseconds and keeps a small padding budget. In adaptive, padding is unchanged, but intervals under load differ from the original profile. Preserving the format and encryption does not by itself prove resistance to DPI. Padding enlarges short packets but does not shrink long ones: the sizes and rate of the real workload limit how closely the profile can be matched.

The policy is set locally and is not imported from the connection key:

Restart the client process or the server service to apply a new setting. An invalid value is a configuration error, not a silent fallback to the default mode.

On Linux, a full tunnel without an assigned IPv6 address blocks IPv6 with two owned blackhole routes, including when the IPv4 MTU is below 1280. With an assigned IPv6 address, the interface MTU is never below 1280. An explicit disconnect removes the owned routes; after a crash, aivpn-client kill-switch clear removes the firewall rules and any remaining owned IPv6 guards. Leftover IPv6 routes are not cleaned up automatically on a normal start: only an explicit operator command removes them. Update the CLI and aivpn-ip-helper from the same build.

All 10 bundled profiles are available through --preferred-mask and --polymorphic-base; an unknown ID is rejected. The preference selects an initial candidate of the requested base from the verified bootstrap. If there is no such candidate, the client keeps the trusted opening and requests the base after PFS. --polymorphic-base takes precedence; later automatic server rotations still apply. Retries of the initial exchange keep the ephemeral key of a single attempt but use a fresh nonce. The whole attempt is limited to 10 seconds. Switching between the STUN and QUIC mask families does not require a new session. Outer QUIC and SRTP packets are limited to 1380 bytes; QUIC starts at 1200 UDP bytes and probes the path MTU up to 1380. The inner packet is limited to 1140 bytes for QUIC, 1324 for ICE/DTLS/SRTP and 1358 for ICE/SRTP. Padding accounts for the headers, AEAD and alignment of the selected carrier. Control messages are fragmented before encryption. QUIC and RTC run in userspace in both directions, and plain STUN TX also stays in userspace; ABI 7 is unchanged. Native installation and systemd stay the same.

The default TUN MTU is 1280 bytes; an explicit TUN MTU up to 1500 is preserved. Inner DATA and FEC repairs that exceed the carrier budget are authenticated and fragmented separately, then reassembled at the receiver. FEC counts each original IP packet once. A peer must support the 1.2.0 fragment format. Every FEC member carries an authenticated group number and position, including small packets. Groups remain separate across reordering and an FEC pause; completed groups reject late originals before fragment allocation. FEC frames use the userspace receive path even when FEC was enabled after a kernel session was installed.

The new QUIC mask format and bundled STUN profile versions require clients and servers to be updated together, including pool/site/chain nodes and mobile cores. The connection key format, PSK and inter-server management messages are unchanged. make mask-gate runs the real client and gateway over UDP with loss, delay and duplicates, verifies PFS and the reverse exchange, then parses bidirectional PCAPs with TShark and nDPI, checking the first packets separately. This validates structure and classification; it does not prove resistance to arbitrary DPI or active probing.

Pool sync

Server-to-server client database synchronization uses ControlPayload::PoolSync carried inside ordinary VPN UDP packets — indistinguishable from client traffic. No separate TCP port or firewall rule required.

---

Platform Support

| Platform | Server | Client | GUI | TUN driver | |----------|:------:|:------:|:---:|------------| | Linux CLI | ✅ | ✅ | — | /dev/net/tun | | Linux GUI | — | ✅ | ✅ iced AppImage + tray | /dev/net/tun | | macOS | — | ✅ | ✅ menu bar | utun | | Windows | — | ✅ | ✅ egui GUI | Wintun | | Android | — | ✅ | ✅ native Kotlin | VpnService API | | iOS | — | ✅ | ✅ SwiftUI | NetworkExtension | | MikroTik RouterOS 7.6+ | — | ✅ | — | container veth + TUN | | Entware routers (ARMv7 / MIPSel) | — | ✅ | — | musl static binary |

Feature Capability Matrix

| Feature | Linux CLI | Linux GUI | Win | Mac | Android | iOS | |---------|:---------:|:---------:|:---:|:---:|:-------:|:---:| | Traffic Mimicry | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Adaptive Mode (4 levels) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Live Quality Score | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Split Tunnel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | DNS Proxy | ✅ | ✅ | ✅ | ✅ | N/A* | ❌ | | Kill Switch | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | mTLS Certificate | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | FEC (forward error correction) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Traffic Recording | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Device Key / JIT | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | SOCKS5 Proxy | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | | Full Tunnel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Diagnostics / Benchmark | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Bootstrap Descriptor Discovery | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Polymorphic Masks | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Crowdsourced Mask Feedback (opt-in) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | In-App Admin (roles, client mgmt, revoke, audit)‡ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Pool Topology View + Per-Client Exit Node | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | SSH Server Install Wizard§ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Live Metrics Graphs† | — | — | — | — | — | — |

On macOS, Kill Switch blocks new connections outside the VPN and preserves connections that were already open when it was enabled.

\* Android's VpnService API routes all device traffic (including DNS) through the encrypted tunnel by design — there's no separate local DNS-proxy listener because none is needed; DNS leaks aren't possible on this platform.

† Live Metrics Graphs is a server + Web Management Panel feature, not a client capability — it requires building the server with --features metrics and is viewed from the web dashboard, not from any of the clients above.

‡ See In-App Client Administration & Roles. On desktop, the CLI exposes the same surface via aivpn-client mgmt/aivpn-client role (bridged over the local admin socket); Linux CLI's checkmark reflects that CLI bridge rather than a graphical admin screen.

§ See SSH Server Installer. Requires the client to be built with the ssh-install Cargo feature (bundled by default in the released GUI/mobile builds); on Linux CLI it is the aivpn-client ssh-install {script,probe,run} subcommand rather than a graphical wizard.

---

Web Management Panel

platforms/aivpn-web/ provides a full-stack web UI for managing the aivpn server.

Stack: Hono 4 + Bun (backend) · SvelteKit 2 + Svelte 5 + TailwindCSS 4 (frontend) · Layerchart charts · SQLite (default) or PostgreSQL

Features:

Quick Start:

# 1. Generate secrets
JWT_SECRET=$(openssl rand -base64 48)
TOTP_KEY=$(openssl rand -base64 32)

2. Run with Docker (simplest)

docker run -d --name aivpn-web \ -v /run/aivpn:/run/aivpn \ -e JWT_SECRET="$JWT_SECRET" \ -e TOTP_ENCRYPTION_KEY="$TOTP_KEY" \ -e ORIGIN=https://vpn.example.com \ -p 8080:8080 \ ghcr.io/infosave2007/aivpn-web:latest

3. Get the one-time admin password from the startup log

docker logs aivpn-web 2>&1 | grep -A4 "FIRST-TIME SETUP"

4. Open https://vpn.example.com and log in with username "admin"

Or via docker compose up -d aivpn-web (secrets go in platforms/aivpn-web/.env).

Run (Bun, from source):

cd platforms/aivpn-web
cp .env.example .env          # fill JWT_SECRET, TOTP_ENCRYPTION_KEY, ORIGIN
bun install && bun run build
bun run start                 # listens on PORT (default 8080)

Key environment variables:

| Variable | Default | Description | |----------|---------|-------------| | DATABASE_URL | file:./data/aivpn-web.db | SQLite path or postgres://... | | JWT_SECRET | — | Long random string for token signing | | TOTP_ENCRYPTION_KEY | — | 32-byte base64 key (openssl rand -base64 32) | | ORIGIN | — | Public HTTPS URL (required for WebAuthn / CSRF) | | UNIX_SOCK | /run/aivpn/api.sock | Path to aivpn management socket | | PORT | 8080 | HTTP listen port |

Makefile targets:

make web           # install deps + build frontend
make web-docker    # build Docker image aivpn-web:latest
make web-dev       # start dev servers (hot reload)

An nginx reverse-proxy example is in deploy/nginx/aivpn-web.conf.

Default credentials (first run):

On first startup with an empty database, a random admin password is generated and printed once to the server console:

╔══════════════════════════════════════════════════╗
║         FIRST-TIME SETUP — SAVE THESE NOW        ║
╠══════════════════════════════════════════════════╣
║  Username : admin                                 ║
║  Password :      ║
╚══════════════════════════════════════════════════╝

Save this password immediately — it is shown once only. After logging in, change it in Settings → Security or register a passkey.

OIDC / SSO (optional):

| Variable | Description | |----------|-------------| | OIDC_ISSUER | IdP base URL (e.g. https://accounts.google.com) | | OIDC_CLIENT_ID | OAuth2 client ID | | OIDC_CLIENT_SECRET | Client secret (omit for public PKCE clients) | | OIDC_MODE | disabled (default) · enabled (adds SSO button) · exclusive (SSO only) | | OIDC_ROLE_CLAIM | ID token claim containing the user's role (e.g. role) | | OIDC_ADMIN_VALUE | Claim value that grants admin role (default: admin) |

The role from OIDC is applied only on first SSO login; admins can override it afterwards in the web panel.

---

Quick Start

Server (Linux)

Docker (recommended)

```bash mkdir -p config docker comp

GitHub Stars & Activity

744Stars
65Forks
14Open issues
RustLanguage

GitHub Popularity

GitHub stars744
Forks65
Open issues14
Primary languageRust
LicenseNOASSERTION
Stars gained today49
Created2026-03-26
Last pushed2026-10-28

Trending History

Daily boardrank #84 · ▲ 49 stars

Related GitHub Projects

1

rustdesk / rustdesk

Rust★ 127,567⑂ 20,169▲ 160 stars
→
2

ruvnet / RuView

Rust★ 101,668⑂ 13,208▲ 849 stars
→
3

pbakaus / impeccable

Rust★ 96,301⑂ 5,663▲ 2,870 stars
→
4

juspay / hyperswitch

Rust★ 45,567⑂ 6,560▲ 128 stars
→
5

janhq / jan

Rust★ 45,163⑂ 3,117▲ 34 stars
→
6

vercel-labs / agent-browser

Rust★ 44,893⑂ 3,071▲ 83 stars
→
7

magnitudedev / magnitude

Rust★ 7,587⑂ 541▲ 141 stars
→
8

agentgateway / agentgateway

Rust★ 5,797⑂ 1,028▲ 63 stars
→

More Trending Repositories