WireGuard VPN Setup

WireGuard VPN setup with port forwarding and tunneling. Modern, fast, and secure VPN solution.


Installation

 1# Linux (Ubuntu/Debian)
 2sudo apt update
 3sudo apt install wireguard
 4
 5# Linux (Fedora/RHEL)
 6sudo dnf install wireguard-tools
 7
 8# macOS
 9brew install wireguard-tools
10
11# Windows
12# Download from https://www.wireguard.com/install/

Server Setup

Generate Keys

1# Generate private key
2wg genkey | sudo tee /etc/wireguard/server_private.key
3sudo chmod 600 /etc/wireguard/server_private.key
4
5# Generate public key from private key
6sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key

Server Configuration

1# Create server config
2sudo nano /etc/wireguard/wg0.conf

/etc/wireguard/wg0.conf:

 1[Interface]
 2# Server private key
 3PrivateKey = <SERVER_PRIVATE_KEY>
 4
 5# Server VPN IP
 6Address = 10.0.0.1/24
 7
 8# Listen port
 9ListenPort = 51820
10
11# Post-up commands (enable forwarding and NAT)
12PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
13PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
14PostUp = ip6tables -A FORWARD -i wg0 -j ACCEPT
15PostUp = ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
16
17# Post-down commands (cleanup)
18PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
19PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
20PostDown = ip6tables -D FORWARD -i wg0 -j ACCEPT
21PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
22
23# Client 1
24[Peer]
25PublicKey = <CLIENT1_PUBLIC_KEY>
26AllowedIPs = 10.0.0.2/32
27
28# Client 2
29[Peer]
30PublicKey = <CLIENT2_PUBLIC_KEY>
31AllowedIPs = 10.0.0.3/32

Enable IP Forwarding

1# Enable IPv4 forwarding
2echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
3echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf
4sudo sysctl -p
5
6# Verify
7sysctl net.ipv4.ip_forward

Start Server

 1# Start WireGuard
 2sudo wg-quick up wg0
 3
 4# Stop WireGuard
 5sudo wg-quick down wg0
 6
 7# Enable on boot
 8sudo systemctl enable wg-quick@wg0
 9
10# Check status
11sudo wg show

Client Setup

Generate Client Keys

1# Generate client private key
2wg genkey | tee client_private.key
3chmod 600 client_private.key
4
5# Generate client public key
6cat client_private.key | wg pubkey > client_public.key

Client Configuration

/etc/wireguard/wg0.conf:

 1[Interface]
 2# Client private key
 3PrivateKey = <CLIENT_PRIVATE_KEY>
 4
 5# Client VPN IP
 6Address = 10.0.0.2/24
 7
 8# DNS (optional)
 9DNS = 1.1.1.1, 8.8.8.8
10
11[Peer]
12# Server public key
13PublicKey = <SERVER_PUBLIC_KEY>
14
15# Server endpoint (public IP and port)
16Endpoint = server.example.com:51820
17
18# Route all traffic through VPN
19AllowedIPs = 0.0.0.0/0, ::/0
20
21# Or only route specific networks
22# AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
23
24# Keep connection alive (NAT traversal)
25PersistentKeepalive = 25

Connect Client

1# Start VPN
2sudo wg-quick up wg0
3
4# Stop VPN
5sudo wg-quick down wg0
6
7# Check status
8sudo wg show

Port Forwarding

Forward Specific Port

1# On server, forward port 8080 to client
2sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.2:8080
3sudo iptables -A FORWARD -p tcp -d 10.0.0.2 --dport 8080 -j ACCEPT
4
5# Save rules
6sudo iptables-save | sudo tee /etc/iptables/rules.v4

Forward Port Range

1# Forward ports 8000-9000
2sudo iptables -t nat -A PREROUTING -p tcp --dport 8000:9000 -j DNAT --to-destination 10.0.0.2
3sudo iptables -A FORWARD -p tcp -d 10.0.0.2 --dport 8000:9000 -j ACCEPT

Add to WireGuard Config

 1[Interface]
 2PrivateKey = <SERVER_PRIVATE_KEY>
 3Address = 10.0.0.1/24
 4ListenPort = 51820
 5
 6# Port forwarding rules
 7PostUp = iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.2:8080
 8PostUp = iptables -A FORWARD -p tcp -d 10.0.0.2 --dport 8080 -j ACCEPT
 9
10PostDown = iptables -t nat -D PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.2:8080
11PostDown = iptables -D FORWARD -p tcp -d 10.0.0.2 --dport 8080 -j ACCEPT

Site-to-Site VPN

Server A Configuration

 1[Interface]
 2PrivateKey = <SERVER_A_PRIVATE_KEY>
 3Address = 10.0.0.1/24
 4ListenPort = 51820
 5
 6PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
 7PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
 8
 9PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
10PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
11
12[Peer]
13PublicKey = <SERVER_B_PUBLIC_KEY>
14Endpoint = server-b.example.com:51820
15AllowedIPs = 10.0.0.2/32, 192.168.2.0/24  # Server B VPN IP + LAN
16PersistentKeepalive = 25

Server B Configuration

 1[Interface]
 2PrivateKey = <SERVER_B_PRIVATE_KEY>
 3Address = 10.0.0.2/24
 4ListenPort = 51820
 5
 6PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
 7PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
 8
 9PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
10PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
11
12[Peer]
13PublicKey = <SERVER_A_PUBLIC_KEY>
14Endpoint = server-a.example.com:51820
15AllowedIPs = 10.0.0.1/32, 192.168.1.0/24  # Server A VPN IP + LAN
16PersistentKeepalive = 25

Docker Setup

 1version: '3.8'
 2
 3services:
 4  wireguard:
 5    image: linuxserver/wireguard
 6    container_name: wireguard
 7    cap_add:
 8      - NET_ADMIN
 9      - SYS_MODULE
10    environment:
11      - PUID=1000
12      - PGID=1000
13      - TZ=America/New_York
14      - SERVERURL=vpn.example.com
15      - SERVERPORT=51820
16      - PEERS=3  # Number of client configs to generate
17      - PEERDNS=auto
18      - INTERNAL_SUBNET=10.13.13.0/24
19    volumes:
20      - ./config:/config
21      - /lib/modules:/lib/modules
22    ports:
23      - 51820:51820/udp
24    sysctls:
25      - net.ipv4.conf.all.src_valid_mark=1
26    restart: unless-stopped
1# Start
2docker-compose up -d
3
4# View client configs (QR codes)
5docker exec -it wireguard /app/show-peer 1

Mobile Setup

Generate QR Code

1# Install qrencode
2sudo apt install qrencode
3
4# Generate QR code for mobile
5qrencode -t ansiutf8 < /etc/wireguard/mobile.conf
6
7# Or save as image
8qrencode -o mobile.png < /etc/wireguard/mobile.conf

Mobile Client Config:

 1[Interface]
 2PrivateKey = <MOBILE_PRIVATE_KEY>
 3Address = 10.0.0.10/24
 4DNS = 1.1.1.1
 5
 6[Peer]
 7PublicKey = <SERVER_PUBLIC_KEY>
 8Endpoint = server.example.com:51820
 9AllowedIPs = 0.0.0.0/0, ::/0
10PersistentKeepalive = 25

Troubleshooting

Check Status

1# Show interface status
2sudo wg show
3
4# Show with transfer stats
5sudo wg show wg0
6
7# Show specific peer
8sudo wg show wg0 peers

Test Connectivity

 1# Ping VPN server from client
 2ping 10.0.0.1
 3
 4# Ping client from server
 5ping 10.0.0.2
 6
 7# Check routing
 8ip route show
 9
10# Check if traffic is going through VPN
11curl ifconfig.me

Debug Connection

 1# Check firewall
 2sudo ufw status
 3sudo iptables -L -n -v
 4
 5# Check if port is open
 6sudo ss -tulpn | grep 51820
 7
 8# Test UDP connectivity
 9nc -u -v server.example.com 51820
10
11# Enable debug logging
12sudo wg set wg0 private-key /etc/wireguard/server_private.key listen-port 51820

Common Issues

 1# Issue: Connection timeout
 2# Solution: Check firewall allows UDP port 51820
 3sudo ufw allow 51820/udp
 4
 5# Issue: No internet after connecting
 6# Solution: Check DNS and routing
 7# Verify AllowedIPs in config
 8
 9# Issue: Peer not connecting
10# Solution: Check keys match
11# Verify endpoint is correct
12# Check PersistentKeepalive is set
13
14# Issue: IP forwarding not working
15# Solution: Enable IP forwarding
16sudo sysctl -w net.ipv4.ip_forward=1

Security Best Practices

 1✅ Use strong keys (automatically generated)
 2✅ Limit AllowedIPs to only what's needed
 3✅ Use firewall rules to restrict access
 4✅ Rotate keys periodically
 5✅ Use different keys for each client
 6✅ Enable PersistentKeepalive for NAT traversal
 7✅ Monitor connection logs
 8✅ Use DNS over VPN
 9✅ Disable unused peers
10✅ Keep WireGuard updated

Quick Reference

 1# Server
 2wg genkey | tee private.key | wg pubkey > public.key
 3sudo wg-quick up wg0
 4sudo wg show
 5
 6# Client
 7sudo wg-quick up wg0
 8sudo wg show
 9ping 10.0.0.1
10
11# Management
12sudo systemctl enable wg-quick@wg0
13sudo systemctl start wg-quick@wg0
14sudo systemctl status wg-quick@wg0
15
16# Firewall
17sudo ufw allow 51820/udp
18sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT

Related Snippets