3.4 KiB
3.4 KiB
Stealth Mode: HAProxy + Konduit
Konduit's stealth mode makes the VPN server indistinguishable from a normal HTTPS site. It implements a fake TLS handshake — embedding the client's ephemeral key inside the TLS SessionID field. For this to work, konduit must see the raw TCP stream from the client. Any proxy that terminates TLS before konduit breaks stealth mode.
Architecture
Client
│ raw TCP (looks like TLS to observers)
▼
HAProxy :443 ── TCP passthrough ──► konduit-server :8443
│
valid handshake │ handshake fails (real browser)
│ ▼
│ HAProxy :4443 (SSL termination)
│ │
│ ▼
│ real HTTPS backend
VPN tunnel
HAProxy Configuration
# VPN ingress — raw TCP passthrough, no SSL termination
frontend vpn-ingress
bind *:443
mode tcp
option tcplog
default_backend konduit-vpn
backend konduit-vpn
mode tcp
server konduit 127.0.0.1:8443
# Camouflage backend — receives failed handshakes from konduit via PROXY protocol
# SSL is terminated here, not on the ingress
frontend camouflage
bind *:4443 ssl crt /etc/haproxy/ssl/your-domain.pem accept-proxy
mode http
http-request set-header X-Real-IP %[src]
http-request set-header X-Forwarded-Proto https
default_backend web
backend web
mode http
server web1 127.0.0.1:80 check
Konduit server.toml
[server]
listen_addr = "0.0.0.0"
listen_port = 8443
public_addr = "your-domain.com"
public_port = 443 # port clients connect to (HAProxy front)
[stealth]
enabled = true
camouflage = "127.0.0.1:4443" # where to proxy non-konduit connections
Bootstrap with --public-port so generated client configs reference port 443:
echo "your mantra" | ./konduit-ctl bootstrap -l your-domain.com:8443 --public-port 443 -p -
How It Works
Konduit client (stealth handshake):
- Client sends fake TLS ClientHello with identity proof embedded
- HAProxy passes raw TCP to konduit on port 8443
- Konduit verifies identity, completes handshake, establishes VPN tunnel
- Traffic looks like TLS Application Data to any observer
Real browser or censor probe:
- Browser sends a real TLS ClientHello
- HAProxy passes it raw to konduit
- Konduit cannot verify identity — proxies the connection to
127.0.0.1:4443with a PROXY protocol header preserving the real client IP - HAProxy at 4443 terminates TLS and serves your website
- Observer sees a normal HTTPS site
Common Mistakes
# WRONG — TLS terminated by HAProxy before konduit, fake handshake never works
Client → HAProxy SSL termination → konduit
# CORRECT — raw TCP passed through, konduit handles the fake TLS
Client → HAProxy TCP passthrough → konduit → HAProxy SSL termination (on failure)
The camouflage frontend uses accept-proxy — do not use it as the VPN ingress.
Verify
# Browser should see your real website, not an error
curl -sk https://your-domain.com/
# Check konduit logs for stealth handshakes
journalctl -u konduit-server -f | grep -E "Stealth|Authenticated|camouflage"