Set Up a WireGuard VPN Server in Under 10 Minutes
Install WireGuard on a Linux server, generate keys, configure the server and one client, and have an encrypted tunnel running with internet traffic routed through it.
WireGuard is a modern VPN protocol built into the Linux kernel since version 5.6. It is faster than OpenVPN, significantly simpler to configure, and uses state-of-the-art cryptography by default. A basic setup takes ten minutes.
What you need
- A Linux server with a public IP (Ubuntu 22.04+ recommended)
- Root or sudo access on the server
- The WireGuard app on your client device
Step 1 — Install WireGuard on the server
sudo apt update
sudo apt install wireguard
On RHEL/Fedora:
sudo dnf install wireguard-tools
Step 2 — Generate server keys
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
This pipes the private key through wg pubkey to derive the public key. Both are saved to files. The private key gets 600 permissions — it must never be readable by other users.
Step 3 — Generate client keys
Do this for each device that will connect. On the server (or on the client — either works):
wg genkey | tee client_private.key | wg pubkey > client_public.key
Step 4 — Configure the server
Find your server's primary network interface (the one with the public IP):
ip route | grep default
# default via 203.0.113.1 dev eth0 ...
Note the interface name — eth0 in this example. Yours may be ens3, enp3s0, or something else.
Create /etc/wireguard/wg0.conf:
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <contents of server_private.key>
# Enable IP forwarding and NAT — lets clients route internet traffic through the VPN
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
[Peer]
# Client device
PublicKey = <contents of client_public.key>
AllowedIPs = 10.0.0.2/32
Replace eth0 with your actual interface name, and paste the actual key contents.
Enable IP forwarding permanently:
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Step 5 — Open the firewall
sudo ufw allow 51820/udp
Step 6 — Start WireGuard
sudo systemctl enable --now wg-quick@wg0
Check that it is running:
sudo wg show
Step 7 — Configure the client
On the client device, create a configuration file (WireGuard apps on all platforms accept this format):
[Interface]
PrivateKey = <contents of client_private.key>
Address = 10.0.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = <contents of server_public.key>
Endpoint = <your-server-public-ip>:51820
AllowedIPs = 0.0.0.0/0 # route all traffic through the VPN
AllowedIPs = 0.0.0.0/0 is what makes this a full-tunnel VPN — all traffic goes through the server. For a split-tunnel (only traffic to 10.0.0.0/24 goes through the VPN, everything else goes directly to the internet), use AllowedIPs = 10.0.0.0/24 instead.
Import the file in the WireGuard app, or on a Linux client:
sudo wg-quick up ./client.conf
Add more clients
For each new device, generate a new key pair and add a [Peer] block to the server config:
[Peer]
# Second device
PublicKey = <new-client-public-key>
AllowedIPs = 10.0.0.3/32
Reload the running interface without disconnecting existing clients:
sudo wg syncconf wg0 <(wg-quick strip wg0)
Verify the connection
From the client, check your public IP — it should now show the VPN server's IP:
curl ifconfig.me
On the server, check active peers:
sudo wg show
The output shows each peer's public key, their last handshake time, and how much data has been transferred. A handshake within the last few minutes means the tunnel is active.
SysEmperor