−50% on all plans · starting at €2.48/mo · Blog·Docs·Sales

Setting up WireGuard VPN on a Linux VPS

Step-by-step guide from zero to encrypted tunnel, with security hardening and client management tips.

WireGuard is the modern VPN protocol that replaced OpenVPN and IPsec in most new deployments. It's faster (kernel-resident), simpler (less than 4,000 lines of code), and cryptographically more conservative (modern primitives, no negotiated cipher suites). This guide takes you from a fresh Ubuntu VPS to a working WireGuard server with multiple clients in about 30 minutes.

What you need

Step 1: Install WireGuard

WireGuard has been in the mainline Linux kernel since 5.6, so on any modern distro the install is trivial:

sudo apt update
sudo apt install -y wireguard wireguard-tools

Verify the kernel module is available:

sudo modprobe wireguard
lsmod | grep wireguard

Step 2: Generate server keys

WireGuard uses public-key cryptography. Each peer (server and client) has a key pair. Generate the server's pair:

cd /etc/wireguard
sudo umask 077
sudo wg genkey | sudo tee server_private.key | wg pubkey | sudo tee server_public.key

The umask command ensures private key files aren't world-readable. Always preserve this — leaked private keys mean your VPN is compromised.

Step 3: Create the server config

Create /etc/wireguard/wg0.conf with the following:

[Interface]
Address = 10.66.66.1/24
ListenPort = 51820
PrivateKey = <paste contents of server_private.key>
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

The PostUp/PostDown rules enable IP forwarding and NAT — necessary if you want clients to reach the public internet through the VPN.

Replace eth0 with your actual primary interface (ip route | grep default tells you).

Step 4: Enable IP forwarding

sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
sudo sysctl -p

Step 5: Start the server

sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

Verify it's running:

sudo wg show

You should see the wg0 interface with your public key and listening port. No peers yet.

Step 6: Configure your VPS firewall

Open UDP port 51820:

sudo ufw allow 51820/udp
sudo ufw allow ssh
sudo ufw enable

Step 7: Generate a client config

For each device that will connect, generate a key pair on the server (you'll send the private key to the client securely, or generate it on the client device — both are valid):

wg genkey | tee client1_private.key | wg pubkey > client1_public.key

Add the client to the server config (/etc/wireguard/wg0.conf):

[Peer]
PublicKey = <client1 public key>
AllowedIPs = 10.66.66.2/32

Reload the interface:

sudo wg syncconf wg0 <(wg-quick strip wg0)

Then create the client's wg0.conf file (give this to the client device):

[Interface]
Address = 10.66.66.2/24
PrivateKey = <client1 private key>
DNS = 1.1.1.1, 9.9.9.9

[Peer]
PublicKey = <server public key>
Endpoint = <your VPS public IP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Setting AllowedIPs = 0.0.0.0/0 in the client config means all traffic is routed through the VPN. If you only want certain subnets routed (split tunneling), specify those instead (e.g., 10.66.66.0/24 for VPN-internal only).

Step 8: Connect from the client

On Linux: sudo wg-quick up <config-file>

On macOS/Windows: install the WireGuard app, import the config file.

On iOS/Android: install the WireGuard app, scan a QR code generated from the config (use qrencode -t ansiutf8 < client1.conf on the server).

Hardening checklist

Common pitfalls

Mismatched AllowedIPs. The most common WireGuard misconfiguration. Server's peer AllowedIPs and client's interface Address must match. If client is at 10.66.66.2/24, server peer entry must be 10.66.66.2/32 (single IP) — not /24, which would route the entire subnet to that one client.

NAT not working. Check iptables -t nat -L POSTROUTING -n -v shows the MASQUERADE rule. If it's missing, the PostUp didn't run — restart wg0.

DNS leaks. Set DNS in client config explicitly. Otherwise the client will use its local DNS resolver, which might bypass the tunnel and leak query info.

MTU issues. WireGuard's overhead is 60 bytes for IPv4. If you see large packets timing out, set MTU = 1420 in the client interface section.

Going further

Once the basic setup works, consider:

For most personal and small-team use cases, the single-server hub-and-spoke setup we just built is more than sufficient. It handles a few dozen clients with negligible CPU on even our €2.48 Starter VPS — WireGuard is genuinely that lightweight.


Related articles

Try FranceVPS today

14-day money-back guarantee. No card required to explore. Sovereign French infrastructure.