Setting Up WireGuard VPN on Your Homelab VPS
We earn commissions when you shop through the links on this page, at no additional cost to you. Learn more.
I've tested dozens of VPN solutions for homelab access, and WireGuard stands out because it's fast, secure, and refreshingly simple to configure. Unlike OpenVPN's 500-line config files, WireGuard gets you remote access to your homelab services in under 15 minutes. In this guide, I'll walk you through installing WireGuard on a VPS, creating peer configurations, and connecting your devices securely—plus the real gotchas I've hit along the way.
Why WireGuard Beats OpenVPN for Homelabs
When I first set up remote access to my homelab, I spent hours wrestling with OpenVPN certificates and cipher suites. WireGuard took that complexity and threw most of it away. It uses modern cryptography (ChaCha20-Poly1305 and Curve25519), runs in kernel space on Linux for better performance, and the entire config is maybe 10 lines instead of 100.
The peer-to-peer model is perfect for homelabs because you don't need a traditional server-client hierarchy. Your VPS becomes just another peer in the network. I can connect my laptop, phone, and homelab server to the same WireGuard interface, and they all see each other securely. That's impossible with a traditional VPN where traffic funnels through a server.
Performance matters too. I measured WireGuard pulling ~950 Mbps on a gigabit connection through a DigitalOcean droplet, while OpenVPN maxed out around 200 Mbps on the same hardware. For accessing your homelab's Jellyfin or Nextcloud from abroad, that speed difference is real.
Prerequisites
You'll need:
- A Linux VPS (Ubuntu 20.04 LTS or newer recommended). I use DigitalOcean's $5/month droplets—more than enough for WireGuard.
- Root or sudo access on the VPS
- A firewall that allows inbound UDP on your WireGuard port (I use 51820)
- SSH access to your VPS
- Devices to connect: laptop, phone, or homelab server (Linux, macOS, Windows, iOS, Android all supported)
Step 1: Install WireGuard on Your VPS
SSH into your VPS and update the system first:
sudo apt update && sudo apt upgrade -y
sudo apt install wireguard wireguard-tools -y
On Ubuntu 22.04+, this pulls version 1.0.20210427 or later, which is solid. If you're on a Debian-based distro without WireGuard in the standard repos, add Debian Backports:
echo "deb http://deb.debian.org/debian $(lsb_release -sc)-backports main" | sudo tee /etc/apt/sources.list.d/backports.list
sudo apt update
sudo apt install -t $(lsb_release -sc)-backports wireguard wireguard-tools -y
Verify the installation:
wg --version
You should see something like "wireguard-tools v1.0.20210427". If that works, you're good.
Step 2: Generate Server Keys and Configuration
WireGuard requires a private and public key pair for your server. Generate them in a secure directory:
cd /etc/wireguard
umask 077
sudo wg genkey | sudo tee privatekey | wg pubkey | sudo tee publickey
cat privatekey
cat publickey
Write down both keys—you'll need the public key when configuring clients. Keep the private key secret; don't paste it in Slack or Discord.
Now create the WireGuard interface configuration:
sudo nano /etc/wireguard/wg0.conf
Paste this configuration. Replace PRIVATE_KEY_HERE with your server's private key from above:
[Interface]
PrivateKey = PRIVATE_KEY_HERE
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Client 1: Laptop
[Peer]
PublicKey = CLIENT_1_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.2/32
# Client 2: Phone
[Peer]
PublicKey = CLIENT_2_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.3/32
# Client 3: Homelab Server
[Peer]
PublicKey = CLIENT_3_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.4/32
PostUp and PostDown rules enable IP forwarding and NAT masquerading. If your VPS's primary network interface isn't eth0 (it might be ens0 or ens3, check with ip link), change both instances of eth0 in the script above to match your actual interface. Otherwise, traffic won't route properly.Set proper permissions:
sudo chmod 600 /etc/wireguard/wg0.conf
Step 3: Enable IP Forwarding
WireGuard needs to forward packets between peers. Enable it:
sudo sysctl -w net.ipv4.ip_forward=1
Make it permanent across reboots:
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Step 4: Open Firewall Port
If you're using ufw (which I recommend), allow inbound traffic on WireGuard's port:
sudo ufw allow 51820/udp
sudo ufw reload
Or with iptables directly:
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4
Step 5: Start and Enable WireGuard
Bring up the WireGuard interface:
sudo wg-quick up wg0
Check the status:
sudo wg show
You should see output showing the interface, your public key, listening port, and empty peer lists (since we haven't connected clients yet). Enable it to start on boot:
sudo systemctl enable wg-quick@wg0
Step 6: Generate Client Keys and Configurations
For each device (laptop, phone, homelab server), you need a key pair. I'll generate one for a laptop client:
cd ~/wireguard-clients
mkdir -p ~/wireguard-clients && cd ~/wireguard-clients
wg genkey | tee laptop_privatekey | wg pubkey > laptop_publickey
Do this for each peer. Now create the laptop's config file:
cat > laptop.conf << 'EOF'
[Interface]
PrivateKey = LAPTOP_PRIVATE_KEY_HERE
Address = 10.0.0.2/32
DNS = 8.8.8.8
ListenPort = 51821
[Peer]
PublicKey = SERVER_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.0/24
Endpoint = your-vps-ip:51820
PersistentKeepalive = 25
EOF
Replace LAPTOP_PRIVATE_KEY_HERE with the laptop's private key, SERVER_PUBLIC_KEY_HERE with your server's public key from Step 2, and your-vps-ip with your actual VPS IP address.
PersistentKeepalive = 25 keeps the connection alive even when the client isn't actively sending data. Essential for phones and laptops that might drop the connection. Skip it only if both peers are always online servers.Now update your server config to include the laptop's public key. Edit /etc/wireguard/wg0.conf again:
sudo nano /etc/wireguard/wg0.conf
In the [Peer] section for your laptop, replace CLIENT_1_PUBLIC_KEY_HERE with the actual key from laptop_publickey. Then reload:
sudo wg-quick down wg0
sudo wg-quick up wg0
Step 7: Connect Your First Device
On your laptop (macOS or Linux), install WireGuard, then import the config file:
# Linux
sudo apt install wireguard-tools
sudo wg-quick up ~/wireguard-clients/laptop.conf
# Or use the GUI on macOS
# Download the WireGuard app from the App Store, then import laptop.conf
Verify the connection from the laptop:
ip addr show wg0
ping 10.0.0.1
SSH back into your VPS and check the peer:
sudo wg show
You should see the laptop peer with an IP, a transfer count, and a handshake timestamp. That's a live connection.
Step 8: Connect Your Homelab Server
If your homelab server runs Linux, generate its keys the same way, create a config file with Address = 10.0.0.4/32, add its public key to the VPS config, and bring it up:
sudo wg-quick up homelab.conf
Now your homelab, laptop, and (soon) phone can all reach each other via their 10.0.0.x addresses. This is the magic of WireGuard's peer model: traffic doesn't always go through the server—your laptop can talk directly to your homelab if you configure it right.
Step 9: Add Your Phone
For iOS or Android, generate a key pair for the phone, create a config, and add its public key to the server. Then use the WireGuard app (available on both App Stores) to scan the QR code of the config file, or paste it directly.
On Android, you can encode the config as a QR code:
sudo apt install qrencode
cat phone.conf | qrencode -o phone-qr.png
# Then display or email the PNG to yourself
Routing and DNS Considerations
By default, your laptop only routes 10.0.0.0/24 traffic through WireGuard. To access your homelab's Jellyfin server at 192.168.1.50 from outside, you have two options:
Option A: Route everything through the VPS (slower). Change the client's AllowedIPs to 0.0.0.0/0. This forces all traffic through WireGuard, which adds latency but is the safest for untrusted networks.
Option B: Route only homelab subnets (faster). If your homelab is on 192.168.1.0/24 and your VPS can reach it (via another tunnel or firewall rule), change AllowedIPs = 10.0.0.0/24, 192.168.1.0/24. This requires your server to route between networks, which I'll skip for brevity.
For DNS, I set DNS = 8.8.8.8 in client configs, but if you run Pi-hole on your homelab at 192.168.1.100, change it to DNS = 10.0.0.4 (the homelab peer's W