Skip to main content
Back to Category

WireGuard VPN Server Setup: Step-by-Step Guide

Set up a WireGuard VPN server: key generation, server and client configuration, IP forwarding, firewall rules, and Windows/Linux/Android client setup guide.

Read time: 15 min Security
wireguardvpnserver securitytunnellinuxnetwork securityencryptionvpn setup

Table of Contents

WireGuard VPN Server Setup: Step-by-Step Guide

WireGuard is a modern, fast, and secure VPN protocol. Compared to OpenVPN and IPSec, it has a much simpler structure and delivers high performance. This guide walks you through setting up a WireGuard VPN server on your REXE server so clients can establish secure connections.

Why Choose WireGuard?

  • Simple configuration: Only a few lines of config
  • High performance: Runs at kernel level, low latency
  • Modern cryptography: ChaCha20, Poly1305, Curve25519
  • Small codebase: ~4000 lines (OpenVPN ~100,000 lines)
  • Cross-platform: Linux, Windows, macOS, iOS, Android

Installation

hljs bash
# Ubuntu 20.04+
sudo apt update
sudo apt install wireguard -y

# CentOS/AlmaLinux 8+
sudo dnf install epel-release -y
sudo dnf install wireguard-tools -y

# Debian 11+
sudo apt install wireguard -y

Key Generation

WireGuard uses a key pair (private + public) for each server and client.

hljs bash
# Generate server keys
cd /etc/wireguard

# Generate private key
wg genkey | sudo tee /etc/wireguard/server_private.key

# Derive public key
sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key

# View keys
sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key

# Set file permissions
sudo chmod 600 /etc/wireguard/server_private.key

Server Configuration

hljs bash
# Find your network interface
ip route | grep default
# Example output: default via 192.168.1.1 dev eth0
# Here 'eth0' is the network interface

# Create WireGuard configuration file
sudo nano /etc/wireguard/wg0.conf
hljs ini
# /etc/wireguard/wg0.conf — Server configuration

[Interface]
# IP address of the WireGuard interface
Address = 10.0.0.1/24

# WireGuard listening port
ListenPort = 51820

# Server private key
PrivateKey = SERVER_PRIVATE_KEY_HERE

# IP forwarding rules (PostUp/PostDown)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# Client 1 (Peer)
[Peer]
# Client public key
PublicKey = CLIENT1_PUBLIC_KEY
# IP assigned to client
AllowedIPs = 10.0.0.2/32

# Client 2 (Peer)
[Peer]
PublicKey = CLIENT2_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32

Replace eth0 with your actual network interface name. Find it with ip route | grep default.

Enabling IP Forwarding

hljs bash
# Enable temporarily
sudo sysctl -w net.ipv4.ip_forward=1

# Enable permanently
sudo nano /etc/sysctl.conf
# Add or uncomment this line:
# net.ipv4.ip_forward=1

# Apply changes
sudo sysctl -p

# Verify
cat /proc/sys/net/ipv4/ip_forward
# Output: 1

Firewall Rules

hljs bash
# If using UFW
sudo ufw allow 51820/udp
sudo ufw allow OpenSSH
sudo ufw enable

# For UFW forwarding
sudo nano /etc/default/ufw
# Change DEFAULT_FORWARD_POLICY="ACCEPT"

sudo nano /etc/ufw/before.rules
# Add before the *filter line:
# NAT table
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
COMMIT
hljs bash
# If using iptables
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Make rules persistent
sudo apt install iptables-persistent -y
sudo netfilter-persistent save

Starting the WireGuard Service

hljs bash
# Start WireGuard interface
sudo wg-quick up wg0

# Auto-start on boot
sudo systemctl enable wg-quick@wg0

# Check status
sudo wg show

# View interface info
ip addr show wg0

Client Configuration

Generating Client Keys

hljs bash
# On the client side (or generate on server and transfer)
wg genkey | tee client_private.key | wg pubkey > client_public.key

cat client_private.key  # Private key
cat client_public.key   # Public key (to be added to server)

Linux Client Configuration

hljs ini
# /etc/wireguard/wg0.conf — Client configuration

[Interface]
# Client's VPN IP address
Address = 10.0.0.2/24

# Client private key
PrivateKey = CLIENT_PRIVATE_KEY

# DNS (optional)
DNS = 1.1.1.1

[Peer]
# Server public key
PublicKey = SERVER_PUBLIC_KEY

# Server address and port
Endpoint = SERVER_IP:51820

# Which traffic to route through VPN
# For all traffic:
AllowedIPs = 0.0.0.0/0, ::/0
# For VPN network only:
# AllowedIPs = 10.0.0.0/24

# Keep connection alive (for clients behind NAT)
PersistentKeepalive = 25
hljs bash
# Connect on Linux client
sudo wg-quick up wg0

# Test connection
ping 10.0.0.1
curl ifconfig.me  # Verify external IP is server's IP

Windows Client Setup

  1. Download and install WireGuard for Windows
  2. Open the app → "Add Tunnel" → "Add empty tunnel"
  3. Paste the following configuration:
hljs ini
[Interface]
Address = 10.0.0.3/24
PrivateKey = WINDOWS_CLIENT_PRIVATE_KEY
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_IP:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
  1. Click "Activate"

Android/iOS Client Setup

  1. Download the WireGuard app from Play Store/App Store
  2. Tap "+" → "Create from QR code" or "Create from file"
  3. To convert config to QR code on the server:
hljs bash
# Generate QR code on server
sudo apt install qrencode -y
qrencode -t ansiutf8 < /path/to/client.conf

Adding New Clients

hljs bash
# 1. Generate client keys
wg genkey | tee /etc/wireguard/client3_private.key | wg pubkey > /etc/wireguard/client3_public.key

# 2. Add to server config (without restarting service)
sudo wg set wg0 peer $(cat /etc/wireguard/client3_public.key) allowed-ips 10.0.0.4/32

# 3. Save permanently
sudo wg-quick save wg0

# 4. Check status
sudo wg show

Troubleshooting

hljs bash
# View WireGuard logs
sudo journalctl -u wg-quick@wg0 -f

# Connection statistics
sudo wg show wg0

# Packet capture (for troubleshooting)
sudo tcpdump -i wg0

# Check IP forwarding
cat /proc/sys/net/ipv4/ip_forward

# Check firewall rules
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v

After establishing a WireGuard connection, the latest handshake field in sudo wg show output should be current. If there's no handshake, check the server IP/port, keys, and firewall rules in the client configuration.

Conclusion

WireGuard provides a modern and secure VPN solution. With its simple configuration and high performance, it's ideal for both personal use and enterprise networks. Setting up WireGuard on your REXE server ensures all your clients can establish secure connections.