WireGuard is the modern way to run a VPN. It's a tiny protocol (about 4 000 lines of kernel code, vs ~600 000 for OpenVPN), it's been part of the mainline Linux kernel since 5.6 (2020), and on the same hardware it routinely outperforms OpenVPN by 3–4× while using a fraction of the CPU. It's what Mullvad, ProtonVPN, NordLynx, Tailscale and almost every modern VPN product is built on under the hood. Setting your own up on a VPS takes a single command — this article shows exactly how.
WireGuard vs OpenVPN, in one paragraph
| Codebase size | WireGuard ~4k lines · OpenVPN ~600k lines |
| Where it runs | WireGuard: in the Linux kernel · OpenVPN: userspace daemon |
| Throughput on the same VPS | WireGuard 800–950 Mbps · OpenVPN 150–300 Mbps (typical) |
| Latency overhead | WireGuard ~1 ms added · OpenVPN ~3–5 ms added |
| Handshake / reconnect | WireGuard <100 ms (designed for mobile) · OpenVPN 1–3 s |
| Crypto | WireGuard: ChaCha20-Poly1305 + Curve25519, fixed · OpenVPN: configurable, often AES-256-GCM |
| Config file | WireGuard: ~10 lines · OpenVPN: ~50–200 lines + a separate cert chain |
| Audit-friendliness | WireGuard: tiny, formally analysed · OpenVPN: huge surface, mature but heavy |
Step 1 — get a VPS
Any NetGrid Host plan will do — even the Starter at €2.98/month is more than enough for a personal VPN serving a handful of devices. Pick the location based on where you want your IP to appear: Germany, Netherlands or Switzerland are popular for privacy/EU jurisdiction; the US for accessing US-only services; pick whatever matches your goal. Spin it up, grab the IP, root password and SSH port from the welcome email.
Step 2 — one-line install
SSH into the server as root:
ssh -p <PORT> root@<YOUR-VPS-IP>Run the well-known Nyr's WireGuard installer (BSD-2 license, single bash file, used by hundreds of thousands of self-hosters since 2020):
curl -O https://raw.githubusercontent.com/Nyr/wireguard-install/master/wireguard-install.sh
bash wireguard-install.shThe installer is interactive — it asks you 4 questions:
- Public IPv4 address — auto-detected, just hit Enter.
- Public DNS for clients — pick `Cloudflare (1.1.1.1)` or `Google (8.8.8.8)`. These are the resolvers your devices use *while the VPN is on*.
- Name for the first client — `my-laptop`, `my-phone`, anything memorable.
- Press any key to continue — and it does the rest.
What the script does, under the hood
- Detects the OS (Ubuntu / Debian / Fedora / RHEL / Rocky / AlmaLinux / CentOS Stream — all supported).
- Installs `wireguard`, `qrencode`, `iptables`.
- Generates the server private/public key pair.
- Writes `/etc/wireguard/wg0.conf` (the server config).
- Enables IPv4/IPv6 forwarding (`net.ipv4.ip_forward`, `net.ipv6.conf.all.forwarding`).
- Adds NAT iptables rules so traffic leaves the VPS using its public IP.
- Generates the first client's keys, writes `/root/<client-name>.conf`.
- Starts and enables `[email protected]` so it auto-starts on reboot.
- Prints a QR code in the terminal that encodes the entire client config.
Step 3 — connect from your device
Install the official WireGuard app:
| iOS | App Store |
| Android | Google Play |
| macOS | App Store |
| Windows | wireguard.com/install/ |
| Linux | `apt install wireguard` (Debian/Ubuntu) or `dnf install wireguard-tools` (RHEL family) |
On a phone — open the app, + → Create from QR code → point the camera at the QR code in your SSH terminal → name the tunnel → toggle the switch. You're connected.
On desktop — copy the `.conf` file from the VPS to your machine, then in the WireGuard app Add Tunnel → Import tunnel(s) from file. To copy:
# From your laptop, replace <port> and <ip>:
scp -P <port> root@<server-ip>:/root/my-laptop.conf ./Step 4 — verify it works
- Before turning on the VPN: open https://geomyip.com — note your real IP and country.
- Enable the WireGuard tunnel in the app.
- Reload https://geomyip.com — the IP should now be your VPS IP, country should match the location you ordered.
- On the server, check the tunnel state with `sudo wg show` — you'll see `latest handshake: a few seconds ago` and `transfer: X received, Y sent` per connected peer.
Add more devices later
Re-run the installer at any time to get a menu (add user, remove user, uninstall):
bash wireguard-install.shPick Add a new user, give it a name, and a fresh `.conf` + QR code drop in `/root/<name>.conf`.
Where the configs live
| Server config | `/etc/wireguard/wg0.conf` — don't share this, it has the server private key |
| Per-client configs | `/root/<client-name>.conf` — these go to your devices |
| systemd service | `[email protected]` (started + enabled on boot) |
| Live status | `sudo wg show` and `sudo wg show wg0` |
Common pitfalls
- A local firewall (ufw / firewalld) blocks UDP 51820. The Nyr installer adds iptables rules but doesn't touch ufw/firewalld. If you have one of them on, allow the WireGuard port: `sudo ufw allow 51820/udp` or `sudo firewall-cmd --permanent --add-port=51820/udp && sudo firewall-cmd --reload`. See our firewall and ports article for the full picture.
- Some mobile carriers / hotel Wi-Fi block UDP 51820. Re-run the installer, pick a more friendly port like `443` (UDP) — it's almost universally allowed because that's HTTPS.
- Speedtest after connecting shows lower than your usual home speed. That's expected — see our internet speed article. VPN throughput is bounded by the slowest link in the path: your home, the server's network, and any transit between them.
- `sudo wg show` shows no peers / no handshake. The client never connected. Check that the public IP in the client config actually points to the server, that UDP 51820 is open from the client, and that you imported the right `.conf` file.
Need to debug something on the VPS? The general-purpose Linux command cheatsheet is at Essential Linux server diagnostics.
VPS from€1.99/ month
Unlimited traffic, a 1 Gbps port and NVMe storage. 12 locations across Europe & the US.