uction
e walks through a complete server + client setup.
Prerequisites: Ubuntu 20.04+ server with a public IP, sudo access.
Server Setup
Step 1: Install WireGuard
# Ubuntu 20.04+
sudo apt update && sudo apt install wireguard
# Verify kernel module
lsmod | grep wireguard
# wireguard 94208 0
Step 2: Generate Server Keys
# Generate key pair
wg genkey | sudo tee /etc/wireguard/server_private.key | \
erver_public.key
# Set permissions
sudo chmod 600 /etc/wireguard/server_private.key
# View the keys
sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key
Step 3: Create Server Config
sudo nano /etc/wireguard/wg0.conf
[Interface]
# Server's VPN IP address
Address = 10.0.0.1/24
# Port WireGuard listens on
ListenPort = 51820
# Server's private key
PrivateKey = <paste server_private.key here>
# Enable IP forwarding and NAT for client internet access
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -A FORWARD -o wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -o wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Client 1 (add more [Peer] sections for each client)
[Peer]
# Client's public key
PublicKey = <client1_public_key>
# IP address assigned to this client
AllowedIPs = 10.0.0.2/32
# Client 2
[Peer]
PublicKey = <client2_public_key>
AllowedIPs = 10.0.0.3/32
Step 4: Enable IP Forwarding
# Enable now
sudo sysctl -w net.ipv4.ip_forward=1
# Make permanent
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Step 5: Start WireGuard
enable on boot
sudo systemctl enable --now wg-quick@wg0
# Check status
do systemctl status wg-quick@wg0
sudo wg show wg0
Expected output:
interface: wg0
public key: <server_public_key>
private key: (hidden)
listening port: 51820
peer: <client1_public_key>
allowed ips: 10.0.0.2/32
Step 6: Open Firewall
# UFW
sudo ufw allow 51820/udp
sudo ufw allow OpenSSH # don't lock yourself out!
# iptables directly
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
Client Setup
Linux Client
# Install
sudo apt install wireguard
# Generate client keys
wg genkey | tee client_private.key | wg pubkey > client_public.key
# Create config
sudo nano /etc/wireguard/wg0.conf
[Interface]
# Client's VPN IP
Address = 10.0.0.2/24
# Client's private key
PrivateKey = <client_private_key>
# Us DNS server
DNS = 1.1.1.1
[Peer]
# Server's public key
PublicKey = <server_public_key>
# Server's address and port
Endpoint = YOUR_SERVER_IP:51820
# Route all traffic through VPN (full tunnel)
AllowedIPs = 0.0.0.0/0, ::/0
/algo)
ard automation](https://github.com/trailofbitss://github.com/wg-easy/wg-easy)
- [Algo VPN โ WireGuges/man8/wg.8.html)
- [wg-easy โ Web UI for WireGuard](http Page](https://man7.org/linux/man-pa/quickstart/)
- [WireGuard Mancode -t ansiutf8 < "${CLIENT_NAME}.conf"
Resources
- [WireGuard Quick Start](https://www.wireguard.com"Client config saved to ${CLIENT_NAME}.conf" echo "Public key: $CLIENT_PUBLIC"
Generate QR code for mobile
qrenPOINT AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25 EOF
echo _KEY Endpoint = $SERVER_ENDNS = 1.1.1.1
[Peer] PublicKey = $SERVER_PUBLIC"${CLIENT_NAME}.conf" « EOF [Interface] Address = ${CLIENT_IP}/24 PrivateKey = $CLIENT_PRIVATE D [Peer] PublicKey = $CLIENT_PUBLIC AllowedIPs = ${CLIENT_IP}/32 EOF
Generate client config
cat > et wg0 peer “$CLIENT_PUBLIC" allowed-ips "${CLIENT_IP}/32”
Append to server config
sudo tee -a /etc/wireguard/wg0.conf « EOF
$CLIENT_NAME=$(wg genkey)
CLIENT_PUBLIC=$(echo "$CLIENT_PRIVATE" | wg pubkey)
Add to server
sudo wg svpn.example.com:51820" CLIENT_NAME=$1 CLIENT_IP=$2 # e.g., 10.0.0.5
Generate keys
CLIENT_PRIVATEent.sh โ generate config for a new client
SERVER_PUBLIC_KEY=$(sudo cat /etc/wireguard/server_public.key) SERVER_ENDPOINT="
Automating Client Config Generation
#!/bin/bash
# generate-clirewall, check AllowedIPs, check IP forwarding
terface: No such device" โ module not loaded: sudo modprobe wireguard
No traffic flowing โ check fissues:
“RTNETLINK answers: Operation not permitted” โ need sudo
“Unable to access intl -u wg-quick@wg0 -f
Common i10.0.0.1 # ping server from client
traceroute 8.8.8.8 # verify traffic goes through VPN
Check logs
sudo journalcable main | grep wg0
Test connectivity
ping time stats watch -n 1 ‘sudo wg show’
Check routing table
ip route show teceived, 456 MiB sent
Watch real-wg0
Check if traffic is flowing
sudo wg show wg0 transfer
peer:
transfer: 1.23 GiB rhow specific interface
sudo wg show ```
Monitoring and Troubleshooting
# Show all peers and their status
sudo wg show
# Soint = office.example.com:51820
AllowedIPs = 10.0.0.1/32, 192.168.1.0/24 # office VPN IP + office subnet
PersistentKeepalive = 25
# Office server
PublicKey = <office_public_key>
Endp[Interface]
Address = 10.0.0.2/24
ListenPort = 51820
PrivateKey = <cloud_private_key>
[Peer]2.16.0.0/24 # cloud VPN IP + cloud subnet
PersistentKeepalive = 25
# Cloud server (172.16.0.0/24)
office_private_key>
[Peer]
# Cloud server
PublicKey = <cloud_public_key>
Endpoint = cloud.example.com:51820
AllowedIPs = 10.0.0.2/32, 17rver (192.168.1.0/24)
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <
## Site-to-Site Configuration
Connect two networks (e.g., office + cloud):
```ini
# Office seS only for internal domains
DNS = 10.0.0.1
# Some clients support: DNS = 10.0.0.1, 1.1.1.1
ent config โ use VPN DNdomain=vpn.internal
### Split DNS (different DNS for VPN vs internet)
```ini
# Cli on the VPN
# On server: install and configure dnsmasq
sudo apt install dnsmasq
# /etc/dnsmasq.conf
listen-address=10.0.0.1
bind-interfaces
ace]
DNS = 10.0.0.1 # point to your DNS server
```ini
# Client config
[Interfwg set wg0 peer <client_public_key> remove
# Also remove from config file
DNS Configuration
Use Pi-hole or Custom DNS10/32
### Remove a Peer
```bash
# Remove from running server
sudo guard/wg0.conf
# Add:
# [Peer]
# PublicKey = <new_client_public_key>
# AllowedIPs = 10.0.0.w_client_public.key) allowed-ips 10.0.0.10/32
# Also add to config file for persistence
sudo nano /etc/wireey
# Add peer to running server (no restart needed)
sudo wg set wg0 peer $(cat nePN.
## Adding and Removing Peers
### Add a New Client (Without Restarting)
```bash
# Generate keys for new client
wg genkey | tee new_client_private.key | wg pubkey > new_client_public.kormance โ only corporate traffic goes through Vom/blog/2021/03/wireguard-allowedips-calculator/
Split tunneling is better for perfhing EXCEPT specific IPs
Use a split tunnel calculator: https://www.procustodibus.cy route corporate network through VPN
AllowedIPs = 10.0.0.0/8, 192.168.1.0/24
Route everytthrough VPN)
# In [Peer] section:
AllowedIPs = 0.0.0.0/0, ::/0
All internet traffic goes through the VPN server. Use for: public WiFi protection, bypassing geo-restrictions.
Split Tunnel (only route specific networks)
# Onlsiutf8 < /etc/wireguard/client.conf
Split Tunneling vs Full Tunnel
Full Tunnel (route all traffic “+” โ “Create from QR code” or “Create from file”
- Generate QR code from config:
# Generate QR code for mobile import
sudo apt install qrencode
qrencode -t anGuard"
iOS / Android
- Install WireGuard from App Store / Play Store
- Tapient
# Homebrew
brew install wireguard-tools
# Or download the App Store app: "Wiree client config (same format as Linux)
4. Click "Activate"
### macOS Clwww.wireguard.com/install/)
2. Click "Add Tunnel" โ "Add empty tunnel"
3. Paste thnnect on boot
sudo systemctl enable wg-quick@wg0
Windows Client
- Download from [wireguard.com/install](https://.me # should show server’s IP
Disconnect
sudo wg-quick down wg0
Auto-co
PersistentKeepalive = 25
```bash
# Connect
sudo wg-quick up wg0
# Verify connection
ping 10.0.0.1 # ping server
curl ifconfig# Keep NAT mapping alive
Comments