← Projects
raspberry-pi intermediate Jul 15, 2026 ◯ 4 min read

Build a WireGuard VPN Server on a Raspberry Pi: Secure Remote Access to Your Home Network

Build time: 2-3 hours
Tools needed: None required
Parts List
raspberry piwireguardvpnnetworkingremote accesssecurityself hosting

Running your own VPN server on a Raspberry Pi gives you secure access back to your home network from anywhere — browsing safely on public WiFi, reaching your home file server or security cameras remotely, or routing traffic through your home connection. WireGuard is the modern choice for this: dramatically simpler to configure than OpenVPN, faster, and with a much smaller attack surface due to its minimal codebase.

Why WireGuard Over OpenVPN

WireGuardOpenVPN Configuration complexityMinimal — a handful of config lines per peerSignificantly more complex, certificate management PerformanceGenerally faster, lower overheadMore overhead, especially on low-power hardware like a Pi Codebase size~4,000 lines, easier to audit~100,000+ lines CompatibilityNative or near-native support on all modern OSesUniversally supported, more mature ecosystem of edge-case features

For a straightforward "access my home network securely" use case, WireGuard's simplicity is a genuine advantage — less config surface means fewer places to make a mistake.

What You'll Need

Installation

  1. Update your system first: sudo apt update && sudo apt upgrade
  2. Install WireGuard: sudo apt install wireguard
  3. Generate a key pair for the server: wg genkey | tee privatekey | wg pubkey > publickey — this creates both files in your current directory; keep the private key secret

Server Configuration

Create /etc/wireguard/wg0.conf with your server's interface configuration:

[Interface] PrivateKey = <your server private key> Address = 10.0.0.1/24 ListenPort = 51820 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] PublicKey = <client public key, added per device> AllowedIPs = 10.0.0.2/32

The PostUp/PostDown lines enable routing traffic from VPN clients out through your Pi's normal internet connection — needed if you want VPN clients to route all their traffic through home, not just reach your home network. Adjust eth0 to match your Pi's actual interface name if it's using WiFi instead (typically wlan0).

Enable IP Forwarding

Uncomment or add this line in /etc/sysctl.conf:

net.ipv4.ip_forward=1

Apply it immediately without a reboot: sudo sysctl -p

Client Configuration

For each device you want to connect (phone, laptop, etc.), generate its own key pair and create a client config:

[Interface] PrivateKey = <client private key> Address = 10.0.0.2/24 DNS = 1.1.1.1 [Peer] PublicKey = <server public key> Endpoint = your-dynamic-dns-address.com:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25

Set AllowedIPs to 0.0.0.0/0 to route all client traffic through the VPN (full tunnel — good for public WiFi security), or to just your home subnet (e.g. 192.168.1.0/24) if you only want access to home devices without routing all internet traffic through home.

Add each client's public key as a new [Peer] block back in the server's wg0.conf.

Router Configuration

Forward UDP port 51820 (or whatever port you chose) on your router to your Pi's local IP address. Set up dynamic DNS if you don't have a static IP — most routers support this natively for common providers, or you can run a small client on the Pi itself to keep a DNS record updated with your current public IP.

Starting the Service

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

The second command makes it start automatically on boot — important for a headless Pi that might reboot after a power outage while you're away.

Testing and Troubleshooting

SymptomLikely Cause Client can't connect at allPort forwarding misconfigured, or firewall blocking UDP 51820 — verify with an external port checker Connects but no internet/network access through itIP forwarding not enabled, or PostUp/PostDown iptables rules referencing the wrong interface name Connects intermittently, drops after inactivityNAT timeout on your router — PersistentKeepalive in the client config (set to 25 above) should prevent this by sending periodic keepalive packets Works on local network, fails from outsideAlmost always a router port-forward or dynamic DNS issue, not a WireGuard config problem

A Few Security Notes

Once it's running, connecting is just flipping the VPN toggle on your phone or laptop — the actual day-to-day use is completely invisible after setup, which is exactly what you want from infrastructure like this.