News
🌐 Networking Tutorials Set Up a WireGuard VPN Server in Under 10 Minutes

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.