Overview
WireGuard is a modern VPN protocol that provides faster, simpler, and more secure connectivity than traditional solutions like OpenVPN or IPsec. This guide covers complete server and client configuration.
Who Should Use This Guide
- Network administrators deploying remote access VPN
- Security teams implementing secure site connectivity
- Home lab enthusiasts setting up private networks
Why WireGuard
| Feature | WireGuard | OpenVPN |
|---|---|---|
| Performance | Significantly faster | Moderate |
| Codebase | ~4,000 lines | ~100,000 lines |
| Cryptography | Modern (ChaCha20, Curve25519) | Configurable (varies) |
| Configuration | Simple INI format | Complex |
| Platforms | All major OS | All major OS |
Requirements
Server Requirements
| Component | Requirement |
|---|---|
| Operating System | Linux (Ubuntu 22.04+, Debian 12+, RHEL 8+) |
| Network | Public IP address or port forwarding |
| Privileges | Root/sudo access |
| Firewall | UDP port access (default 51820) |
Client Requirements
| Platform | Application |
|---|---|
| Linux | wireguard-tools package |
| Windows | WireGuard for Windows |
| macOS | WireGuard from App Store |
| iOS/Android | WireGuard mobile app |
Architecture
Internet
│
▼
┌─────────────────┐
│ WireGuard │
│ Server │
│ 10.200.200.1 │
└────────┬────────┘
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│Client │ │Client │ │Client │
│ .2 │ │ .3 │ │ .4 │
└───────┘ └───────┘ └───────┘Process
Step 1: Install WireGuard Server
Ubuntu/Debian:
sudo apt update && sudo apt upgrade -y
sudo apt install wireguard wireguard-tools -yRHEL/Rocky/Alma:
sudo dnf install epel-release -y
sudo dnf install wireguard-tools -yVerification:
wg --versionExpected Output: wireguard-tools v1.x.x
Step 2: Generate Server Keys
Create key pair for the server.
# Create configuration directory
sudo mkdir -p /etc/wireguard
cd /etc/wireguard
# Generate private key
wg genkey | sudo tee server_private.key
sudo chmod 600 server_private.key
# Generate public key from private key
sudo cat server_private.key | wg pubkey | sudo tee server_public.keyVerification:
# Display public key (needed for client configuration)
cat /etc/wireguard/server_public.keyExpected Output: Base64-encoded public key string.
Important: Save the public key - clients will need it.
Step 3: Configure Server
Create the WireGuard interface configuration.
Create /etc/wireguard/wg0.conf:
[Interface]
# Server private key (from Step 2)
PrivateKey = <server-private-key>
# VPN subnet - use private range
Address = 10.200.200.1/24
# Listen port (default 51820)
ListenPort = 51820
# Enable IP forwarding and NAT on startup
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Clean up on shutdown
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Peer configurations added belowSet Permissions:
sudo chmod 600 /etc/wireguard/wg0.confNote: Replace
eth0with your server's primary network interface name.
Step 4: Enable IP Forwarding
Make IP forwarding persistent across reboots.
# Add to sysctl configuration
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
# Apply immediately
sudo sysctl -pVerification:
cat /proc/sys/net/ipv4/ip_forwardExpected Output: 1
Step 5: Configure Firewall
Allow WireGuard traffic through firewall.
UFW:
sudo ufw allow 51820/udp
sudo ufw reloadfirewalld:
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --reloadiptables:
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4Step 6: Generate Client Keys
Create key pair for each client device.
# Generate client keys
wg genkey | tee client1_private.key | wg pubkey > client1_public.key
# Generate preshared key for additional security (recommended)
wg genpsk > client1_preshared.keyVerification:
cat client1_public.key
cat client1_preshared.keyStep 7: Add Client to Server Configuration
Add peer section to server's /etc/wireguard/wg0.conf:
# Client 1
[Peer]
PublicKey = <client1-public-key>
PresharedKey = <client1-preshared-key>
AllowedIPs = 10.200.200.2/32Note: Each client needs a unique IP address in AllowedIPs.
Step 8: Create Client Configuration
Linux Client - /etc/wireguard/wg0.conf:
[Interface]
PrivateKey = <client1-private-key>
Address = 10.200.200.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = <server-public-key>
PresharedKey = <client1-preshared-key>
Endpoint = <server-public-ip>:51820
AllowedIPs = 0.0.0.0/0 # Route all traffic through VPN
PersistentKeepalive = 25Split Tunnel (route only VPN traffic):
# Replace AllowedIPs with specific networks
AllowedIPs = 10.200.200.0/24, 192.168.1.0/24Generate QR Code for Mobile:
sudo apt install qrencode -y
qrencode -t ansiutf8 < client1.confStep 9: Start WireGuard Service
Start Server:
# Start interface
sudo wg-quick up wg0
# Enable on boot
sudo systemctl enable wg-quick@wg0Start Client:
sudo wg-quick up wg0Verification:
sudo wg showExpected Output:
interface: wg0
public key: <server-public-key>
private key: (hidden)
listening port: 51820
peer: <client-public-key>
preshared key: (hidden)
endpoint: <client-ip>:<port>
allowed ips: 10.200.200.2/32
latest handshake: X seconds ago
transfer: X KiB received, X KiB sent
Step 10: Verify Client Connection
On Client:
# Test VPN connectivity
ping 10.200.200.1
# Verify external IP (should show server IP if routing all traffic)
curl ifconfig.meExpected Result: Ping succeeds; external IP matches server IP.
Security Hardening
Use Non-Standard Port
# In server wg0.conf
ListenPort = 41194Enable Kill Switch (Client)
Prevent traffic leaks if VPN disconnects:
[Interface]
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECTRegular Key Rotation
Rotate keys periodically (quarterly recommended):
# Generate new keys
wg genkey | tee new_private.key | wg pubkey > new_public.key
# Update both server and client configurations
# Coordinate timing to avoid connectivity gapsTroubleshooting
| Symptom | Possible Cause | Solution |
|---|---|---|
| Handshake not completing | Firewall blocking UDP | Verify port 51820/udp is open |
| No internet after connecting | IP forwarding disabled | Check cat /proc/sys/net/ipv4/ip_forward returns 1 |
| Client can't reach server | Wrong endpoint IP/port | Verify server public IP and port in client config |
| Connection drops behind NAT | No keepalive | Add PersistentKeepalive = 25 to client config |
| DNS not resolving | DNS not configured | Add DNS = 1.1.1.1 to client Interface section |
Diagnostic Commands
# Check interface status
ip link show wg0
# View WireGuard logs
sudo journalctl -u wg-quick@wg0
# Test UDP connectivity to server
nc -vzu <server-ip> 51820
# Check NAT rules
sudo iptables -t nat -L POSTROUTINGVerification Checklist
- Server keys generated with proper permissions (600)
- Configuration files secured (chmod 600)
- IP forwarding enabled and persistent
- Firewall allows UDP traffic on WireGuard port
- Preshared keys used for all peers
- Client connection verified with ping test
- External IP routing verified (if full tunnel)
- Kill switch enabled on clients (optional)
Multiple Clients Template
Complete server configuration with multiple peers:
[Interface]
PrivateKey = <server-private-key>
Address = 10.200.200.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Laptop
[Peer]
PublicKey = <laptop-public-key>
PresharedKey = <laptop-psk>
AllowedIPs = 10.200.200.2/32
# Phone
[Peer]
PublicKey = <phone-public-key>
PresharedKey = <phone-psk>
AllowedIPs = 10.200.200.3/32
# Tablet
[Peer]
PublicKey = <tablet-public-key>
PresharedKey = <tablet-psk>
AllowedIPs = 10.200.200.4/32References
Last Updated: January 2026