WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec and OpenVPN.
Installation
# Debian / Ubuntu
sudo apt install wireguard
# RHEL / CentOS / Fedora
sudo dnf install wireguard-tools
# Arch Linux
sudo pacman -S wireguard-tools
# macOS
brew install wireguard-toolsPrerequisites
Enable IP forwarding on the server (required for routing client traffic):
# Enable temporarily
sudo sysctl -w net.ipv4.ip_forward=1
# Enable permanently (add to /etc/sysctl.conf or /etc/sysctl.d/)
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --systemKey Generation
WireGuard requires a private/public key pair for every peer (server and each client).
# Generate a private key
wg genkey > privatekey
# Generate the corresponding public key from the private key
wg pubkey < privatekey > publickey
# Generate both in a single line
wg genkey | tee privatekey | wg pubkey > publickey
# Generate a preshared key (optional — adds extra layer of symmetric encryption)
wg genpsk > presharedkeyServer Configuration (/etc/wireguard/wg0.conf)
[Interface]
Address = 10.0.0.1/24 # VPN IP for this server
ListenPort = 51820 # UDP port WireGuard listens on
PrivateKey = <Server-Private-Key>
SaveConfig = true # Auto-save runtime changes to this file
# NAT rules: forward VPN traffic to the internet via eth0
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>
AllowedIPs = 10.0.0.2/32 # IP assigned to this clientClient Configuration (/etc/wireguard/wg0.conf)
[Interface]
Address = 10.0.0.2/24 # VPN IP for this client
PrivateKey = <Client-Private-Key>
DNS = 1.1.1.1, 8.8.8.8 # DNS servers to use while connected
[Peer]
PublicKey = <Server-Public-Key>
Endpoint = 203.0.113.1:51820 # Server's public IP and port
AllowedIPs = 0.0.0.0/0 # Route ALL traffic through VPN (full tunnel)
# AllowedIPs = 10.0.0.0/24 # Route only VPN subnet traffic (split tunnel)
PersistentKeepalive = 25 # Send keepalive every 25s (helps with NAT)Interface Management
# Start the WireGuard interface
sudo wg-quick up wg0
# Stop the WireGuard interface
sudo wg-quick down wg0
# Enable the interface to start automatically on boot
sudo systemctl enable --now wg-quick@wg0Status and Monitoring
# Show status of all active WireGuard interfaces
sudo wg
# Show detailed status of a specific interface
sudo wg show wg0
# Show only the public key of a specific interface
sudo wg show wg0 public-keyAdding and Removing Peers at Runtime
# Add a new peer to the running interface
sudo wg set wg0 peer <Client-Public-Key> allowed-ips 10.0.0.3/32
# Remove a peer from the running interface
sudo wg set wg0 peer <Client-Public-Key> removeTroubleshooting
# Check if the WireGuard kernel module is loaded
sudo modprobe wireguard
lsmod | grep wireguard
# Check if the UDP port is open
sudo ss -ulnp | grep 51820
# Test connectivity from client
ping 10.0.0.1 # Ping VPN gateway