Setup Wireguard

Wireguard VPN

Setting up Wireguard for

By Puyu Wang

Published on Friday 2024-07-26

Last Modified on Saturday 2025-11-01

How to Set Up WireGuard Server

Introduction

This is step-by-step guide to set up a WireGuard server.


Understanding WireGuard Basics

How WireGuard Works

WireGuard uses public-key cryptography (similar to SSH) to establish secure tunnels. Each device has: - Private Key: Kept secret on the device - Public Key: Shared with peers - Preshared Key (optional): Additional layer of security

Network Topology

In our setup: - Server: Acts as the central hub (e.g., 10.0.0.1/24) - Peers: All client devices (e.g., 10.0.0.2, 10.0.0.3, etc.) - All traffic is encrypted and routed through the server


Installing WireGuard

On Ubuntu/Debian Server

# Update package list
sudo apt update

# Install WireGuard
sudo apt install wireguard

# Verify installation
wg --version

Generating Keys

Understanding Key Security

Before generating keys, set the proper umask to ensure your private keys are only readable by you:

umask 077

Server Keys

Generate keys for your WireGuard server:

# Navigate to WireGuard directory
cd /etc/wireguard/


# Generate privatekey
wg genkey > privatekey
# Generate publickey from the private key
wg pubkey < privatekey > publickey

# Generate a pair of  private and public keys with one command
wg genkey | tee server_privatekey | wg pubkey > server_publickey

Client Keys (Automated Script)


#!/bin/bash

umask = 077

peers=("peerServer" "peerA" "peerB" "peerC")

for peer in "${peers[@]}"; do
  wg genkey | tee "${peer}_privatekey" | wg pubkey > "${peer}_publickey"

  wg genpsk > "${peer}_presharedkey"

  echo "Keys generated for ${peer}:"
  echo "  - Private Key: ${peer}_privatekey"
  echo "  - Public Key: ${peer}_publickey"
  echo "  - Preshared Key: ${peer}_presharedkey"

done

Save this script as generate_peer_keys.sh, make it executable, and run it:

chmod +x generate_peer_keys.sh
./generate_peer_keys.sh

Important: Store these keys securely! Anyone with a private key can access your VPN.


Configuring the Server

Create Server Configuration

Create /etc/wireguard/wg0.conf:

[Interface]
# Server private key
PrivateKey = <SERVER_PRIVATE_KEY>

# Server IP address in the VPN network
Address = 10.0.0.1/32 [or other subnet]

# UDP port for WireGuard (default: 51820)
ListenPort = 51820

# Enable IP forwarding you can also enable it permanently in /etc/sysctl.conf
PostUp = sysctl -w net.ipv4.ip_forward=1

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


### Peers Configuration ###
[Peer]
# Client's public key
PublicKey = <Peer A PUBLIC KEY>

# Optional: Preshared key for additional security
PresharedKey = <Peer A PRESHARED KEY>

# IP address assigned to this peer
AllowedIPs = 10.0.0.2/32

### Peer B Configuration ###
[Peer]
PublicKey = <Peer B PUBLIC KEY>
PresharedKey = <Peer B PRESHARED KEY>
AllowedIPs = 10.0.0.3/32

Note: Replace eth0 with your actual network interface name. Find it using ip link show.

Set Proper Permissions

sudo chmod 600 /etc/wireguard/wg0.conf

Enable IP Forwarding Permanently

Edit /etc/sysctl.conf:

sudo nano /etc/sysctl.conf

Add or uncomment:

net.ipv4.ip_forward=1

Apply changes:

sudo sysctl -p

Start WireGuard Server

# Start the VPN
sudo wg-quick up wg0

# Enable automatic startup on boot
sudo systemctl enable wg-quick@wg0

# Check status
sudo wg show

Configuring Clients

Client Configuration

Create wg0.conf for each client:

[Interface]
# Client's private key
PrivateKey = <PEER_PRIVATE_KEY>

# Client's VPN IP address
Address = 10.0.0.2/32

# Optional: DNS servers to use when connected
DNS = 1.1.1.1, 8.8.8.8

[Peer]
# Server's public key
PublicKey = <SERVER_PUBLIC_KEY>

# Preshared key
PresharedKey = <PEER_PRESHARED_KEY>

# Server's public IP and port
Endpoint = <SERVER_PUBLIC_IP>:51820

# Route all traffic through VPN (full tunnel)
AllowedIPs = 0.0.0.0/0, ::/0

# Keep connection alive (important for mobile)
PersistentKeepalive = 25

Configuration Options Explained:

  • AllowedIPs = 0.0.0.0/0: Routes all traffic through VPN (full tunnel)
  • AllowedIPs = 10.0.0.0/24: Routes only VPN subnet traffic (split tunnel)
  • PersistentKeepalive = 25: Sends keepalive packets every 25 seconds to maintain NAT mappings

Start the client:

sudo wg-quick up wg0

Network and Firewall Setup

Router Configuration

  1. Port Forwarding:
  2. Forward UDP port 51820 to your server's local IP
  3. Example: External 51820 → Internal 192.168.1.100:51820

  4. Dynamic DNS: If your ISP provides a dynamic IP, set up Dynamic DNS (DDNS) to map a domain name to your changing IP. I am not able to do this as I am using eduroam for most of the time.

Firewall Configuration (UFW)

# Allow WireGuard port
sudo ufw allow 51820/udp

# Allow SSH (important! if you use SSH at port 22 to manage the server)
sudo ufw allow 22/tcp

# Enable firewall
sudo ufw enable

# Check status
sudo ufw status

Testing Your VPN

Verify Server Status

# Check if WireGuard is running
sudo wg show

# Should show connected peers
sudo wg show wg0

Expected output:

interface: wg0
  public key: <server_public_key>
  private key: (hidden)
  listening port: 51820

peer: <peer1_public_key>
  preshared key: (hidden)
  endpoint: <peer_ip>:<peer_port>
  allowed ips: 10.0.0.2/32
  latest handshake: 30 seconds ago
  transfer: 15.2 MiB received, 8.4 MiB sent

Security Best Practices

  • Never share private keys
  • Regenerate keys if compromised
  • Use preshared keys for additional security

Advanced Configuration

Split Tunneling

To route only specific traffic through VPN (e.g., home network only):

Client configuration:

[Peer]
# Only route home network traffic through VPN
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24