$ Building a WireGuard Mesh for My Homelab
I replaced a hub-and-spoke OpenVPN setup with a full mesh of WireGuard peers. Latency dropped, complexity dropped, and I finally understand why everyone moved.
WireGuard collapsed an entire layer of YAML config into ~10 lines per peer. After a year of running it across 4 sites, here's what I'd tell my past self.
Why mesh, not hub-and-spoke
A hub means every cross-site packet does a round trip through one node. With three sites that's fine. With seven it's painful.
A full mesh means each peer knows every other peer directly. WireGuard's stateless UDP makes this cheap — no persistent connections to manage.
The minimal config
[Interface]
PrivateKey = <yours>
Address = 10.20.0.1/24
ListenPort = 51820
[Peer]
PublicKey = <theirs>
AllowedIPs = 10.20.0.2/32
Endpoint = peer.example.com:51820
PersistentKeepalive = 25
That's it. No certificates, no PKI, no easy-rsa ritual.
The trick: AllowedIPs is routing
This is the part everyone trips on. AllowedIPs is both an ACL and a route. Whatever IPs you list there get pushed into the kernel routing table pointing at this peer. That's how you build the mesh — each peer's AllowedIPs defines the slice of the mesh it owns.
What I'd skip
Don't bother with wg-quick for production. Use systemd-networkd natively — it survives reboots cleanly and integrates with networkctl.