Files
konduit-public/docs/stealth-setup.md
2026-06-26 23:16:30 +03:00

3.0 KiB

Stealth Mode Setup

Stealth mode makes VPN traffic look like normal HTTPS to deep packet inspection systems. The client opens a real TLS 1.3 connection, performs a WebSocket upgrade, and then carries the konduit protocol inside WebSocket binary frames — identical in appearance to any browser-based web app.

Client  ──TLS 1.3──▶  HAProxy :443 (TCP passthrough)  ──▶  Konduit :8443
                       HTTP/1.1 GET /ws  →  101 Switching Protocols
                       WebSocket binary frames (konduit protocol inside)

Server Requirements

  • A domain with a valid TLS certificate (Let's Encrypt / certbot)
  • HAProxy 2.4+
  • Konduit server on a non-public port (e.g. 8443)

HAProxy Configuration

HAProxy acts as a pure TCP proxy — it passes TLS through to the konduit server unchanged.

frontend https-ingress
    bind *:443
    mode tcp
    default_backend konduit-vpn

backend konduit-vpn
    mode tcp
    timeout tunnel 0
    server konduit 127.0.0.1:8443

timeout tunnel 0 prevents HAProxy from dropping idle connections.

Reload after changes:

haproxy -c -f /etc/haproxy/haproxy.cfg   # validate first
systemctl reload haproxy

Konduit Server (server.toml)

[server]
listen_addr = "0.0.0.0"
listen_port = 8443
public_addr = "your-domain.com"
public_port = 443
tls_cert    = "/etc/letsencrypt/live/your-domain.com/fullchain.pem"
tls_key     = "/etc/letsencrypt/live/your-domain.com/privkey.pem"
websocket   = true

Client Configuration (client.toml)

[client]
server_endpoint   = "your-domain.com:443"
peer_id           = "..."
identity_key      = "..."
server_public_key = "..."

[stealth]
enabled = true

That's it — stealth = true activates TLS and WebSocket camouflage automatically.

Flutter / Mobile App

Enable Stealth Mode in the app settings. The toggle maps to [stealth] enabled = true in the connection config and activates TLS + WebSocket camouflage on all platforms (Linux, Android, Windows).

For QR-code-based provisioning, the t: true field in the QR payload enables stealth.

Verify

# TLS cert must be valid — browser must reach your site
curl -s https://your-domain.com/ | head -5

# Connect the VPN client
sudo ./konduit --config client.toml

# Watch HAProxy — you should see the tunnel established
journalctl -u haproxy -f

Common Mistakes

Mistake Effect Fix
HAProxy terminating TLS (bind *:443 ssl crt ...) konduit receives plain TCP, WebSocket handshake fails Use bind *:443 (no ssl) — TCP passthrough
Missing timeout tunnel 0 Connection drops after 30 s of silence Add timeout tunnel 0 to backend
Port 8443 exposed to internet Bypass HAProxy entirely Firewall port 8443 to localhost only
Expired/self-signed cert TLS error on client Use Let's Encrypt; renew via certbot
stealth = false on client Plain TCP connection, DPI detects VPN Set [stealth] enabled = true