Skip to content

WireGuard VPN

Tunnel Architecture

The infrastructure uses three WireGuard tunnels with different access scopes:

graph LR
    LAPTOP[Admin Laptop]
    LOCALVM[Local VM]

    subgraph Strato["Strato VPS"]
        HOST[Host]
        VM[KVM VM]
    end

    LAPTOP -->|"strato-host<br/>10.0.0.0/24<br/>:51820"| HOST
    LAPTOP -->|"strato-vm<br/>10.0.1.0/24<br/>:51821"| VM
    LOCALVM -->|"openclaw-ai<br/>10.0.3.0/24<br/>:51822"| VM

Tunnel Details

strato-host (Admin VPN)

Property Value
Listen Port 51820
Server IP 10.0.0.1
Laptop IP 10.0.0.2
Phone IP 10.0.0.3
Subnet 10.0.0.0/24
Purpose Full admin access to host
Access SSH, dashboards, DNS, VM (via forwarding)
Host Access ✅ Full

PostUp rules configure DNS forwarding to Pi-hole:

# Forward DNS from VPN clients to Pi-hole
iptables -t nat -A PREROUTING -i strato-host -p udp --dport 53 -j DNAT --to 172.20.10.53:53
iptables -t nat -A PREROUTING -i strato-host -p tcp --dport 53 -j DNAT --to 172.20.10.53:53
iptables -I FORWARD 1 -i strato-host -d 172.20.10.53 -p udp --dport 53 -j ACCEPT
iptables -I FORWARD 1 -i strato-host -d 172.20.10.53 -p tcp --dport 53 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -d 172.20.10.0/24 -j MASQUERADE

strato-vm (VM Access VPN)

Property Value
Listen Port 51821
Server IP 10.0.1.1
Laptop IP 10.0.1.2
Phone IP 10.0.1.3
Subnet 10.0.1.0/24
Purpose Direct VM access from laptop/phone
Access VM only (host blocked)
Host Access ❌ INPUT DROP

PostUp rules forward traffic to VM and block host access:

# Block host access
iptables -I INPUT 1 -i strato-vm -j DROP

# Forward VPN traffic to VM
iptables -I FORWARD 1 -i strato-vm -d 192.168.10.0/24 -j ACCEPT
iptables -I FORWARD 1 -o strato-vm -s 192.168.10.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -d 192.168.10.0/24 -j MASQUERADE

openclaw-ai (AI Tunnel)

Property Value
Listen Port 51822
Server IP 10.0.3.1
Client IP 10.0.3.2
Subnet 10.0.3.0/24
Purpose Local VM → Strato VM (AI sandbox)
Access VM only (host blocked)
Host Access ❌ INPUT DROP

Client Configuration

Laptop: vpn_host.conf

[Interface]
PrivateKey = <laptop-private-key>
Address = 10.0.0.2/24
DNS = 10.0.0.1

[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
Endpoint = 217.154.228.231:51820
AllowedIPs = 10.0.0.0/24, 192.168.10.0/24, 172.20.10.0/24
PersistentKeepalive = 25

Laptop: vpn_vm.conf

[Interface]
PrivateKey = <laptop-private-key>
Address = 10.0.1.2/24

[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
Endpoint = 217.154.228.231:51821
AllowedIPs = 10.0.1.0/24, 192.168.10.0/24
PersistentKeepalive = 25

Local VM: openclaw-ai.conf

[Interface]
PrivateKey = <vm-private-key>
Address = 10.0.3.2/24

[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
Endpoint = 217.154.228.231:51822
AllowedIPs = 10.0.3.0/24, 192.168.10.0/24
PersistentKeepalive = 25

Mobile Setup via QR Code

To connect from your phone, install the WireGuard mobile app (iOS / Android), then scan the QR code below.

Strato Host — Full Admin Access

SSH, dashboards, DNS (Pi-hole), VM access. Phone IP: 10.0.0.3

WireGuard Strato Host QR Code

Open WireGuard app → + → Create from QR code → scan above.

Strato VM — VM Access Only

Forwarded to 192.168.10.10. Phone IP: 10.0.1.3

WireGuard Strato VM QR Code

Open WireGuard app → + → Create from QR code → scan above.

What You Get on Your Phone

With the strato-host config active:

Feature Works?
https://firewall.clsxx.de ✅ (VPN + BasicAuth)
https://pihole.clsxx.de ✅
https://fail2ban.clsxx.de ✅
https://docs.clsxx.de ✅
https://traefik.clsxx.de ✅
SSH to host (10.0.0.1) ✅ (with SSH app)
SSH to VM (192.168.10.10) ✅
DNS via Pi-hole ✅ (ad-blocking)

Security

These QR codes contain your private keys. This documentation page is behind VPN + BasicAuth, but do not share screenshots of these QR codes.

Regenerating QR Codes

If you need to regenerate (e.g., after key rotation):

sudo apt install qrencode  # if not installed
qrencode -t png -o wg_strato_host_phone.png -s 6 -l H < /path/to/phone_host.conf
qrencode -t png -o wg_strato_vm_phone.png -s 6 -l H < /path/to/phone_vm.conf

For a quick terminal preview:

qrencode -t ansiutf8 < /path/to/config.conf

NetworkManager Integration

WireGuard tunnels are managed by NetworkManager on the laptop. To prevent conflicts:

# /etc/NetworkManager/conf.d/99-unmanaged-wg.conf
[keyfile]
unmanaged-devices=type:wireguard

This tells NetworkManager to leave WireGuard interfaces alone when you manage them manually via wg-quick.

Connection Guide

Target VPN Required Command
Strato Host strato-host ssh admin@10.0.0.1
Strato VM (via host) strato-host ssh admin@192.168.10.10
Strato VM (direct) strato-vm ssh admin@192.168.10.10
Dashboards strato-host Browser: https://firewall.clsxx.de

UFW before.rules

WireGuard VPN interfaces must be explicitly allowed in /etc/ufw/before.rules before the conntrack INVALID drop rule. Without this, WireGuard traffic can be dropped due to invalid connection tracking state:

# In /etc/ufw/before.rules, *filter section, BEFORE the conntrack INVALID drop:
-A ufw-before-input -i strato-host -s 10.0.0.0/24 -j ACCEPT
-A ufw-before-input -i strato-vm -s 10.0.1.0/24 -j ACCEPT
-A ufw-before-input -i openclaw-ai -s 10.0.3.0/24 -j ACCEPT

Critical for VPN reliability

If these rules are missing, SSH over VPN will fail with "Connection refused" after WireGuard tunnel re-establishment because the conntrack module marks the traffic as INVALID.

Key Rotation

See Key Rotation for the procedure to rotate WireGuard keys.