The mesh
A WireGuard network connecting two houses and a rented server. I set it up to get around CGNAT and it now carries the services my family uses. Each home has a node acting as its gateway, so devices on those networks reach the rest without any setup of their own.
Why it exists
I had been eyeing the idea of selfhosting my own services at home instead of relying on the cloud; during the 2020 lockdown I decided to pull the trigger, but my ISP at the time had me behind CGNAT, which meant no public address and no way to reach anything at home from outside it. I set up WireGuard to get back in.
What started as a workaround later got extended to be able to access my family’s network for impromptu IT support, and in turn family access to my services.
How it’s routed
Each home has one node acting as its gateway into the mesh. That node has IP
forwarding enabled, its AllowedIPs covers the other site’s range, and the router
hands it anything destined for the far side.
The consequence is the part I care about: no device on either network needs any configuration at all. My mother’s laptop reaches a machine in another house the same way it reaches her own printer. There is no client to install, no tunnel to remember to switch on, nothing to explain over the phone. She does not know a VPN exists, which is the correct amount for her to know.
The rented server is the third node, and it holds the only stable public address in the system. Traffic between the two houses normally goes through it. That is not the only path available, though: the two homes also hold a direct WireGuard peering with each other, which carries their traffic if the rented server is unreachable. The link between the houses does not depend on a third party staying up.
How names resolve
There is no clever DNS here, and the absence is deliberate. Every service has a public name that resolves to the rented server, and the reverse proxy there forwards each name onward to the right container over the tunnel. One place holds the routing table, one place terminates TLS, one place gets a certificate.
The trade is that a request from inside a house still leaves the building, crosses to another country, and comes back. I haven’t felt the latency yet, however. If it became a problem I could always manually configure local IPs for the hosts files in the relevant machines.
The renumbering
Both home networks shipped on the same default subnet, which does not work: with identical ranges on both sides, a packet has no way to know which house you meant. I renumbered mine, on the grounds that I was better equipped to live with an unusual subnet than anyone else in the family was.
I picked the next obvious range, which was a mistake I got to discover twice. It collided with the corporate VPN at a job I started shortly afterwards, so with both connected, work resources and home resources were fighting over the same addresses. I renumbered a second time, to something less likely to overlap in the future.
Topology
- Gateway rented VPS
- reverse proxy
- this site
- personal data server
- notes
- status page
- Site A Proxmox mini PC
- single sign-on
- DNS filtering
- document archive
- family wishlist
- agent front-end
- Site B Proxmox tower, big storage
- file sync + office suite
- photo library
- Git forge
- ebook library
- RSS feed reader
- link archive
What runs on it
Most of it is not for me. Nextcloud with OnlyOffice attached is where the family’s documents live and get edited. Immich holds the photos. There’s a wishlist app that exists to make sure birthday and Christmas presents will always be well received.
There are three key ones, more important than the rest:
- Authentik provides single sign-on across everything, so there is one account and one password rather than one per service.
- A public status page, so when something is down my family can see that it is down without depending on me to inform them.
- A dashboard with links to everything, so nobody here needs to memorise each and every subdomain.
The rest is mine: a Git forge, a tangled.org knot server, and a personal data server.
How it’s managed
Every host runs a small agent that dials back to a management server and holds the connection open. The management server is reachable from inside the network and not from the internet. Container stacks are defined there rather than on the hosts, and pushed down to whichever machine should run them, so changing what a host runs does not mean opening a shell on it.
The placement decision
Storage-heavy services run at home, not on the VPS. Rented storage is expensive and the VPS has very little of it, so the photo library and the document store sit on hardware I already own. This is, of course, a trade-off.
Known gaps
Backup rotation is planned but not built. The intent is for each host to keep a compressed copy of the others, with the rented server excluded because it does not have the space. The layout was still moving until this year, and rebuilding a backup scheme against a design that keeps changing is wasted work; so that is the reason it was not done earlier.
There is path redundancy but no service redundancy. If the rented server drops, the houses still reach each other. If a house loses power, everything it hosts goes with it and nothing takes over. For a network whose users are my relatives, building the second kind costs more than occassionally being offline for an evening does.
Tools
- Network
- WireGuardIP forwardingNginx Proxy Managerdynamic DNSACME / DNS-01
- Hosts
- ProxmoxDebianLXCvirtualisation
- Services
- DockerDockhandHawserUptime Kuma
- Identity
- AuthentikOIDCLDAPforward auth