Updated: May 2026 | Covers Ubuntu 26.04, 24.04, Debian, Fedora | Server + client + mobile setup
WireGuard is the default VPN protocol in 2026. It is built into the Linux kernel, faster than OpenVPN, simpler to configure, and cryptographically sound. Mullvad deprecated OpenVPN entirely in January 2026 — that is the direction the industry is moving.
This guide covers how to set up WireGuard VPN on Linux from scratch — server installation, key generation, firewall configuration, client setup on Linux and mobile, and post-quantum pre-shared keys. By the end you will have a fully working self-hosted VPN that you own and control, with no subscription fees and no third-party access to your traffic.
Why WireGuard over OpenVPN or IPsec?
Where OpenVPN ships roughly 600,000 lines of code, WireGuard accomplishes the same core task in around 4,000 lines — a surface area small enough for a single security researcher to audit over a weekend. It has been merged directly into the Linux kernel since version 5.6, meaning there is nothing extra to compile or load on any modern distribution. On top of that, it uses exclusively state-of-the-art cryptography: the Noise protocol framework, ChaCha20-Poly1305 for symmetric encryption, Curve25519 for key exchange, and BLAKE2 for hashing.
The practical result is a VPN that is faster than OpenVPN in almost every benchmark, simpler to configure than IPsec, and easier to audit than both.
What you need before starting
For the server:
- A Linux VPS with a public IP address — Ubuntu 26.04 LTS, Ubuntu 24.04 LTS, or Debian 12 recommended
- SSH access with sudo privileges
- UDP port 51820 open in your firewall or hosting control panel
- A $5–10/month VPS from providers like Hetzner, Linode, or DigitalOcean is more than enough. Oracle Cloud’s free tier also provides a VM with a public IP at no cost.
For the client:
- Any Linux machine, or a smartphone (iOS/Android)
- The WireGuard client package installed
Part 1 — Server setup
Step 1: Install WireGuard
Ubuntu 26.04 / 24.04 / 22.04 and Debian:
bash
sudo apt update
sudo apt install wireguard -y
Fedora:
bash
sudo dnf install wireguard-tools -y
Arch Linux:
bash
sudo pacman -S wireguard-tools
Verify the installation:
bash
wg --version
Step 2: Generate server keys
bash
# Generate the private key
wg genkey | sudo tee /etc/wireguard/server_private.key
# Derive the public key from the private key
sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
# Lock down the private key — readable by root only
sudo chmod 600 /etc/wireguard/server_private.key
Note your server public key — you will need it when configuring clients:
bash
sudo cat /etc/wireguard/server_public.key
Step 3: Enable IP forwarding
WireGuard needs IP forwarding enabled to route client traffic through the server.
bash
# Enable immediately
sudo sysctl -w net.ipv4.ip_forward=1
# Make it persistent across reboots
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Step 4: Find your server’s network interface name
bash
ip route | grep default | awk '{print $5}'
This typically returns eth0, ens3, or similar. Note it — you need it for the firewall rules in the next step.
Step 5: Create the server configuration
bash
sudo nano /etc/wireguard/wg0.conf
Paste the following, replacing SERVER_PRIVATE_KEY with the contents of /etc/wireguard/server_private.key and eth0 with your interface name:
ini
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820
SaveConfig = true
# Firewall rules — replace eth0 with your interface name
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
Insert the private key directly:
bash
sudo sed -i "s|SERVER_PRIVATE_KEY|$(sudo cat /etc/wireguard/server_private.key)|" /etc/wireguard/wg0.conf
Lock down the config file:
bash
sudo chmod 600 /etc/wireguard/wg0.conf
Step 6: Start WireGuard and enable on boot
bash
sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0
Verify the interface is up:
bash
sudo wg show
You should see the wg0 interface listed with your public key and listening port.
Step 7: Open the firewall
Ubuntu with UFW:
bash
sudo ufw allow 51820/udp
sudo ufw reload
sudo ufw status
Fedora / RHEL with firewalld:
bash
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --reload
Part 2 — Client setup on Linux
Step 1: Install WireGuard on the client machine
Same commands as the server — use the appropriate package manager for your distro.
Step 2: Generate client keys
Run this on the client machine, not the server:
bash
wg genkey | sudo tee /etc/wireguard/client_private.key
sudo cat /etc/wireguard/client_private.key | wg pubkey | sudo tee /etc/wireguard/client_public.key
sudo chmod 600 /etc/wireguard/client_private.key
Note the client public key:
bash
sudo cat /etc/wireguard/client_public.key
Step 3: Add the client as a peer on the server
Back on the server, add the client peer:
bash
sudo wg set wg0 peer CLIENT_PUBLIC_KEY allowed-ips 10.0.0.2/32
Replace CLIENT_PUBLIC_KEY with the public key you generated on the client. Because SaveConfig = true is set in the server config, this is saved automatically.
Step 4: Create the client configuration
On the client machine, create the config file:
bash
sudo nano /etc/wireguard/wg0.conf
ini
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.0.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = YOUR_SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Replace:
CLIENT_PRIVATE_KEY— contents of/etc/wireguard/client_private.keyon the clientSERVER_PUBLIC_KEY— contents of/etc/wireguard/server_public.keyon the serverYOUR_SERVER_IP— your VPS public IP address
Full tunnel vs split tunnel:
AllowedIPs = 0.0.0.0/0 routes all traffic through the VPN — use this for privacy and public WiFi protection.
AllowedIPs = 192.168.1.0/24, 10.0.0.0/24 routes only home network traffic through the VPN — split tunneling, much faster if you only need remote access to local resources rather than full privacy routing.
Step 5: Connect the client
bash
sudo wg-quick up wg0
Verify the connection:
bash
sudo wg show
curl https://ifconfig.me
The IP returned by curl should be your VPS’s public IP, not your local IP — confirming all traffic is routing through the VPN.
Step 6: Enable auto-connect on boot (optional)
bash
sudo systemctl enable wg-quick@wg0
Useful client commands
bash
# Connect
sudo wg-quick up wg0
# Disconnect
sudo wg-quick down wg0
# Check connection status
sudo wg show
# Check your public IP (should show VPS IP when connected)
curl https://ifconfig.me
Part 3 — Mobile client setup via QR code
Adding a phone client is easiest via QR code — no manual config file transfer required.
Step 1: Generate mobile client keys on the server
bash
wg genkey | tee /tmp/mobile_private.key | wg pubkey > /tmp/mobile_public.key
Step 2: Add the mobile peer to the server
bash
sudo wg set wg0 peer $(cat /tmp/mobile_public.key) allowed-ips 10.0.0.3/32
Step 3: Create the mobile client config
bash
cat > /tmp/mobile_wg0.conf << EOF
[Interface]
PrivateKey = $(cat /tmp/mobile_private.key)
Address = 10.0.0.3/24
DNS = 1.1.1.1
[Peer]
PublicKey = $(sudo cat /etc/wireguard/server_public.key)
Endpoint = YOUR_SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
Step 4: Generate and scan the QR code
bash
sudo apt install qrencode -y # Ubuntu/Debian
# or
sudo dnf install qrencode -y # Fedora
qrencode -t ansiutf8 < /tmp/mobile_wg0.conf
A QR code appears in your terminal. Open the WireGuard app on iOS or Android, tap the + button, select Scan QR code, and scan it. The tunnel is imported instantly.
Step 5: Clean up temp files
bash
rm /tmp/mobile_private.key /tmp/mobile_public.key /tmp/mobile_wg0.conf
Part 4 — Post-quantum pre-shared keys (optional but recommended)
WireGuard supports adding a pre-shared key (PSK) to each peer relationship as a post-quantum defence layer. The PSK is a symmetric secret shared between server and client that supplements the Curve25519 key exchange with an additional layer of symmetric encryption resistant to quantum attacks.
Generate a PSK for each peer:
bash
wg genpsk | sudo tee /etc/wireguard/psk_client1.key
sudo chmod 600 /etc/wireguard/psk_client1.key
Add it to the server peer entry:
bash
sudo wg set wg0 peer CLIENT_PUBLIC_KEY preshared-key /etc/wireguard/psk_client1.key
Add PresharedKey = PSK_CONTENTS to the [Peer] section of the client config as well. Both sides must have the same PSK for the tunnel to establish.
Security best practices
Protect your private keys. If the server private key is compromised, rotate it and redistribute the new public key to all peers. The server config file contains the private key in plaintext — keep /etc/wireguard/wg0.conf readable only by root.
bash
sudo chmod 600 /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/server_private.key
WireGuard does not log connections by default. If you need audit trails, add logging at the firewall level or use a monitoring solution to track tunnel activity.
Additional recommendations:
- Use a non-standard port if your VPS host allows it — anything other than 51820 reduces automated scanning noise
- Rotate peer keys periodically for long-running deployments
- Remove peer entries for devices you no longer use:
sudo wg set wg0 peer PUBLIC_KEY remove - Use a dedicated non-root user on the server for WireGuard management
Troubleshooting common issues
Tunnel connects but no internet access
Check IP forwarding is active:
bash
cat /proc/sys/net/ipv4/ip_forward
# Should return: 1
Check iptables rules are applied:
bash
sudo iptables -t nat -L POSTROUTING -n -v
If the MASQUERADE rule is missing, verify the interface name in your PostUp line matches your actual network interface (ip route | grep default).
wg-quick up wg0 fails with “Address already in use”
The interface already exists. Bring it down first:
bash
sudo wg-quick down wg0
sudo wg-quick up wg0
Client connects but DNS leaks
Verify the DNS = 1.1.1.1 line is present in the client [Interface] section. On some distros you may need resolvconf installed:
bash
sudo apt install resolvconf # Ubuntu/Debian
Test for DNS leaks at dnsleaktest.com with the VPN connected.
Handshake never completes
Check UDP port 51820 is open on the server:
bash
sudo ss -ulnp | grep 51820
If nothing appears, WireGuard is not listening. Check the service status:
bash
sudo systemctl status wg-quick@wg0
sudo journalctl -u wg-quick@wg0 -n 50
Peer shows “last handshake” but no data transfer
The AllowedIPs on the server and client must match. On the server, the client’s allowed IP must be exactly its assigned address (10.0.0.2/32). A mismatch silently blocks traffic.
Managing multiple peers
For a home lab or small team, add additional peers following the same pattern — generate a key pair, add the peer to the server, create a client config with a unique Address (10.0.0.3/24, 10.0.0.4/24, etc.).
View all connected peers and their last handshake times:
bash
sudo wg show
Remove a peer:
bash
sudo wg set wg0 peer PEER_PUBLIC_KEY remove
List all peers in the config:
bash
sudo wg showconf wg0
Summary — WireGuard VPN on Linux in five commands
bash
# 1. Install
sudo apt install wireguard -y
# 2. Generate server keys
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
# 3. Enable IP forwarding
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
# 4. Start the tunnel
sudo systemctl enable --now wg-quick@wg0
# 5. Verify
sudo wg show
WireGuard is the cleanest, fastest, and most auditable VPN protocol available on Linux in 2026. Self-hosting it means no subscription, no third party between you and your traffic, and a setup that takes under 30 minutes to get right.
How to Set Up WireGuard VPN on Linux
How to Set Up WireGuard VPN on Linux (Server and Client, 2026)
Updated: May 2026 | Covers Ubuntu 26.04, 24.04, Debian, Fedora | Server + client + mobile setup Wire…
Origami Linux Is Dead — and That Might Be Great News for Immutable Linux
Published: June 2026 | Category: News & Analysis If you blinked last week, you might have missed…
How to Harden Your Linux System in 30 Minutes (Step-by-Step)
Skill level: Intermediate | Time to complete: 30–40 minutes | Tested on: Ubuntu 24.04, Debian 12, Fe…
Windows 11 vs Linux in 2026 — Should You Switch?
Updated: May 2026 | Covers performance, gaming, privacy, software, and who should actually switch Wi…
Best Linux Distro for Gaming in 2026 (AMD, NVIDIA and Beginner Picks)
Updated: May 2026 | Covers desktop, laptop and handheld gaming | Steam, Proton, and native titles Li…
Best Linux Distro for Developers in 2026
Updated: May 2026 | Covers web dev, DevOps, data science, security, embedded and general purpose Ask…

Best VPN Services in 2026: Top Picks for Speed, Privacy, and Value
The best VPN services in 2026 do a lot more than hide your IP address. The top options protect your …

How to Protect IoT Devices from Hackers: A Practical Guide for Home Users
A few years ago, a family in the US noticed something strange. Their baby monitor — a perfectly ordinary Wi-Fi connected camera — had started moving on its own.

IoT and Data Privacy: How Safe Is Your Smart Home in 2026? – IoT Security
The smart home revolution has made everyday life more convenient than ever. From voice assistants that control the lights to security cameras that send alerts directly to your phone, connected…

VPNs and IoT: How to Secure Your Smart Home Network
As smart home devices become more common, so do the security risks that come with them. From smart thermostats and voice assistants to connected cameras and door locks, each device…





