AIVPN hides a VPN tunnel inside traffic that looks like DNS or QUIC
AI-VPN that makes your traffic invisible to deep packet inspection
At a glance
- What is it?
- AIVPN is a UDP-based VPN written in Rust whose distinguishing idea is traffic mimicry, since outbound packets are reshaped to resemble known application protocols such as WebRTC, QUIC and DNS over UDP so that a passive observer sees something statistically ordinary. The session lookup is also unusual, since no session identifier travels in the clear and the server resolves sessions from an eight-byte tag.
- Who is it for?
- Adopt AIVPN if you are on a network where a tunnel is visible to inspection and you need the traffic to look like ordinary application traffic, since that is the specific problem it is built to solve and the module list shows real engineering behind it.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The idea is that the tunnel should not look like a tunnel
AIVPN is described as a UDP-based VPN system that combines standard tunnel encryption with traffic mimicry. Outbound packets are reshaped to resemble known application protocols, with WebRTC, QUIC and DNS over UDP named, and the stated goal is that the connection becomes statistically indistinguishable from regular application traffic to passive observers.
That is a specific and narrow threat model, and being clear about it is what makes the rest of the design legible. The adversary here is an observer who is classifying traffic rather than one who is decrypting it. A VPN tunnel that carries a distinctive handshake, or one that sits on a port nothing else uses, is trivially labelled. The response is to make the packets look like something else.
The properties listed under the overview are the ones that make that workable in practice. There is a zero-RTT data start, so encrypted payload can flow in the first packet with no mandatory handshake round trip, which matters because a handshake that takes two round trips is a handshake an observer can see and time.
Then there is the session lookup, and this is the part that surprised me. No session identifier is transmitted in the clear. Every packet carries an 8-byte resonance tag derived from a timestamp and a per-session secret, and the server resolves the session in constant time via a DashMap. So there is no identifier field on the wire for anyone to fingerprint, and the lookup cost does not grow with the number of sessions.
Perfect forward secrecy is there too, via in-flight session key rotation with an X25519 ratchet, so compromising the server key does not expose past traffic.
The project is Rust with a client binary of about 2.5 MB, and the description notes it runs on a five dollar VPS.
The neural part watches the traffic and rotates the mask when it drifts
The Neural Resonance module is the piece that makes the mimicry adaptive rather than fixed.
It is a per-mask micro-MLP, around 66 KB, that monitors live traffic statistics. When the reconstruction error is high, it triggers automatic mask rotation without disconnecting clients.
The way to read that is as a drift detector. A mask is a statistical profile of what the traffic looks like, and a profile that was recorded from real traffic will match real traffic for a while. But the underlying distribution moves, whether because the mix of applications behind the tunnel changed or because the network's own behaviour changed, and a fixed profile that no longer matches is a signature. The micro-MLP models the expected distribution and the reconstruction error says how far the live traffic has drifted from it, so the mask can be replaced before the drift becomes a classifier's signal.
The module details are in the table. The neural.rs file lives in the server crate and implements a per-mask MLP of 64 to 128 to 64 with an MSE threshold of 0.35 and auto mask rotation.
The masks themselves come from a separate mechanism. The generative mask distributions are auto-recorded from real traffic, modelling multimodal packet size and inter-arrival behaviour with a BIC-selected Gaussian mixture, and the design document section on neural-generated masks calls out that this reproduces real DNS, QUIC and WebRTC distributions far more faithfully than a single Gaussian. The important clarification is that this is an internal representation sampled transparently by every client, not a separate mask type.
That last point matters. If the generative masks were a separate kind of mask that only some clients used, then the traffic would fall into two populations and the distinction between them would itself be a signal. Because every client samples the same representation, there is nothing to tell apart.
The bundled profiles live in the assets/masks directory as traffic mimicry JSON profiles, so the set you ship with determines what your traffic looks like before any recording happens.
The protocol is one tag, one length and then ciphertext
The key modules table gives the wire format, and it is short enough to be worth reading exactly.
The protocol.rs file in the common crate handles the wire format, which is an 8-byte tag, then pad_len, then an inner header, then the encrypted payload, then a poly1305 tag.
So a packet on the wire is a constant-size tag the server uses to find the session, a length field, a header, the ciphertext and the authentication tag. There is no session identifier and no obvious version field, because either would be a stable thing to match on.
The pad_len field is worth a moment, because padding is how the mimicry works. The payload length is masked to match what the masqueraded protocol would produce, so a DNS query and a large file transfer both end up with plausible packet sizes.
The crypto module handles X25519 key exchange, ChaCha20-Poly1305 AEAD, BLAKE3 and HMAC, and the resonance tag generation. The dependency list confirms the choices, with chacha20poly1305 at 0.10, x25519-dalek at 2.0, blake3 at 1.8, hmac at 0.12 and sha2 at 0.10, alongside zeroize for clearing secrets from memory and subtle for constant-time operations.
The masking itself is the mask.rs file, which defines a MaskProfile with header templates, finite state machine states and inter-arrival time distributions, and the mimicry.rs file in the client is the MimicryEngine that applies a MaskProfile to outbound packets.
On the server side, gateway.rs is the central event loop handling UDP receive, session dispatch, NAT forwarding and the neural checks, and session.rs is the SessionManager with the DashMap-based constant-time tag lookup, a 256-entry replay window and a 500-session cap.
The replay window and the session cap are the two numbers worth remembering, since they bound what a server can hold and how much replay it will accept before the session state fills up.
Server to server sync rides inside ordinary client packets
There is a detail in the architecture section that removes an entire category of operational problem, and it is easy to miss.
Server-to-server client database synchronisation uses a ControlPayload::PoolSync carried inside ordinary VPN UDP packets. The stated consequence is that it is indistinguishable from client traffic, and that no separate TCP port or firewall rule is required.
That last point is the practical one. A conventional management channel for a VPN fleet means a port that has to be opened on every node, a rule in every firewall, and an obvious target for anyone watching for management traffic. Folding the synchronisation into the data path means a deployment is one UDP port, which is what you need for a system whose entire premise is that its traffic should blend in.
The platform support table shows how many deployment shapes this leads to. The server is Linux only and is described as the VPN gateway and management CLI, while the client runs on Linux, macOS and Windows. There are also platform crates for Android, iOS, Windows and Linux, and the platform directories hold the native apps, including an Android Kotlin app with MVVM and a RecyclerView, an iOS SwiftUI app with a NetworkExtension PacketTunnelProvider, a macOS SwiftUI menu bar app with a privileged helper daemon, a web management panel built on Hono and SvelteKit with SQLite or PostgreSQL, an optional in-kernel data path module, an OpenWrt package and a MikroTik RouterOS container.
The TUN drivers are named per platform, since that is where a cross-platform VPN usually gets messy. The tunnel.rs file in the client handles /dev/net/tun on Linux, utun on macOS and Wintun on Windows, and the table gives the Android VpnService API and the iOS NetworkExtension for the mobile platforms.
The client state machine is also explicit in the module table. client.rs is a Unprovisioned to Connecting to Connected progression with key exchange and reconnection.
A capability matrix, and the places where the platforms differ
The feature capability matrix is one of the more useful pieces of documentation in the repository, and the differences it records are real rather than cosmetic.
Traffic mimicry, adaptive mode with four levels, the live quality score, split tunnelling, the kill switch, mutual TLS certificates, forward error correction, traffic recording, device key and JIT provisioning, SOCKS5 proxy, full tunnel, the diagnostics and benchmark tooling, bootstrap descriptor discovery, polymorphic masks, opt-in crowdsourced mask feedback, in-app admin with roles and client management and revoke and audit, the pool topology view with per-client exit node, and the SSH server install wizard are all marked as present on every platform listed, which is Linux CLI, Linux GUI, Windows, Mac, Android and iOS.
Then there are the exceptions, and they are the interesting rows.
The DNS proxy row is marked N/A for Android and a cross for iOS. The footnote explains the Android case: the VpnService API routes all device traffic including DNS through the encrypted tunnel by design, so there is no separate local DNS proxy listener because none is needed, and DNS leaks are not possible on that platform.
The SOCKS5 proxy row is marked present everywhere except Android and iOS, which follows from the same platform design rather than being an omission.
The live metrics graphs row is marked as absent on every platform in the table, so that is a feature that is not in any of the listed clients yet.
The adaptive mode with four levels is worth noting as a concept even without more detail. The idea is that the closer the mimicry is to the real thing, the more traffic you have to shape and the more it costs, so a level setting trades stealth against performance, and the live quality score is presumably the feedback that tells you where you are.
The MikroTik row is also notable, since RouterOS 7.6 or newer is listed with a container veth and TUN arrangement, and there is an Entware row for ARMv7 and MIPSel routers with a musl static binary. Those are unusual targets for a VPN and they tell you where the author expects the system to be deployed.
The workspace layout and what the Rust build tells you
The Cargo.toml describes a workspace with seven member crates and three default members, which is the fastest way to understand the code structure.
[workspace]
members = [
"crates/aivpn-common",
"crates/aivpn-client",
"crates/aivpn-server",
"crates/aivpn-android-core",
"crates/aivpn-ios-core",
"crates/aivpn-windows",
"crates/aivpn-linux",
]
default-members = [
"crates/aivpn-common",
"crates/aivpn-client",
"crates/aivpn-server",
]
resolver = "2"The default-members are the common crate, the client and the server, which is what you build when you are working on the core protocol rather than on a specific platform app. The workspace package metadata gives the version as 1.1.0, edition 2021, with the description AIVPN, an AI-powered VPN designed for censorship circumvention, and the authors listed as the AIVPN Team.
The dependency list shows the engineering priorities. The crypto section is the group listed first, and the constant-time crate subtle is there alongside the primitives, which tells you the implementation is treating side channels as a concern.
The async section is where there is a comment worth reading, because it explains a design decision rather than just a dependency:
# Object-safe `async fn` in traits. Native RPITIT `async fn` in traits is not
# dyn-compatible, and the transport abstraction is used as
# `Arc<dyn DatagramTransport>` (a runtime-selected transport), so the
# boxed-future desugaring is required.
async-trait = "0.1"The comment above the async-trait entry explains that object-safe async fn in traits is needed because native RPITIT async fn in traits is not dyn-compatible, and the transport abstraction is used as an Arc<dyn DatagramTransport>, a runtime-selected transport, so the boxed-future desugaring is required. That is a paragraph of explanation for a single dependency line, and it is the kind of comment that saves a reader an afternoon of trying to remove the dependency.
The networking section has socket2 with all features, and the concurrency section has dashmap at 5.5 and parking_lot at 0.12, which matches the session lookup design described earlier.
The repository also ships a Makefile whose CI gates are described in the deploy/ci directory, a Dockerfile, a docker-compose.yml, and a THREAT_MODEL.md in English, Chinese and Russian alongside the three README languages.
Editorial conclusion
Adopt AIVPN if you are on a network where a tunnel is visible to inspection and you need the traffic to look like ordinary application traffic, since that is the specific problem it is built to solve and the module list shows real engineering behind it. Skip it if your threat model is a passive observer only, because the traffic mimicry is aimed at classification and it is not a substitute for a well configured transport, and if you cannot run a Linux server with a public address. Verify first which mask profiles ship with the build, since the bundled profiles are what determine what your traffic actually looks like on the wire, that the server and client versions match, since the crates are published separately, and that you read the threat model document, since the repository ships one in three languages and it will tell you what this tool does not protect against.
Frequently asked questions
What is AIVPN and how does its traffic mimicry work?
AIVPN is a UDP-based VPN system written in Rust that combines standard tunnel encryption with traffic mimicry, where outbound packets are reshaped to resemble known application protocols such as WebRTC, QUIC and DNS over UDP so the connection is statistically indistinguishable from regular application traffic to passive observers. The masks model multimodal packet size and inter-arrival behaviour with a BIC-selected Gaussian mixture rather than a single Gaussian.
How does the AIVPN server identify a session without a session ID?
No session identifier is transmitted in the clear. Every packet carries an 8-byte resonance tag derived from a timestamp and a per-session secret, and the server resolves the session in constant time via a DashMap. The SessionManager keeps a 256-entry replay window and a 500-session cap.
Which platforms does the AIVPN client support?
The client runs on Linux, macOS, Windows, Android and iOS, with a Linux GUI, a macOS menu bar app, a Windows GUI, a native Kotlin Android app and a SwiftUI iOS app. The server is Linux only. There are also packages for MikroTik RouterOS 7.6 or newer, Entware routers on ARMv7 and MIPSel, and OpenWrt, plus an optional in-kernel data path module.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/infosave2007-aivpn)Was this useful?