qtun

A post-quantum, leak-proof, self-hiding VPN — in two static binaries.

ML-KEM-768 (FIPS 203) X25519 hybrid ChaCha20-Poly1305 dual-stack traffic obfuscation

Quantum-proof cryptography

Harvest-now-decrypt-later resistant. Built on Go 1.26 stdlib crypto, no external crypto code.

Hybrid key exchange

Every handshake combines ML-KEM-768 (NIST FIPS 203, lattice-based) with classical X25519. An attacker must break both to learn anything — including a future quantum computer.

Authenticated transport

All traffic inside ChaCha20-Poly1305 AEAD with 256-bit session keys derived via HKDF-SHA256. 64-bit packet counters and a 2048-packet sliding replay window.

Forward secrecy

Ephemeral keys on every handshake; sessions rekey automatically every 2 minutes. Past traffic stays unreadable even if the PSK leaks later.

Mutual PSK authentication

Both sides prove possession of a 256-bit pre-shared key via HMAC-SHA256 transcript tags. The server generates a random key file (mode 0600) on first start — just copy it to clients.

Zero-leak routing

If traffic can't go through qtun, it goes nowhere.

Full-tunnel by default

Dual-stack IPv4 and IPv6. Covering /1 routes capture everything; the server address is pinned via the original gateway so the underlay never loops.

IPv6: tunneled or dead

If the server offers IPv6, it's routed through the tunnel like IPv4. If not, IPv6 is hard-disabled for the session (restored on exit) — no silent v6 escape hatch.

DNS kill-switch

All outbound and forwarded port-53 traffic is DNAT'd into the tunnel; anything that would bypass (loopback and tunnel excepted) is REJECTed. Hardcoded-DNS apps can't leak either.

systemd-resolved integration

Detects resolvectl and registers the tunnel link as default DNS route (~.), so per-link-socket behavior of resolved is handled correctly. Cleanly reverted on exit.

Built-in recursive DNS

No upstream forwarders. No third party ever sees a query.

True recursion

The server resolves from the root servers down — root hints → TLD → authoritative. No 8.8.8.8, no ISP resolver, no logging middleman.

Tunnel-only, random port

The resolver binds only to the tunnel gateway addresses on a random high port (20000–60000, collision-checked). Unreachable from the WAN.

Encrypted by construction

Client queries ride inside the ML-KEM-encrypted tunnel — DNS gets post-quantum protection without needing DoH/DoT layers on top.

Fast & resilient

TTL-aware positive/negative cache, CNAME chasing, TCP fallback on truncation, concurrency-capped so query floods can't stall the resolver. Outbound recursion is SO_MARK-tagged so it can never loop back into the tunnel.

Multi-server resilience

One PSK, as many exits as you like.

Round-robin rotation

-server a:55555,b:55555 — the client re-handshakes to the next server every rekey interval. A single DNS name with multiple A/AAAA records expands into multiple servers automatically.

Instant failover

A dead server is skipped after a 3s handshake timeout; the client walks the list until one answers. Addresses and DNS config re-apply automatically on switch.

Same-IP replies

Multi-homed servers read IP_PKTINFO and answer from the exact address the client contacted — ingress IP equals egress IP, per client, v4 and v6.

Traffic obfuscation

Optional stealth mode — the wire shows only random blobs.

Header masking

Every datagram is XOR-masked with a PSK-keyed ChaCha20 stream under a random per-packet nonce. No type bytes, no counters, no fingerprint.

Random padding

Adjustable per-packet padding (-obfs-pad) decorrelates datagram sizes from the inner IP traffic.

Chaff traffic

-chaff-ms N keeps a randomized drip of junk packets flowing in both directions, so idle and busy periods look alike.

vs. the classics

Where qtun stands.

qtunWireGuardOpenVPN
Post-quantum key exchangeML-KEM-768 + X25519nono
Transport cipherChaCha20-Poly1305ChaCha20-Poly1305AES-GCM (varies)
Forward secrecyrekey every 2 minevery 2 minTLS-dependent
Built-in recursive DNSyes, tunnel-onlynono
Anti-leak kill-switchroutes + DNS + IPv6manualmanual
Server round-robin / failoverbuilt-innoremote-random
Traffic obfuscationmask + pad + chaffnovia proxies
Kernel-space speeduserspace (TUN)yesuserspace
Formal security analysisnot yetyesyes

Quick start

Two static binaries. No dependencies.

# server (first start generates /etc/qtun.psk, mode 0600)
qtun-server -listen 0.0.0.0:55555 -psk-file /etc/qtun.psk -nat

# client — full dual-stack tunnel + encrypted DNS + rotation
qtun-client -server vpn1.example.com:55555,vpn2.example.com:55555 \
    -psk-file /etc/qtun.psk

# stealth mode
qtun-client -server test.qtun.de:55555 -psk-file /etc/qtun.psk \
    -obfs -obfs-pad 96 -chaff-ms 200