Install and configure WireGuard VPN server with client management

Intermediate 25 min Mar 31, 2026 50 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Set up a secure WireGuard VPN server with automated client management, including key generation, firewall configuration, and traffic routing for remote access.

Prerequisites

  • Root or sudo access
  • Server with public IP address
  • Basic command line knowledge

What this solves

WireGuard provides a modern, fast, and secure VPN solution that's easier to configure than traditional VPN protocols like OpenVPN or IPSec. This tutorial shows you how to set up a WireGuard server with proper client management, allowing secure remote access to your network or internet traffic routing through your server.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions of WireGuard and dependencies.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install WireGuard

Install WireGuard and the necessary tools for key generation and management.

sudo apt install -y wireguard wireguard-tools
sudo dnf install -y wireguard-tools

Generate server keys

Create the public and private key pair for your WireGuard server. These keys authenticate your server and encrypt traffic.

sudo mkdir -p /etc/wireguard
cd /etc/wireguard
sudo wg genkey | sudo tee server_private.key
sudo cat server_private.key | wg pubkey | sudo tee server_public.key

Set proper key permissions

Secure the private key by restricting access to root only. The private key must never be readable by other users.

sudo chmod 600 /etc/wireguard/server_private.key
sudo chmod 644 /etc/wireguard/server_public.key
Security: Never use chmod 777 on key files. Private keys should only be readable by root (600 permissions).

Find your network interface

Identify your server's main network interface to configure NAT routing properly.

ip route | grep default
ip addr show

Look for the interface in the default route (usually eth0, ens3, or similar). Note this interface name for the next step.

Create WireGuard server configuration

Configure the WireGuard server with network settings, key authentication, and routing rules. Replace eth0 with your actual interface name.

[Interface]
PrivateKey = $(sudo cat /etc/wireguard/server_private.key)
Address = 10.0.0.1/24
ListenPort = 51820
SaveConfig = true

Enable IP forwarding and NAT

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

Create the configuration file with proper substitution

Since we need to substitute the actual private key, create the configuration file with this command.

sudo bash -c 'cat > /etc/wireguard/wg0.conf << EOF
[Interface]
PrivateKey = $(cat /etc/wireguard/server_private.key)
Address = 10.0.0.1/24
ListenPort = 51820
SaveConfig = true

Enable IP forwarding and NAT (replace eth0 with your interface)

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 EOF'

Enable IP forwarding

Configure the kernel to forward packets between network interfaces, which is required for VPN routing.

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Configure firewall

Open the WireGuard port and configure firewall rules for VPN traffic routing.

# Install ufw if not present
sudo apt install -y ufw

Configure UFW rules

sudo ufw allow 51820/udp sudo ufw allow OpenSSH sudo ufw --force enable
# Configure firewalld
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --reload

Start and enable WireGuard

Enable WireGuard to start automatically on boot and start the service now.

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
sudo systemctl status wg-quick@wg0

Generate client keys

Create key pairs for your first client. Repeat this process for each client you want to add.

cd /etc/wireguard
sudo wg genkey | sudo tee client1_private.key
sudo cat client1_private.key | wg pubkey | sudo tee client1_public.key
sudo chmod 600 /etc/wireguard/client1_private.key

Add client to server configuration

Add the client's public key and assigned IP address to the server configuration.

sudo wg set wg0 peer $(sudo cat /etc/wireguard/client1_public.key) allowed-ips 10.0.0.2/32
sudo wg-quick save wg0

Create client configuration file

Generate a complete configuration file that clients can import. Replace 203.0.113.10 with your server's public IP address.

sudo bash -c 'cat > /etc/wireguard/client1.conf << EOF
[Interface]
PrivateKey = $(cat /etc/wireguard/client1_private.key)
Address = 10.0.0.2/32
DNS = 8.8.8.8, 8.8.4.4

[Peer]
PublicKey = $(cat /etc/wireguard/server_public.key)
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF'

Generate QR code for mobile clients

Install qrencode to generate QR codes that mobile WireGuard apps can scan for easy setup.

sudo apt install -y qrencode
sudo qrencode -t ansiutf8 < /etc/wireguard/client1.conf
sudo dnf install -y qrencode
sudo qrencode -t ansiutf8 < /etc/wireguard/client1.conf

Managing additional clients

Add a new client

Use this script template to easily add new clients with automatic IP assignment.

#!/bin/bash
CLIENT_NAME="client2"
CLIENT_IP="10.0.0.3"
SERVER_PUBLIC_IP="203.0.113.10"

Generate client keys

cd /etc/wireguard sudo wg genkey | sudo tee ${CLIENT_NAME}_private.key sudo cat ${CLIENT_NAME}_private.key | wg pubkey | sudo tee ${CLIENT_NAME}_public.key sudo chmod 600 /etc/wireguard/${CLIENT_NAME}_private.key

Add to server

sudo wg set wg0 peer $(sudo cat /etc/wireguard/${CLIENT_NAME}_public.key) allowed-ips ${CLIENT_IP}/32 sudo wg-quick save wg0

Create client config

sudo bash -c "cat > /etc/wireguard/${CLIENT_NAME}.conf << EOF [Interface] PrivateKey = \$(cat /etc/wireguard/${CLIENT_NAME}_private.key) Address = ${CLIENT_IP}/32 DNS = 8.8.8.8, 8.8.4.4 [Peer] PublicKey = \$(cat /etc/wireguard/server_public.key) Endpoint = ${SERVER_PUBLIC_IP}:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25 EOF"

Remove a client

Remove a client's access by removing their peer configuration from the server.

# Remove client from server
sudo wg set wg0 peer $(sudo cat /etc/wireguard/client1_public.key) remove
sudo wg-quick save wg0

Clean up client files

sudo rm /etc/wireguard/client1_private.key sudo rm /etc/wireguard/client1_public.key sudo rm /etc/wireguard/client1.conf

Verify your setup

# Check WireGuard status
sudo wg show
sudo systemctl status wg-quick@wg0

Check if IP forwarding is enabled

sysctl net.ipv4.ip_forward

Check firewall rules

sudo iptables -t nat -L POSTROUTING sudo iptables -L FORWARD

Test connectivity (after connecting a client)

ping 10.0.0.2
Note: The client configuration files contain sensitive private keys. Transfer them securely and delete them from the server after distribution.

Common issues

SymptomCauseFix
Connection timeoutsFirewall blocking port 51820Check firewall rules with sudo ufw status or sudo firewall-cmd --list-all
Can connect but no internetIP forwarding disabled or wrong interface in PostUpCheck sysctl net.ipv4.ip_forward and verify interface name in wg0.conf
Handshake failsClock synchronization issuesInstall and enable NTP: sudo apt install ntp or sudo dnf install chrony
Permission denied on keysIncorrect file permissionsSet private keys to 600: sudo chmod 600 /etc/wireguard/*_private.key
Service won't startConfiguration syntax errorCheck config with sudo wg-quick up wg0 for detailed error messages

Next steps

Automated install script

Run this to automate the entire setup

#wireguard #vpn #server #networking #security

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer