Setting Up WireGuard VPN to Access Your Home Lab Remotely
You've built a home lab with a NAS, some services, maybe a few Raspberry Pis. It works great when you're home. But the moment you step outside your front door, you can't reach any of it. That's where WireGuard comes in.
WireGuard is a modern VPN protocol that's fast, simple, and built into the Linux kernel. Compared to OpenVPN, it has less code (around 4,000 lines vs 100,000+), faster connection times (it feels instant), and better performance. It's what you should be using in 2026 for homelab remote access.
This guide sets up WireGuard on a Linux server in your homelab so you can access your internal network from anywhere — your phone, laptop, a coffee shop, a hotel.
How WireGuard Works (Briefly)
WireGuard creates a point-to-point encrypted tunnel between peers. Each peer has a public/private key pair. There's no concept of "client" and "server" in the protocol itself — it's peer-to-peer. But in practice, you'll configure one peer as the "server" (always-on, at home) and others as "clients" (your mobile devices).
Traffic flows through a virtual network interface (wg0) on each peer. You assign each peer an IP address in a private subnet (like 10.0.0.0/24), and WireGuard handles encryption and routing transparently.
Prerequisites
You need:
- A Linux machine in your homelab that stays on. Anything works — a Pi, a VM, your main server. This guide uses Ubuntu/Debian commands, but WireGuard runs on every major distro.
- A public IP address or dynamic DNS. Your clients need to reach your home network from the internet. If your ISP gives you a dynamic IP, set up a DDNS service like DuckDNS or use your router's built-in DDNS.
- Port forwarding access on your router. You'll need to forward one UDP port.
Server Setup
Install WireGuard
On Ubuntu/Debian:
sudo apt update
sudo apt install wireguard
On Fedora:
sudo dnf install wireguard-tools
On Arch:
sudo pacman -S wireguard-tools
Generate Server Keys
# Generate private and public key pair
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
# Lock down the private key
chmod 600 /etc/wireguard/server_private.key
Note the contents of both files — you'll need them for the config:
cat /etc/wireguard/server_private.key
cat /etc/wireguard/server_public.key
Create Server Configuration
Create /etc/wireguard/wg0.conf:
[Interface]
# Server's private key
PrivateKey = <server_private_key>
# VPN subnet address for the server
Address = 10.0.0.1/24
# UDP port to listen on
ListenPort = 51820
# Enable IP forwarding and NAT when the interface comes up
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
# Peer entries will go here (added later)
Replace eth0 with your server's actual network interface name. Check with ip addr — it might be ens18, enp0s3, or something similar.
Enable IP Forwarding
WireGuard needs the server to forward packets between the VPN tunnel and your LAN:
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
Verify:
cat /proc/sys/net/ipv4/ip_forward
# Should output: 1
Configure Your Router
Forward UDP port 51820 to your WireGuard server's LAN IP. The exact steps depend on your router, but you're looking for "Port Forwarding" in the router's admin interface:
- Protocol: UDP
- External port: 51820
- Internal IP: your server's LAN IP (e.g., 192.168.1.100)
- Internal port: 51820
If you're behind CGNAT (common with some ISPs), port forwarding won't work. In that case, look into Tailscale (covered in a separate article) or a cloud relay.
Client Setup
Generate Client Keys
On the server (or on the client machine — doesn't matter where you generate them):
wg genkey | tee client1_private.key | wg pubkey > client1_public.key
Add Client as Peer on Server
Edit /etc/wireguard/wg0.conf and add a [Peer] section:
[Peer]
# Client's public key
PublicKey = <client1_public_key>
# Client's VPN IP
AllowedIPs = 10.0.0.2/32
Create Client Configuration
Create a file called client1.conf:
[Interface]
PrivateKey = <client1_private_key>
Address = 10.0.0.2/24
DNS = 10.0.0.1 # Or your Pi-hole address
[Peer]
PublicKey = <server_public_key>
Endpoint = your-home-ip.duckdns.org:51820
AllowedIPs = 0.0.0.0/0 # Route ALL traffic through VPN
PersistentKeepalive = 25
Endpoint is your home's public IP or DDNS hostname plus the WireGuard port.
PersistentKeepalive sends a packet every 25 seconds to keep the connection alive through NAT. Essential for mobile devices.
Transfer Config to Client
The simplest method — generate a QR code:
sudo apt install qrencode
qrencode -t ansiutf8 < client1.conf
Open the WireGuard app on your phone and scan the QR code. Done.
For laptops, install WireGuard and copy the config file:
# Linux
sudo cp client1.conf /etc/wireguard/wg0.conf
sudo wg-quick up wg0
# macOS/Windows
# Import the .conf file through the WireGuard GUI app
Start WireGuard
On the server:
# Start the tunnel
sudo wg-quick up wg0
# Enable on boot
sudo systemctl enable wg-quick@wg0
Verify it's running:
sudo wg show
You should see the interface details and any connected peers.
Split Tunneling
The config above routes ALL client traffic through your home VPN. This is good for security on public WiFi, but it means streaming Netflix routes through your home connection, which adds latency and uses your upload bandwidth.
Split tunneling routes only homelab traffic through the VPN, while everything else goes directly to the internet.
Change the AllowedIPs line in your client config:
# Instead of routing everything:
# AllowedIPs = 0.0.0.0/0
# Route only your home LAN and VPN subnet:
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
Now only traffic destined for 10.0.0.x (VPN peers) or 192.168.1.x (your home LAN) goes through the tunnel. Everything else takes the normal path.
You can also add specific IP ranges for services:
# Home LAN + VPN subnet + your office network
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24, 172.16.0.0/16
DNS Configuration
Using Pi-hole Through the VPN
If you run Pi-hole, point your VPN clients at it for ad blocking even when you're away. Set the DNS line in your client config:
DNS = 192.168.1.53 # Pi-hole's LAN IP
Or, if Pi-hole is also a WireGuard peer:
DNS = 10.0.0.53 # Pi-hole's VPN IP
Avoiding DNS Leaks
With full tunnel (AllowedIPs = 0.0.0.0/0), all DNS goes through the VPN automatically. With split tunnel, only add a DNS server if it's within the AllowedIPs ranges. Otherwise, your DNS queries will bypass the tunnel and resolve locally, which is usually fine for split tunnel but worth understanding.
Adding More Clients
For each new client, repeat the process:
- Generate a key pair
- Add a
[Peer]block to the server config with a unique IP (10.0.0.3, 10.0.0.4, etc.) - Create a client config file
- Reload the server config:
sudo wg syncconf wg0 <(wg-quick strip wg0)
The syncconf command updates peers without taking the tunnel down — useful when you're connected remotely.
Troubleshooting
Can't connect from outside your network: Verify port forwarding is working. Test with nc -zvu your-public-ip 51820 from an external machine. Check your router's firewall rules.
Connected but can't reach LAN devices: IP forwarding isn't enabled, or the iptables NAT rule isn't working. Check cat /proc/sys/net/ipv4/ip_forward and sudo iptables -t nat -L.
Slow speeds: WireGuard itself is fast. The bottleneck is usually your home upload speed. Test with iperf3 between the client and server to see actual tunnel throughput.
Connection drops on mobile: Make sure PersistentKeepalive = 25 is set in the client config. Without it, NAT mappings expire and the tunnel goes silent.
DNS not working through the tunnel: If using split tunnel, make sure the DNS server IP is included in AllowedIPs. WireGuard won't route DNS traffic to a server that isn't in the allowed range.
Security Considerations
WireGuard is cryptographically sound — it uses Curve25519 for key exchange, ChaCha20 for encryption, and Poly1305 for authentication. There's not much to misconfigure on the crypto side.
The main security concern is protecting your private keys. The server's private key at /etc/wireguard/server_private.key should be readable only by root (chmod 600). Don't store client private keys on the server after transferring them.
Also consider:
- Fail2ban won't help — WireGuard silently drops packets from unknown peers. There's nothing to brute force. An attacker without a valid key pair can't even determine that WireGuard is running.
- Keep your system updated — WireGuard is in the kernel, so kernel updates include WireGuard fixes.
- Rotate keys periodically — Not strictly necessary, but good hygiene. Generate new key pairs yearly and update configs.
WireGuard gives you fast, reliable remote access to your homelab with minimal overhead. The entire server config is a dozen lines long, the tunnel establishes in milliseconds, and the performance is close to bare metal. For most homelabbers, it's the right VPN choice.