WireGuard VPN on VPS
WireGuard is a modern, fast, and simple-to-configure VPN. Ideal for protecting your browsing, securely accessing your server, or creating a private network between multiple servers.
02
Installation
bash
# Ubuntu 20.04+
sudo apt update && sudo apt install wireguard -y
# CentOS/AlmaLinux
sudo dnf install wireguard-tools -y
03
VPN Server Configuration
1. Generate Keys
bash
# Generate server private and public key
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
sudo chmod 600 /etc/wireguard/server_private.key
# Display the keys (you'll need them later)
echo "Private: $(sudo cat /etc/wireguard/server_private.key)"
echo "Public: $(sudo cat /etc/wireguard/server_public.key)"
2. Create Server Configuration
bash
sudo nano /etc/wireguard/wg0.conf
ini
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
# Enable NAT (forward packets to internet)
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
# Replace eth0 with your network interface (ip a to see it)
3. Enable IP Forwarding
bash
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
4. Start WireGuard
bash
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
# Verify
sudo wg show
5. Open the Port in the Firewall
bash
sudo ufw allow 51820/udp
04
Adding a Client (Peer)
On Client: Generate Keys
bash
# Linux/Mac
wg genkey | tee client_private.key | wg pubkey > client_public.key
cat client_private.key
cat client_public.key
# Windows: download WireGuard from wireguard.com, use "Add Tunnel" > "Create from scratch"
On Server: Add the Peer
bash
sudo nano /etc/wireguard/wg0.conf
Add at the end:
ini
[Peer]
# Client 1 (e.g., your PC)
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32
bash
# Reload the configuration without interrupting connections
sudo wg syncconf wg0 <(sudo wg-quick strip wg0)
# or
sudo systemctl restart wg-quick@wg0
On Client: Create Configuration
ini
[Interface]
Address = 10.0.0.2/24
PrivateKey = <CLIENT_PRIVATE_KEY>
DNS = 1.1.1.1
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = <VPS_IP>:51820
AllowedIPs = 0.0.0.0/0 # all traffic through VPN
# Or only traffic to the private network:
# AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25
05
Adding Multiple Clients
Each client has a different IP in the VPN subnet:
ini
# Client 2 (phone)
[Peer]
PublicKey = <PHONE_PUBLIC_KEY>
AllowedIPs = 10.0.0.3/32
# Client 3 (work laptop)
[Peer]
PublicKey = <LAPTOP_PUBLIC_KEY>
AllowedIPs = 10.0.0.4/32
06
QR Code for Mobile Devices
Install qrencode to generate a QR code to scan with the WireGuard app on iOS/Android:
bash
sudo apt install qrencode -y
# Generate QR from client config
qrencode -t ansiutf8 < /path/to/client.conf
07
Management Commands
bash
# Connection status
sudo wg show
# Show data transfer
sudo wg show wg0 transfer
# List connected peers
sudo wg show wg0 peers
# Add peer on the fly (without editing the file)
sudo wg set wg0 peer <pubkey> allowed-ips 10.0.0.5/32
# Remove peer
sudo wg set wg0 peer <pubkey> remove
08
Automatic Setup Script (All-in-One)
To quickly add a new client:
bash
#!/bin/bash
# Usage: ./add-client.sh clientname
CLIENT=$1
CLIENT_IP="10.0.0.$(( $(sudo wg show wg0 peers | wc -l) + 2 ))"
wg genkey | tee /etc/wireguard/clients/${CLIENT}_private.key | wg pubkey > /etc/wireguard/clients/${CLIENT}_public.key
CLIENT_PRIV=$(cat /etc/wireguard/clients/${CLIENT}_private.key)
CLIENT_PUB=$(cat /etc/wireguard/clients/${CLIENT}_public.key)
SERVER_PUB=$(cat /etc/wireguard/server_public.key)
SERVER_IP=$(curl -s ifconfig.me)
# Add to server
echo -e "\n[Peer]\n# $CLIENT\nPublicKey = $CLIENT_PUB\nAllowedIPs = $CLIENT_IP/32" | sudo tee -a /etc/wireguard/wg0.conf
sudo wg syncconf wg0 <(sudo wg-quick strip wg0)
# Create client config
cat > /etc/wireguard/clients/${CLIENT}.conf << EOF
[Interface]
Address = $CLIENT_IP/24
PrivateKey = $CLIENT_PRIV
DNS = 1.1.1.1
[Peer]
PublicKey = $SERVER_PUB
Endpoint = $SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
echo "Client $CLIENT created: IP $CLIENT_IP"
cat /etc/wireguard/clients/${CLIENT}.conf
Related articles
