SELF-HOSTED VPN WITH WIREGUARD
INTRODUCTION
Commercial VPNs log your data despite their "No Logs" claims. The only way to be sure is to host your own. WireGuard is a modern, high-performance VPN protocol that is much faster and easier to set up than OpenVPN.
PREREQUISITES
- A VPS (Virtual Private Server) - DigitalOcean, Linode, or Vultr ($5/mo).
- Ubuntu 24.04 LTS or newer.
- SSH Access.
INSTRUCTIONS
1. Install WireGuard
SSH into your VPS and install the package.
2. Generate Keys
Generate private and public keys for the server and client.
3. Configure Server
Edit /etc/wireguard/wg0.conf:
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = [SERVER_PRIVATE_KEY]
[Peer]
PublicKey = [CLIENT_PUBLIC_KEY]
AllowedIPs = 10.0.0.2/32
4. Enable IP Forwarding
Put net.ipv4.ip_forward=1 into /etc/sysctl.d/99-wireguard.conf (newer releases no longer ship /etc/sysctl.conf) and run sudo sysctl --system.
CONCLUSION
Start the interface with wg-quick up wg0. You now have a private, encrypted tunnel. Use the client
config on your phone or PC to connect.
FAQ / TROUBLESHOOTING
⚠️ Common issues and fixes
❌ wg-quick up wg0 fails with "Permission denied"
Run it with sudo – wg-quick needs root. A world-readable config only triggers a
warning, but it exposes your private key, so lock it down anyway:
❌ Handshake completes, but no internet access
IP forwarding is not active or the firewall is blocking traffic. Verify:
sudo iptables -t nat -L # must show MASQUERADE rule
Add NAT if missing (replace eth0 with your interface):
❌ DNS leaks reveal my real ISP
Add a DNS entry to your client config and disable any plaintext DNS in
/etc/resolv.conf. In the client config, set DNS = 1.1.1.1, 9.9.9.9 under
[Interface] and restart the tunnel.
❌ Connection drops after a few minutes
Most often a keepalive problem with NAT/firewalls. Add to the
[Peer] section of the client config (the side behind NAT):
❌ How do I add a second client?
Generate a new keypair, add a [Peer] block on the server with a unique
IP (e.g. 10.0.0.3/32), and import the matching client config. Never reuse IPs between peers.
❓ Still stuck?
→ Check wg show for handshake/transfer stats
and journalctl -u wg-quick@wg0 for service logs.