docs: add server quickstart, stealth setup guide, and download table
This commit is contained in:
24
README.md
24
README.md
@@ -40,20 +40,36 @@ Most VPNs treat TCP as a fallback. Konduit is designed for TCP from the ground u
|
|||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
Releases are published on the [Releases](../../releases) page.
|
Releases are published on the [Releases](../../releases) page. Each release includes:
|
||||||
|
|
||||||
|
| Binary | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `konduit-server` | VPN server |
|
||||||
|
| `konduit` | CLI client (Linux) |
|
||||||
|
| `konduit-ctl` | Server provisioning tool |
|
||||||
|
|
||||||
### Linux (CLI)
|
### Linux (CLI)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Download konduit-cli from the Releases page, then:
|
# Download konduit and konduit-ctl from the Releases page, then:
|
||||||
chmod +x konduit-cli
|
chmod +x konduit konduit-ctl
|
||||||
./konduit-cli connect --server vpn.example.com:443 --peer-id mydevice --psk YOUR_PSK
|
|
||||||
|
# Bootstrap a server
|
||||||
|
echo "your secret mantra" | ./konduit-ctl bootstrap -l vpn.example.com:443 -p -
|
||||||
|
|
||||||
|
# Connect a client
|
||||||
|
./konduit connect --config client.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
### macOS · Android · iOS
|
### macOS · Android · iOS
|
||||||
|
|
||||||
Coming soon.
|
Coming soon.
|
||||||
|
|
||||||
|
## Server Setup
|
||||||
|
|
||||||
|
- [Server Quickstart](docs/server-quickstart.md) — install, provision, NAT setup for iptables and firewalld
|
||||||
|
- [Stealth Mode Setup](docs/stealth-setup.md) — HAProxy TCP passthrough + camouflage configuration
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
105
docs/server-quickstart.md
Normal file
105
docs/server-quickstart.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# Konduit Server Quickstart
|
||||||
|
|
||||||
|
## 1. Prerequisites
|
||||||
|
|
||||||
|
### IP Forwarding
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo sysctl -w net.ipv4.ip_forward=1
|
||||||
|
# Persist: add 'net.ipv4.ip_forward=1' to /etc/sysctl.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Capabilities
|
||||||
|
|
||||||
|
Konduit needs permission to create TUN devices and bind privileged ports without running as root.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo setcap cap_net_admin,cap_net_bind_service=+ep ./konduit-server
|
||||||
|
sudo setcap cap_net_admin=+ep ./konduit
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Bootstrap
|
||||||
|
|
||||||
|
Konduit derives its identity key from a **mantra** (secret phrase) using Argon2id. Keep the mantra safe — it lets you recover the same identity if the config file is lost.
|
||||||
|
|
||||||
|
**Standard (konduit binds on 443):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "your secret mantra phrase here" | ./konduit-ctl bootstrap -l vpn.example.com:443 -p -
|
||||||
|
```
|
||||||
|
|
||||||
|
**Behind a reverse proxy (HAProxy on 443, konduit on 8443):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "your secret mantra phrase here" | ./konduit-ctl bootstrap -l vpn.example.com:8443 --public-port 443 -p -
|
||||||
|
```
|
||||||
|
|
||||||
|
`--public-port` sets the port written into client configs, so they connect to 443 even though konduit listens on 8443. See [stealth-setup.md](stealth-setup.md) for the full HAProxy configuration.
|
||||||
|
|
||||||
|
## 3. Add a Client
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./konduit-ctl add-client my-laptop
|
||||||
|
```
|
||||||
|
|
||||||
|
Creates `my-laptop.client.toml` and appends the peer to `server.toml`. Transfer the `.client.toml` to the client device, or scan the QR payload with the mobile app.
|
||||||
|
|
||||||
|
## 4. TUN Interface Name
|
||||||
|
|
||||||
|
Set a fixed TUN interface name so firewall rules are stable:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# server.toml
|
||||||
|
[network]
|
||||||
|
tun_name = "konduit0"
|
||||||
|
```
|
||||||
|
|
||||||
|
Without this, konduit picks the first available `tunN`, which shifts if other VPN interfaces exist.
|
||||||
|
|
||||||
|
## 5. Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./konduit-server --config server.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
For persistent operation, use the provided systemd unit (`setup/server/konduit-server.service`).
|
||||||
|
|
||||||
|
## 6. NAT / Masquerade
|
||||||
|
|
||||||
|
VPN clients send packets with source IP `10.10.0.x`. Masquerade rewrites this to the server's public IP so internet hosts can reply.
|
||||||
|
|
||||||
|
### firewalld (RHEL, Fedora, recent Ubuntu)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Trust the VPN interface
|
||||||
|
sudo firewall-cmd --zone=trusted --add-interface=konduit0 --permanent
|
||||||
|
|
||||||
|
# Enable masquerade on the public zone
|
||||||
|
sudo firewall-cmd --zone=public --add-masquerade --permanent
|
||||||
|
|
||||||
|
sudo firewall-cmd --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Important:** `iptables` commands are silently ignored on firewalld systems. Always use `firewall-cmd`.
|
||||||
|
|
||||||
|
### iptables (Debian/Ubuntu without firewalld)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
IFACE=$(ip route get 1.1.1.1 | awk '{print $5; exit}')
|
||||||
|
sudo iptables -t nat -I POSTROUTING 1 -s 10.10.0.0/24 -o $IFACE -j MASQUERADE
|
||||||
|
sudo iptables -I FORWARD 1 -i konduit0 -o $IFACE -j ACCEPT
|
||||||
|
sudo iptables -I FORWARD 2 -i $IFACE -o konduit0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
|
||||||
|
# Persist
|
||||||
|
sudo apt install iptables-persistent && sudo netfilter-persistent save
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Should return your website (camouflage) not an error
|
||||||
|
curl -sk https://your-server/
|
||||||
|
|
||||||
|
# Check konduit logs
|
||||||
|
journalctl -u konduit-server -f
|
||||||
|
```
|
||||||
105
docs/stealth-setup.md
Normal file
105
docs/stealth-setup.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
```haproxy
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "your mantra" | ./konduit-ctl bootstrap -l your-domain.com:8443 --public-port 443 -p -
|
||||||
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
**Konduit client (stealth handshake):**
|
||||||
|
1. Client sends fake TLS ClientHello with identity proof embedded
|
||||||
|
2. HAProxy passes raw TCP to konduit on port 8443
|
||||||
|
3. Konduit verifies identity, completes handshake, establishes VPN tunnel
|
||||||
|
4. Traffic looks like TLS Application Data to any observer
|
||||||
|
|
||||||
|
**Real browser or censor probe:**
|
||||||
|
1. Browser sends a real TLS ClientHello
|
||||||
|
2. HAProxy passes it raw to konduit
|
||||||
|
3. Konduit cannot verify identity — proxies the connection to `127.0.0.1:4443` with a PROXY protocol header preserving the real client IP
|
||||||
|
4. HAProxy at 4443 terminates TLS and serves your website
|
||||||
|
5. 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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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"
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user