VPN
Overview & Architecture
This document describes the modern, high-performance WireGuard VPN service running on the internal infrastructure server ul (10.0.0.3) with full IPv4 and IPv6 dual-stack pass-through from the edge router danknasty (OpenBSD pf).
Network Topology
+-----------------------------------------------------------------------------------------+
| Internet / WAN |
+-----------------------------------------------------------------------------------------+
│ │
IPv4 UDP Port 51820 IPv6 UDP Port 51820
│ │
▼ ▼
+-----------------------------------------------------------------------------------------+
| danknasty (OpenBSD Router & Gateway) |
| WAN IPv4: 71.25.179.69 |
| WAN IPv6: 2603:3001:626:9d80::/64 |
| LAN: 10.0.0.1 / fd77:7777:5010::1 |
| |
| PF Inbound Rules: |
| pass in quick on $ext inet proto udp from any to any port 51820 rdr-to 10.0.0.3 |
| pass in quick on $ext inet6 proto udp from any to $ul_gu port 51820 |
| rdr-to $ul_ula port 51820 |
| |
| Static Route for VPN IPv6 Subnet: |
| route add -inet6 fd77:7777:5010:7700::/64 fd77:7777:5010:0:1337:f1ac:d00d:337 |
+-----------------------------------------------------------------------------------------+
│ │
└───────────────────┬───────────────────┘
│
▼
+-----------------------------------------------------------------------------------------+
| ul.drheck.dev (VPN Server) |
| IPv4: 10.0.0.3 | IPv6: fd77:7777:5010:0:1337:f1ac:d00d:337 |
| WireGuard Interface: wg0 |
| IPv4 Address: 10.77.0.1/24 | IPv6 Address: fd77:7777:5010:7700::1/64 |
| |
| - Full Dual-Stack In-Kernel WireGuard Tunneling (ChaCha20-Poly1305, Curve25519) |
| - Dual-Stack IPv4 & IPv6 Forwarding & MASQUERADE NAT for outgoing client traffic |
+-----------------------------------------------------------------------------------------+
│ │
┌───────────────┴───────────────┐ ┌───────────────┴───────────────┐
▼ ▼ ▼ ▼
10.0.0.0/24 LAN Hosts WAN IPv4 via danknasty fd77:7777:5010::/64 ULA WAN IPv6 via danknasty
Server Configuration
Parameters & Endpoints
| Setting | Value |
|---|---|
| Server Host | ul.drheck.dev (10.0.0.3) |
| Edge Router | danknasty.drheck.dev (10.0.0.1) |
| Public IPv4 Endpoint | 71.25.179.69:51820 |
| Public IPv6 Endpoint | [2603:3001:626:9d80:1337:f1ac:d00d:337]:51820 |
| FQDN Endpoint | vpn.drheck.dev:51820 (or ul.drheck.dev:51820) |
| Protocol & Port | UDP 51820 (IPv4 and IPv6) |
| VPN IPv4 Subnet | 10.77.0.0/24 (Server: 10.77.0.1) |
| VPN IPv6 Subnet | fd77:7777:5010:7700::/64 (Server: fd77:7777:5010:7700::1) |
| DNS Resolvers | 10.0.0.1, fd77:7777:5010::1 (Unbound on danknasty) |
| Server Public Key | ubh+z69hcWcUKgHl3LVfm54sYkDZAaocIKNN5zlsZWA= |
Router (danknasty) PF & Route Configuration
Tracked in /home/luke/git/router_config/pf.conf:
# Ports
wireguard = "51820"
# IPv4 Inbound
pass in quick on $ext inet proto udp from any to any port $wireguard rdr-to $ul_ipv4
# IPv6 Inbound
pass in quick on $ext inet6 proto udp from any to $ul_gu port $wireguard rdr-to $ul_ula port $wireguard
IPv6 routing in /home/luke/git/router_config/hostname.em1:
!route add -inet6 fd77:7777:5010:7700::/64 fd77:7777:5010:0:1337:f1ac:d00d:337
DNS Access Control in /home/luke/git/router_config/unbound.conf:
access-control: 10.77.0.0/24 allow
access-control: fd77:7777:5010:7700::/64 allow
Server (ul) Interface Configuration: /etc/wireguard/wg0.conf
[Interface]
Address = 10.77.0.1/24, fd77:7777:5010:7700::1/64
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
# Dual-stack packet forwarding and NAT masquerade
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -o eth77 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -A FORWARD -o wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -s fd77:7777:5010:7700::/64 -o eth77 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.77.0.0/24 -o eth77 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -D FORWARD -o wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -s fd77:7777:5010:7700::/64 -o eth77 -j MASQUERADE
# Peer entry template
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
PresharedKey = <PRESHARED_KEY>
AllowedIPs = 10.77.0.X/32, fd77:7777:5010:7700::X/128
Client Management Utilities
Management scripts are installed in /home/luke/bin/ on ul:
1. Adding Clients (wg-addclient)
# Syntax: wg-addclient <device-name> [optional_ip_octet]
# IP is automatically assigned to the next available address if omitted:
wg-addclient macbook
wg-addclient iphone
# Or manually specify an IP octet if preferred:
wg-addclient custom-device 10
This utility:
- Automatically allocates the next free IPv4 & IPv6 addresses.
- Generates private/public keypairs + Pre-shared Key (PSK).
- Creates the client configuration in
/etc/wireguard/clients/<name>.conf. - Injects the peer into
/etc/wireguard/wg0.confand live kernel interface dynamically. - Renders an ASCII QR code in the terminal for instant mobile setup.
2. Listing Active Clients (wg-listclients)
wg-listclients
Prints all configured clients, their assigned IP addresses, and their WireGuard public keys.
3. Revoking / Removing Clients (wg-delclient)
# Syntax: wg-delclient <device-name>
wg-delclient macbook
This utility:
- Instantly drops the peer from the live in-kernel WireGuard routing table (
sudo wg set wg0 peer <pubkey> remove), severing all active sessions. - Removes the
[Peer]block from/etc/wireguard/wg0.conf. - Deletes the stored configuration file
/etc/wireguard/clients/<name>.conf.
To display a QR code for mobile devices:
sudo qrencode -t ansiutf8 < /etc/wireguard/clients/<name>.conf
Client Setup Instructions (All Platforms)
1. Apple macOS & iOS
Setup via Mobile / QR Code (iOS)
- Install WireGuard from the App Store.
- Open the app, tap + -> Create from QR code.
- On
ul, runsudo qrencode -t ansiutf8 < /etc/wireguard/clients/<client-name>.confand scan the terminal screen. - Name the tunnel
drheckand toggle to connect.
Setup via Desktop App (macOS)
- Install WireGuard from the Mac App Store.
- Copy the
.conffile from/etc/wireguard/clients/<name>.confto your Mac. - Open WireGuard, click Import tunnel(s) from file, and select the
.conffile. - Click Activate.
2. Linux (systemd-networkd / NetworkManager / wg-quick)
Method A: wg-quick
- Install
wireguard-tools:- Arch Linux:
sudo pacman -S wireguard-tools - Debian/Ubuntu:
sudo apt install wireguard-tools - Fedora:
sudo dnf install wireguard-tools
- Arch Linux:
- Save your configuration as
/etc/wireguard/drheck.conf:[Interface] PrivateKey = <CLIENT_PRIVATE_KEY> Address = 10.77.0.X/24, fd77:7777:5010:7700::X/64 DNS = 10.0.0.1, fd77:7777:5010::1 [Peer] PublicKey = ubh+z69hcWcUKgHl3LVfm54sYkDZAaocIKNN5zlsZWA= PresharedKey = <PRESHARED_KEY> Endpoint = 71.25.179.69:51820 AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25 - Bring the tunnel up:
sudo wg-quick up drheck # To enable on boot: sudo systemctl enable --now wg-quick@drheck
Method B: NetworkManager
sudo nmcli connection import type wireguard file /path/to/<name>.conf
sudo nmcli connection up <name>
3. Android
- Install WireGuard from Google Play Store or F-Droid.
- Tap the floating + button in the bottom-right corner.
- Select Scan from QR code and scan the output of:
sudo qrencode -t ansiutf8 < /etc/wireguard/clients/<name>.conf - Enter tunnel name
drheckand tap to activate.
4. Microsoft Windows
- Download and run the official installer from wireguard.com/install.
- Click Add Tunnel (or press
Ctrl+O) and open<name>.conf. - Click Activate.
5. OpenBSD / FreeBSD
OpenBSD (hostname.wg0)
Create /etc/hostname.wg0:
inet 10.77.0.X 255.255.255.0 NONE
inet6 fd77:7777:5010:7700::X 64
wgkey <CLIENT_PRIVATE_KEY>
wgpeer ubh+z69hcWcUKgHl3LVfm54sYkDZAaocIKNN5zlsZWA= \
wgpresharedkey <PRESHARED_KEY> \
wgendpoint 71.25.179.69 51820 \
wgaip 0.0.0.0/0 wgaip ::/0
up
Run sh /etc/netstart wg0.
Split Tunneling vs Full Tunneling
By default, the client configuration routes all traffic (AllowedIPs = 0.0.0.0/0, ::/0) through the home network connection.
If you only want access to the internal drheck.dev LAN resources and DNS without tunneling general internet browsing, adjust AllowedIPs in the client's [Peer] section:
# Split Tunnel (Internal LAN & VPN Subnet Only)
AllowedIPs = 10.0.0.0/24, 10.77.0.0/24, fd77:7777:5010::/48
Backup & Disaster Recovery
WireGuard configuration, keys, and client management scripts are fully integrated into the host backup architecture under ~/git/backups/ul/scripts/:
Automated Backup (scripts/backup/wireguard)
- Archive Path:
/data/backups/services/current/wireguard/<TIMESTAMP>/wireguard_config.tar.xz - Included Paths:
/etc/wireguard/(Server configwg0.confand all client profiles inclients/)/etc/modules-load.d/wireguard.conf/home/luke/bin/wg-addclient,/home/luke/bin/wg-delclient,/home/luke/bin/wg-listclients
- Parity Redundancy: 10% PAR2 recovery volume generation (
par2create -r10). - Cloud Replication: Automatically bundled by
stage_cloud_archiveinto GPG-encrypted cloud staging for off-site sync.
Disaster Recovery (scripts/restore/wireguard)
To restore the complete WireGuard service from the latest backup:
sudo /home/luke/git/backups/ul/scripts/restore/wireguard
This verifies PAR2 parity, unpacks files with intact permissions (0700/0600), ensures the kernel module is loaded, and enables/starts wg-quick@wg0.