Setting Up WireGuard: The Modern Self-Hosted VPN
Commercial VPN services cost $5-12/month and require you to trust that they actually don't log your traffic (spoiler: some do). A self-hosted VPN gives you genuine privacy and secure access to your home network — and WireGuard makes it surprisingly simple.
WireGuard is a modern VPN protocol that's faster, simpler, and more secure than OpenVPN or IPsec. It's built into the Linux kernel, uses state-of-the-art cryptography, and the entire codebase is about 4,000 lines (compared to OpenVPN's 100,000+).
Why WireGuard Over Alternatives?
| Feature | WireGuard | OpenVPN | Commercial VPN |
|---|---|---|---|
| Setup complexity | Low | Medium-High | None |
| Performance | Excellent | Good | Varies |
| Codebase size | ~4,000 lines | ~100,000 lines | Unknown |
| Protocol | UDP | TCP or UDP | Varies |
| Reconnection | Instant (roaming) | Seconds | Seconds |
| Linux kernel support | Built-in | Userspace | N/A |
| Monthly cost | $0 (+ VPS if needed) | $0 (+ VPS) | $5-12 |
WireGuard is not a complete replacement for commercial VPNs if your goal is to appear to be in a different country or to obscure your IP from websites. For that, the VPN provider's network of exit points is the product. But for secure remote access and privacy from your ISP, WireGuard is superior.
Common Use Cases
1. Secure access to your home network
Access your self-hosted services (Nextcloud, Home Assistant, media servers) from anywhere without exposing them to the internet.
2. Privacy on public WiFi
Encrypt all traffic from your laptop or phone when on coffee shop or hotel WiFi.
3. Site-to-site connections
Connect multiple locations (home, office, VPS) into a single encrypted network.
4. Bypass ISP throttling
Some ISPs throttle specific services. A VPN tunnel prevents them from inspecting your traffic.
Server Setup
Prerequisites
- A Linux server (VPS or home server) with a public IP
- Root access
- UDP port 51820 open in your firewall
Install WireGuard
On Ubuntu/Debian:
sudo apt install wireguard
On Fedora:
sudo dnf install wireguard-tools
Generate server keys
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
chmod 600 /etc/wireguard/server_private.key
Server configuration
Create /etc/wireguard/wg0.conf:
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>
# Enable IP forwarding and NAT for internet access through the VPN
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Peer: Laptop
[Peer]
PublicKey = <client_public_key>
AllowedIPs = 10.0.0.2/32
# Peer: Phone
[Peer]
PublicKey = <phone_public_key>
AllowedIPs = 10.0.0.3/32
Replace eth0 with your server's actual network interface name (check with ip route | grep default).
Enable IP forwarding
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
Start WireGuard
sudo systemctl enable --now wg-quick@wg0
Client Setup
Generate client keys
wg genkey | tee client_private.key | wg pubkey > client_public.key
Client configuration
Create wg0.conf on your client device:
[Interface]
Address = 10.0.0.2/24
PrivateKey = <client_private_key>
DNS = 1.1.1.1
[Peer]
PublicKey = <server_public_key>
Endpoint = your.server.ip:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
AllowedIPs explained:
0.0.0.0/0— Route ALL traffic through the VPN (full tunnel). Use this for privacy on public WiFi.10.0.0.0/24— Only route VPN subnet traffic through the tunnel (split tunnel). Use this to access home services while using your local internet for everything else.10.0.0.0/24, 192.168.1.0/24— Route VPN and home LAN traffic through the tunnel.
Mobile clients
WireGuard has official apps for iOS and Android. You can import the configuration as a file or scan a QR code:
# Generate QR code for mobile (install qrencode first)
qrencode -t ansiutf8 < client-phone.conf
This displays a QR code in your terminal that the mobile app can scan directly.
Management with wg-easy
If you want a web interface for managing peers, wg-easy provides a clean dashboard:
# docker-compose.yml
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy
restart: unless-stopped
ports:
- "51820:51820/udp"
- "51821:51821/tcp" # Web UI
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
volumes:
- wg_data:/etc/wireguard
environment:
WG_HOST: your.server.ip
PASSWORD_HASH: ${WG_PASSWORD_HASH}
volumes:
wg_data:
The web UI lets you create, disable, and delete clients with one click, and generates QR codes automatically.
Performance
WireGuard's kernel-level implementation means it's significantly faster than userspace VPNs:
| Scenario | WireGuard | OpenVPN |
|---|---|---|
| Throughput (1 Gbps link) | ~900 Mbps | ~400 Mbps |
| Latency overhead | ~0.5 ms | ~2-5 ms |
| CPU usage | Minimal | Moderate |
| Handshake time | ~100 ms | ~1-2 seconds |
| Roaming (network change) | Seamless | Reconnects |
The roaming feature is particularly useful on phones — WireGuard maintains the connection as you switch between WiFi and cellular without any reconnection delay.
Security Considerations
WireGuard uses modern, conservative cryptography:
- ChaCha20 for encryption
- Poly1305 for authentication
- Curve25519 for key exchange
- BLAKE2s for hashing
There are no cipher suite negotiations or configuration options that could be misconfigured. The cryptography is fixed and well-audited.
One important caveat: WireGuard does not provide traffic obfuscation. Your ISP can detect that you're using WireGuard (though they can't see the contents). If you need to hide VPN usage itself (e.g., in countries that block VPNs), you'll need an additional obfuscation layer.
When to Use a Commercial VPN Instead
Self-hosted WireGuard doesn't help with:
- Geo-unblocking — You need exit points in multiple countries, which a single VPS doesn't provide
- IP rotation — Commercial VPNs share IPs among thousands of users, providing anonymity through the crowd
- ISP blocking of VPN ports — Some networks block UDP 51820; commercial VPNs run on port 443 to blend in
The Bottom Line
WireGuard is the best option for secure remote access to your network and private browsing on untrusted WiFi. It's fast, simple to set up, and virtually maintenance-free once running. The initial setup takes about 15 minutes, and then it just works.
For accessing your self-hosted services from anywhere, WireGuard should be the first thing you set up — it secures everything else.