wireguard
WireGuard VPN Configuration
Complete guide for WireGuard - modern, fast, and secure VPN.
Quick Reference
Key Commands
| Command | Purpose |
|---|---|
wg genkey |
Generate private key |
wg pubkey |
Derive public key |
wg show |
Show current config |
wg-quick up wg0 |
Start interface |
wg-quick down wg0 |
Stop interface |
Config Locations
Linux: /etc/wireguard/wg0.conf
macOS: /usr/local/etc/wireguard/wg0.conf
Windows: C:\Program Files\WireGuard\Data\Configurations\
Installation
Linux
# Ubuntu/Debian
sudo apt update
sudo apt install wireguard
# Fedora
sudo dnf install wireguard-tools
# Arch
sudo pacman -S wireguard-tools
macOS
brew install wireguard-tools
Docker
services:
wireguard:
image: linuxserver/wireguard
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- SERVERURL=vpn.example.com
- SERVERPORT=51820
- PEERS=5
volumes:
- ./config:/config
- /lib/modules:/lib/modules
ports:
- 51820:51820/udp
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped
Key Generation
Generate Key Pair
# Generate private key
wg genkey | tee privatekey | wg pubkey > publickey
# Or step by step
wg genkey > privatekey
cat privatekey | wg pubkey > publickey
# Generate preshared key (optional, for extra security)
wg genpsk > presharedkey
Secure Key Permissions
chmod 600 privatekey
chmod 644 publickey
Server Configuration
Basic Server Config
# /etc/wireguard/wg0.conf
[Interface]
# Server private key
PrivateKey = SERVER_PRIVATE_KEY
# Server VPN IP address
Address = 10.0.0.1/24
# Listening port
ListenPort = 51820
# DNS for clients (optional)
DNS = 1.1.1.1, 8.8.8.8
# Enable IP forwarding
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# Client 1
PublicKey = CLIENT1_PUBLIC_KEY
# Client allowed IPs
AllowedIPs = 10.0.0.2/32
# Optional preshared key
PresharedKey = PRESHARED_KEY
[Peer]
# Client 2
PublicKey = CLIENT2_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32
Enable IP Forwarding
# Enable temporarily
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Enable permanently
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Client Configuration
Basic Client Config
# /etc/wireguard/wg0.conf
[Interface]
# Client private key
PrivateKey = CLIENT_PRIVATE_KEY
# Client VPN IP address
Address = 10.0.0.2/24
# DNS servers
DNS = 1.1.1.1, 8.8.8.8
[Peer]
# Server public key
PublicKey = SERVER_PUBLIC_KEY
# Optional preshared key
PresharedKey = PRESHARED_KEY
# Server endpoint
Endpoint = vpn.example.com:51820
# Route all traffic through VPN
AllowedIPs = 0.0.0.0/0, ::/0
# Keep connection alive
PersistentKeepalive = 25
Split Tunnel (Specific Routes)
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
# Only route specific subnets through VPN
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25
Interface Management
Start and Stop
# Start interface
sudo wg-quick up wg0
# Stop interface
sudo wg-quick down wg0
# Restart
sudo wg-quick down wg0 && sudo wg-quick up wg0
Enable at Boot
# Enable service
sudo systemctl enable wg-quick@wg0
# Start service
sudo systemctl start wg-quick@wg0
# Check status
sudo systemctl status wg-quick@wg0
Show Status
# Show all interfaces
sudo wg show
# Show specific interface
sudo wg show wg0
# Show with real-time stats
watch -n 1 sudo wg show
Adding Peers
Add Peer Dynamically
# Add peer without restarting
sudo wg set wg0 peer CLIENT_PUBLIC_KEY allowed-ips 10.0.0.4/32
# With preshared key
sudo wg set wg0 peer CLIENT_PUBLIC_KEY \
preshared-key /path/to/presharedkey \
allowed-ips 10.0.0.4/32
Remove Peer
sudo wg set wg0 peer CLIENT_PUBLIC_KEY remove
Save Running Config
# Save current config to file
sudo wg-quick save wg0
Site-to-Site VPN
Site A Configuration
# /etc/wireguard/wg0.conf on Site A
[Interface]
PrivateKey = SITE_A_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT
[Peer]
# Site B
PublicKey = SITE_B_PUBLIC_KEY
Endpoint = site-b.example.com:51820
# Site B's VPN IP and LAN subnet
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
PersistentKeepalive = 25
Site B Configuration
# /etc/wireguard/wg0.conf on Site B
[Interface]
PrivateKey = SITE_B_PRIVATE_KEY
Address = 10.0.0.2/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT
[Peer]
# Site A
PublicKey = SITE_A_PUBLIC_KEY
Endpoint = site-a.example.com:51820
# Site A's VPN IP and LAN subnet
AllowedIPs = 10.0.0.1/32, 192.168.1.0/24
PersistentKeepalive = 25
Firewall Configuration
UFW
# Allow WireGuard port
sudo ufw allow 51820/udp
# Allow forwarding
sudo ufw route allow in on wg0 out on eth0
iptables
# Allow WireGuard traffic
iptables -A INPUT -p udp --dport 51820 -j ACCEPT
# Allow forwarding
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT
# NAT for internet access
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
firewalld
# Add WireGuard port
firewall-cmd --permanent --add-port=51820/udp
# Enable masquerade
firewall-cmd --permanent --add-masquerade
# Reload
firewall-cmd --reload
QR Code Generation
Generate QR for Mobile
# Install qrencode
sudo apt install qrencode
# Generate QR code
qrencode -t ansiutf8 < client.conf
# Save as image
qrencode -o client-qr.png < client.conf
Troubleshooting
Debug Mode
# Enable debug logging
echo 'module wireguard +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
# View logs
sudo dmesg | grep wireguard
sudo journalctl -u wg-quick@wg0
Common Issues
No connection:
# Check interface is up
ip link show wg0
# Check endpoint reachability
ping vpn.example.com
# Verify port is open
nc -zvu vpn.example.com 51820
Handshake not completing:
# Check keys match
# Client's public key should match server's Peer PublicKey
# Server's public key should match client's Peer PublicKey
# Check firewall
sudo iptables -L -n | grep 51820
No internet through VPN:
# Check IP forwarding
sysctl net.ipv4.ip_forward
# Check NAT rules
sudo iptables -t nat -L -n
# Check DNS resolution
nslookup google.com
Verify Configuration
# Test config syntax
sudo wg-quick strip wg0
# Check current config
sudo wg showconf wg0
Automation Scripts
Add New Peer Script
#!/bin/bash
# add-peer.sh
CLIENT_NAME=$1
SERVER_PUBLIC_KEY="YOUR_SERVER_PUBLIC_KEY"
SERVER_ENDPOINT="vpn.example.com:51820"
# Generate keys
CLIENT_PRIVATE_KEY=$(wg genkey)
CLIENT_PUBLIC_KEY=$(echo "$CLIENT_PRIVATE_KEY" | wg pubkey)
# Find next available IP
NEXT_IP=10.0.0.$(( $(sudo wg show wg0 | grep -c 'peer:') + 2 ))
# Add to server
sudo wg set wg0 peer "$CLIENT_PUBLIC_KEY" allowed-ips "$NEXT_IP/32"
# Generate client config
cat > "${CLIENT_NAME}.conf" << EOF
[Interface]
PrivateKey = $CLIENT_PRIVATE_KEY
Address = $NEXT_IP/24
DNS = 1.1.1.1
[Peer]
PublicKey = $SERVER_PUBLIC_KEY
Endpoint = $SERVER_ENDPOINT
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
echo "Client config saved to ${CLIENT_NAME}.conf"
qrencode -t ansiutf8 < "${CLIENT_NAME}.conf"
Best Practices
- Secure keys - Never share private keys
- Use preshared keys - Additional security layer
- Rotate keys - Change keys periodically
- Limit AllowedIPs - Only allow needed ranges
- Enable keepalive - For NAT traversal
- Firewall rules - Restrict access appropriately
- Monitor connections - Watch for anomalies
- Backup configs - Keep secure backups
- Document peers - Track who has access
- Update regularly - Keep WireGuard updated
When to Use This Skill
- Setting up VPN servers
- Configuring client connections
- Creating site-to-site tunnels
- Troubleshooting VPN issues
- Automating peer management
- Securing network communications
More from housegarofalo/claude-code-base
mqtt-iot
Configure MQTT brokers (Mosquitto, EMQX) for IoT messaging, device communication, and smart home integration. Manage topics, QoS levels, authentication, and bridging. Use when setting up IoT messaging, smart home communication, or device-to-cloud connectivity. (project)
22devops-engineer-agent
Infrastructure and DevOps specialist. Manages Docker, Kubernetes, CI/CD pipelines, and cloud deployments. Expert in GitHub Actions, Azure DevOps, Terraform, and container orchestration. Use for deployment automation, infrastructure setup, or CI/CD optimization.
6react-typescript
Build modern React applications with TypeScript. Covers React 18+ patterns, hooks, component architecture, state management (Zustand, Redux Toolkit), server components, and best practices. Use for React development, TypeScript integration, component design, and frontend architecture.
5svelte-kit
Expert guidance for SvelteKit 2 with Svelte 5 runes, server-side rendering, and modern patterns. Covers $state, $derived, $effect, form actions, load functions, and API routes. Use for SvelteKit applications, Svelte 5 runes, and full-stack Svelte development.
5matter-thread
>
5vitest
Fast Vite-native unit testing framework for JavaScript/TypeScript. ESM-first, Jest-compatible API, with instant HMR. Use for modern frontend testing, Vue/React/Svelte testing, or fast test execution. Triggers on vitest, vite test, vue test, svelte test.
5