Configuring WireGuard VPN on a VPS to Securely Access Your Homelab

Configuring WireGuard VPN on a VPS to Securely Access Your Homelab

We earn commissions when you shop through the links on this page, at no additional cost to you. Learn more.

Running a homelab behind a residential ISP usually means dealing with CGNAT, dynamic IPs, and a router you're not fully allowed to control. My solution for the past two years has been running WireGuard on a cheap VPS as a jump point — the VPS gets a stable public IP, my homelab connects to it as a peer, and I can reach every internal service from anywhere without opening a single port on my home router.

This tutorial is specifically about using a VPS as a WireGuard hub that your homelab tunnels into, rather than the more common "VPS as full exit node" setup. The difference matters: with this approach, traffic to your homelab services stays inside the tunnel, but your homelab's regular internet traffic doesn't route through the VPS. That means lower latency for home devices and a smaller bandwidth bill on the VPS side.

I'm running this on a DigitalOcean Droplet — their $6/month AMD instance is plenty for a WireGuard hub. If you're not already using DigitalOcean, create your DigitalOcean account today — they offer a solid SLA and straightforward networking that makes this kind of setup easy to reason about.

Architecture Overview

Before touching a config file, let me explain the three players in this setup:

The tunnel subnet is 10.10.0.0/24. Your home LAN might be 192.168.1.0/24. You'll tell WireGuard that your homelab peer is authoritative for 192.168.1.0/24, so traffic destined for home devices gets routed through it automatically.

Step 1: Prepare the VPS

SSH into your VPS and install WireGuard. On Ubuntu 22.04 or 24.04 it's a one-liner:

sudo apt update && sudo apt install -y wireguard

# Enable IP forwarding — required so the VPS can route between peers
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Generate the VPS key pair
wg genkey | sudo tee /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key
sudo chmod 600 /etc/wireguard/private.key

Now create the WireGuard interface config. Substitute VPS_PRIVATE_KEY with the contents of /etc/wireguard/private.key, and fill in the public keys for your peers once you generate them in later steps. I'll use placeholder names for clarity:

sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <VPS_PRIVATE_KEY>

# NAT outbound tunnel traffic so peers can reach each other
PostUp   = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# --- Homelab Gateway peer ---
[Peer]
PublicKey = <HOMELAB_PUBLIC_KEY>
AllowedIPs = 10.10.0.2/32, 192.168.1.0/24

# --- Road Warrior (laptop/phone) peer ---
[Peer]
PublicKey = <LAPTOP_PUBLIC_KEY>
AllowedIPs = 10.10.0.3/32
Tip: If your VPS network interface isn't eth0, check with ip route get 8.8.8.8 and replace eth0 in the PostUp/PostDown rules with whatever interface name shows up after "dev".

Enable and start the interface:

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
sudo systemctl status wg-quick@wg0

Step 2: Lock Down the VPS Firewall

I always use UFW on the VPS side. WireGuard only needs UDP 51820 open — everything else can stay closed, because authenticated homelab services will be reachable through the tunnel, not directly on the public IP.

sudo ufw allow ssh
sudo ufw allow 51820/udp
sudo ufw enable
sudo ufw status verbose
Watch out: Run sudo ufw allow ssh before sudo ufw enable or you'll lock yourself out. If you changed SSH to a non-standard port (you should!), allow that port number instead of the word "ssh".

Step 3: Configure the Homelab Gateway Peer

On the Linux machine in your home network that will act as the gateway — this could be a Raspberry Pi, a mini PC, or even a VM — install WireGuard and generate its key pair:

sudo apt update && sudo apt install -y wireguard

wg genkey | sudo tee /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key
sudo chmod 600 /etc/wireguard/private.key

# Enable IP forwarding so it can route for the rest of your LAN
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Copy the public key output back to your VPS and paste it as HOMELAB_PUBLIC_KEY in wg0.conf, then reload with sudo wg syncconf wg0 <(sudo wg-quick strip wg0).

Now create the homelab peer config. Replace VPS_PUBLIC_IP with your actual VPS IP address, and VPS_PUBLIC_KEY with the content of /etc/wireguard/public.key on the VPS:

sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.10.0.2/24
PrivateKey = <HOMELAB_PRIVATE_KEY>

# Route traffic for the home LAN back inbound from the tunnel
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

[Peer]
PublicKey = <VPS_PUBLIC_KEY>
Endpoint = <VPS_PUBLIC_IP>:51820
AllowedIPs = 10.10.0.0/24
PersistentKeepalive = 25

The PersistentKeepalive = 25 line is important here. Because your homelab sits behind NAT, the VPS can't initiate the connection — the homelab must keep the tunnel alive with keepalive packets every 25 seconds. Without this, the tunnel will silently drop when there's no traffic.

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

Step 4: Add Your Road Warrior Peer (Laptop or Phone)

For any remote device — laptop, phone, whatever — the process is the same: generate a key pair on that device (or use the WireGuard app's built-in generator on mobile), then add the public key as a peer on the VPS.

The client config for your laptop looks like this:

[Interface]
Address = 10.10.0.3/32
PrivateKey = <LAPTOP_PRIVATE_KEY>
DNS = 10.10.0.1

[Peer]
PublicKey = <VPS_PUBLIC_KEY>
Endpoint = <VPS_PUBLIC_IP>:51820
# Only route homelab traffic through tunnel — true split tunneling
AllowedIPs = 10.10.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25

Notice the AllowedIPs here: 10.10.0.0/24 covers the tunnel itself, and 192.168.1.0/24 covers your home LAN. All other traffic — YouTube, Spotify, your work VPN — goes directly out your laptop's normal connection. This is real split tunneling, and it's one of the things I prefer about self-managed WireGuard over solutions like Tailscale where you need to think harder about exit nodes.

Step 5: Verify the Tunnel

After both peers are up, check the handshake status on the VPS:

sudo wg show

You should see both peers listed with a recent "latest handshake" timestamp and data transfer numbers. If a peer shows no handshake, double-check the public keys match exactly and that UDP 51820 is open on your VPS firewall.

From your laptop, try pinging the homelab gateway through the tunnel:

ping 10.10.0.2        # VPN tunnel address of homelab gateway
ping 192.168.1.100    # A device on your actual home LAN

If the first ping works but the second doesn't, the issue is almost always either IP forwarding not enabled on the homelab gateway, or the iptables MASQUERADE rule not applying. Re-run sudo sysctl net.ipv4.ip_forward on the homelab machine and confirm it returns 1.

Tip: Want to manage your WireGuard peers with a web UI instead of editing config files? Check out wg-easy — it's a Docker container that wraps WireGuard in a clean browser interface, including QR code generation for mobile clients. Run it on the VPS alongside your WireGuard setup.

Why I Prefer This Approach Over Tailscale or Cloudflare Tunnels

I've used Tailscale and I still recommend it for people who want zero configuration. But for a homelab where I want full control — custom subnets, no third-party coordination servers, deterministic routing — self-hosted WireGuard wins. I know exactly what's happening at every hop. There are no relay servers I don't control, no accounts that could be suspended, and no magic DNS that breaks when the Tailscale coordination server has a hiccup.

The VPS cost is essentially nothing. DigitalOcean Droplets give you dependable uptime with a 99.99% SLA and predictable monthly pricing — the $6/month AMD Droplet has handled my WireGuard hub for over a year without a single issue, and WireGuard is so lightweight it barely registers in the CPU graphs.

Next Steps

With this tunnel running, your homelab is now reachable from anywhere over an encrypted, authenticated channel. A few things I'd do next: first, set up a reverse proxy like Caddy on the homelab gateway so you can reach services by hostname rather than IP and port. Second, add fail2ban on the VPS to catch any SSH brute-force attempts — the WireGuard port is safe since it drops unauthenticated packets at the crypto layer, but your SSH port is still exposed. Finally, consider automating key rotation with a simple cron job that regenerates peer keys quarterly and updates configs via Ansible — that's a bit beyond this tutorial, but it's worth the investment if this tunnel carries anything sensitive.

Discussion