WireGuard on a VPS: Server Setup, Client Configs, and Routing That Works

WireGuard is a kernel-resident VPN tunnel: roughly 4,000 lines of code, built on the Noise protocol framework with ChaCha20-Poly1305 authenticated encryption. Because it runs inside the Linux kernel (since 5.6) instead of in userspace, it delivers near-native throughput — benchmarks routinely show WireGuard saturating a gigabit link while OpenVPN manages 30–50% of line rate on the same hardware.

VPN throughput is single-threaded, so it depends heavily on your vCPU’s single-core speed. Check the CPU specs — see the full specs on our VPS comparison table — before you commit to a budget plan with a weak core.

How WireGuard Compares to OpenVPN

WireGuardOpenVPN
Codebase~4,000 lines100,000+ lines
CryptoChaCha20-Poly1305 (kernel)OpenSSL, AES-NI
TransportUDP onlyUDP or TCP
HandshakeNoise IK (1 round trip)TLS-style, multi-round
ConfigOne [Peer] blockCertificates + CRL

The table explains the practical differences: WireGuard’s fixed header and kernel data path cut both latency and CPU overhead, while OpenVPN’s TCP mode can compound packet loss with retransmission stalls. For a VPS acting as a remote-access gateway, WireGuard is the default choice in 2026.

There are trade-offs worth knowing. WireGuard is connectionless — there is no built-in notion of a session, so roaming clients and IP changes are handled gracefully, but per-user authentication and revocation require either manual peer management or a wrapper like wg-easy. OpenVPN brings a mature ecosystem of user databases and certificates. For a single-admin VPS or a small team, WireGuard’s simplicity wins; the wg command line is the entire control plane.

Installing WireGuard on the VPS

apt update && apt install -y wireguard
modprobe wireguard
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

Ubuntu 24.04 ships the wireguard-tools package and the kernel module is included in the generic kernel, so no third-party repositories are needed.

Choose the tunnel subnet before you configure anything. 10.0.0.0/24 is the conventional choice, but if your LAN or office network already uses that range, pick 10.200.0.0/24 or 172.16.0.0/24 to avoid route collisions when clients are at home. Document the subnet and the server address — you will need them in every client config.

Generating Keys and Writing wg0.conf

umask 077
wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = 

[Peer]
PublicKey = 
AllowedIPs = 10.0.0.2/32

The server keeps a static address in the tunnel network (10.0.0.1/24) and one [Peer] block per client, each with its own /32 address. Add more peers by appending blocks and restarting the interface.

Key hygiene matters more here than in most setups: the private key on the server should be readable only by root (chmod 600 /etc/wireguard/privatekey), and the wg0.conf file should live in /etc/wireguard/ with the same permissions. If a client is compromised, remove its peer block — there is no certificate revocation list to update, which is both the simplicity and the risk of the protocol.

Enabling NAT for Client Traffic

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
systemctl enable --now wg-quick@wg0
wg show   # verify handshakes appear

The single MASQUERADE rule lets tunnel clients reach the internet through the VPS. Make it persistent with iptables-persistent or your firewall management tool so a reboot does not silently break the tunnel.

If the VPS also runs a firewall (ufw or nftables), allow UDP 51820 explicitly and ensure the FORWARD chain permits traffic between the tunnel interface and the public interface. A common failure mode is a firewall that allows the handshake but drops forwarded packets, leaving you with a tunnel that connects and then stalls — check iptables -L -v counters to see where packets stop.

Adding Clients

[Interface]
Address = 10.0.0.2/24
PrivateKey = 
DNS = 1.1.1.1

[Peer]
PublicKey = 
Endpoint = your.vps.ip:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
  • Generate each client keypair with wg genkey/wg pubkey and paste the public key into the server config.
  • For phones, render the client config as a QR code with qrencode -t ansiutf8 < client.conf and scan it in the WireGuard app.
  • PersistentKeepalive = 25 keeps NAT mappings alive on mobile networks and behind carrier-grade NAT.
  • Add clients with wg set wg0 peer <pubkey> allowed-ips 10.0.0.x/32 without restarting the interface.

Full Tunnel vs Split Tunnel

  • Full tunnel (AllowedIPs = 0.0.0.0/0): all client traffic routes through the VPS — maximum privacy, higher latency, uses your VPS bandwidth.
  • Split tunnel (AllowedIPs = 10.0.0.0/24): only VPS-bound traffic goes through the tunnel; everything else uses the local connection — better for accessing a home network or internal services.
  • For remote administration, a split tunnel plus SSH on the VPS is the leanest setup and keeps the VPS bandwidth bill flat.

Troubleshooting Common Failures

SymptomCauseFix
Handshake never completesUDP 51820 blockedOpen the port in the firewall / provider panel
No internet through tunnelMissing MASQUERADE ruleRe-add POSTROUTING rule and check ip_forward
Slow throughputSingle-core bottleneckChoose a VPS with a fast single-core vCPU
DNS leaksResolver not pushedSet DNS = in the client [Interface] block

Start with a full-tunnel config for maximum privacy, then trim AllowedIPs once you trust the routing. When you pick the node for it, compare plans side by side on our comparison table — a fast single-core vCPU is what WireGuard actually needs.

Prefer a managed node so you never touch kernel modules or NAT rules yourself? Cloudways VPS plans ship preconfigured servers with root access and 24/7 support. See Cloudways plans and pricing to spin up a WireGuard host in minutes.

Leave a Reply