The Tunnel Home: Reaching Your Homelab from Anywhere with WireGuard
A modern VPN that fits in a single config file

Contents
Picture the scene: you are on a train, you want to check a service running at home, and your options are to expose that service to the entire internet or to go without. For years the answer to this dilemma was a clunky VPN that took an afternoon to configure and never quite behaved on mobile. WireGuard changes the calculus completely. It is a modern virtual private network so lean that its entire configuration fits in a file you can read at a glance, fast enough that you forget it is there, and secure enough that it has been merged into the Linux kernel itself. This guide builds a WireGuard tunnel from scratch so you can reach your homelab from anywhere without exposing a single service to the open web.
Why Not Just Expose the Service
The temptation is always to forward a port and be done with it. Resist it. The moment a service listens on the public internet, it is found, often within minutes, by automated scanners that probe every address relentlessly. A single unpatched vulnerability, a weak password, or a misconfiguration in any one of those exposed services becomes a doorway into your network.
A VPN flips the model. Instead of poking individual holes for each service, you create one encrypted entry point that only authenticated peers can use. Once connected, you reach your internal services as though you were sitting at home, but to the outside world there is nothing to attack except the VPN itself, and WireGuard’s attack surface is famously tiny. Fewer doors, all of them strong, is the whole philosophy.
This pairs naturally with segmentation inside the network. A VPN gets you onto the network safely; how far you can then reach is a separate question, and the sensible answer is “not everywhere”. If you have already done the work of keeping your untrusted smart devices away from your NAS on their own VLAN, the tunnel can drop you into the trusted segment and no further. Defence in depth means the VPN is the outer wall, not the only wall — a compromised laptop that dials in should still not be able to wander into every corner of your home network.
WireGuard Versus OpenVPN
OpenVPN served us faithfully for two decades, but it shows its age. Its codebase is large, its configuration sprawling, and its performance modest because much of its work happens in user space. WireGuard was designed as a deliberate reaction to all of that.
The differences are stark in practice. WireGuard’s entire codebase is a few thousand lines, small enough to be audited in full, against OpenVPN’s hundreds of thousands. It runs in the Linux kernel, which makes it noticeably faster and lower-latency because packets never have to cross the kernel/user-space boundary the way OpenVPN’s do. It uses a fixed, modern set of cryptographic primitives rather than a sprawling menu of negotiable options, which removes whole categories of misconfiguration. And its roaming behaviour is seamless, so your phone moving between mobile data and Wi-Fi does not drop the tunnel. The one thing OpenVPN still does better is blend into hostile networks that block VPNs, but for reaching your own homelab, WireGuard wins comfortably.
That fixed cipher suite is worth naming, because it is the reason there is nothing to negotiate and nothing to get wrong. WireGuard uses ChaCha20-Poly1305 for authenticated encryption and Curve25519 for the key exchange, with BLAKE2s for hashing. You do not choose any of it, you cannot downgrade it, and there is no cipher-negotiation handshake for an attacker to attack. ChaCha20 is also faster than AES on hardware without dedicated AES acceleration — which is to say, on exactly the phones and low-power boards you are most likely to be connecting from. The “no options” design that feels limiting on paper is precisely what makes WireGuard hard to deploy insecurely.
The Core Concepts
WireGuard is built from a few simple ideas. Every participant, server or client, is called a peer, and each peer has a key pair: a private key it keeps secret and a public key it shares. A peer authenticates another by recognising its public key, exactly like SSH keys. There are no usernames or passwords in the protocol at all.
The other concept that trips people up is AllowedIPs. On a peer’s configuration, this serves two roles at once: it defines which source addresses are accepted from that peer, and it defines which destination addresses get routed through the tunnel to it. Get these right and everything flows; get them wrong and traffic silently vanishes. Keep that dual meaning in mind and WireGuard stops being mysterious.
Installing and Configuring the Server
On a Debian or Ubuntu server, install the tools:
| |
Generate the server’s key pair, keeping the private key readable only by root:
| |
Now create /etc/wireguard/wg0.conf. This defines the tunnel interface, gives the server an address inside a private VPN subnet, and listens on a UDP port:
| |
The server lives at 10.8.0.1, the first client will be 10.8.0.2, and the AllowedIPs of 10.8.0.2/32 tells the server that only that single address belongs to that peer.
Generating Keys and a Client Config
On the client, or on the server if you prefer to generate everything centrally, create a key pair the same way:
| |
Take the client’s public key and paste it into the server’s [Peer] block from the previous step. Then build the client’s own configuration file:
| |
Setting AllowedIPs = 0.0.0.0/0 routes all of the client’s traffic through the tunnel, which is the safest choice on untrusted networks. If you only want to reach your home subnet and leave normal browsing alone, set it to something like 10.8.0.0/24, 192.168.1.0/24 instead. The PersistentKeepalive line keeps the tunnel alive through home routers that would otherwise drop the connection.
IP Forwarding, Firewall, and NAT
For the server to pass traffic from VPN clients onward to the rest of your network or the internet, the Linux kernel must be allowed to forward packets, and outbound traffic must be translated. First enable forwarding permanently:
| |
Then add NAT and firewall rules. The tidiest approach is to put them directly in the WireGuard config so they apply and clean up automatically with the interface. Add these lines to the server’s [Interface] section, replacing eth0 with your real outbound interface:
| |
Finally, make sure your home router forwards UDP port 51820 to this server, and bring the tunnel up:
| |
The wg show command is your dashboard; it lists each peer and, once a client connects, the time of the latest handshake.
The Phone in Your Pocket
WireGuard’s mobile apps make client setup painless. Rather than typing a config on a tiny keyboard, install a QR-code tool on the server and render the client configuration as an image:
| |
A block of pixel art appears in your terminal. Open the official WireGuard app on the phone, choose to add a tunnel by scanning a QR code, point the camera at the screen, and the entire configuration imports in one go. Toggle the tunnel on and your phone is now, for all intents and purposes, on your home network.
When the Handshake Will Not Happen
Almost every problem reduces to a handshake that never completes, and there are only a few usual causes. If wg show reports no recent handshake, work through them in order rather than randomly, because random poking at a VPN wastes evenings:
- Confirm the port is actually forwarded. The router must forward UDP 51820 to the correct internal machine. This is the most common failure by a wide margin. Test from outside your network — a phone on mobile data, not Wi-Fi — because from inside, the forward rule is never exercised and everything looks deceptively fine.
- Check the
Endpoint. The client’sEndpointmust point at your real public IP, not a stale or private one. If your ISP hands you a dynamic address, it will change without warning; a domain kept current with dynamic DNS is far more reliable than a hard-coded number, and this is one of the sneakiest causes of a tunnel that “worked yesterday”. - Verify the keys, character for character. Each peer must hold the other’s public key, and a single wrong character breaks everything silently with no error. A classic mistake is pasting a private key where a public one belongs, or copying the key with a trailing space.
- Rule out a subnet collision. If both the network you are connecting from and your home network use
192.168.1.0/24, the routing has no way to tell them apart and traffic for home gets delivered to the café’s router instead. This is why picking an unusual home subnet is quietly sensible. - Check the firewall on the server itself. Beyond the router, the server’s own
ufw/iptablesmay be dropping the inbound UDP. Allow the port explicitly.
A useful diagnostic habit is to run sudo wg show on both ends and compare the “latest handshake” line. If the server sees a handshake but you have no connectivity, the tunnel is up and the problem is routing or AllowedIPs, not WireGuard. If the server sees no handshake at all, the packets are not arriving and the fault is upstream — port forward, endpoint, or firewall.
One behaviour that panics newcomers is not a fault at all: WireGuard is silent by design. It sends nothing until there is traffic, so a tunnel can sit for minutes showing no recent handshake and be perfectly healthy — it simply has nothing to say until you use it. The PersistentKeepalive = 25 line exists precisely to generate a heartbeat through stateful home routers that would otherwise forget the connection. If you want to know the tunnel is down rather than discovering it on a train, wire a simple reachability check into whatever alerting you already run — a self-hosted push-notification service is ideal for exactly this kind of “tell me when the thing I depend on stops answering” job.
The Door You Can Trust
WireGuard delivers something rare in security tooling: it is both stronger and simpler than what it replaces. A handful of keys, a config file you can hold in your head, and a single guarded entry point give you the freedom to reach your homelab from a train, a café, or the other side of the world without ever exposing your services to the scanners that prowl the internet. Set it up once, scan a QR code onto your phone, and the tunnel home is always quietly waiting.




