Ramblings of an aging IT geek
← Ramblings of an aging IT geek
networking

the day i stopped forwarding ports

Moving the whole homelab onto a Tailscale tailnet, ripping the forwarded ports off the router, and what ACLs, subnet routers and tailnet DNS actually buy you.

A bundle of network cables behind a rack

For years my homelab had a small, embarrassing list of ports forwarded through the home router. 443 for the reverse proxy. A high port for Wireguard. Another for the thing I told myself I would lock down properly later and never did. Every one of them was a tiny advertisement to the entire internet that something was listening here, please come and have a look.

This weekend I removed all of them. The router's port-forward table is now empty, the WAN-facing attack surface of my house is essentially nothing, and I can still reach every service I care about from my phone on mobile data. The thing that made that possible is Tailscale, and having lived with it for a fortnight, I am genuinely a convert.

What changed, concretely

Tailscale is Wireguard with the painful part removed. The painful part of Wireguard was never the tunnel; it was the key distribution, the endpoint discovery, and the NAT traversal. Tailscale's coordination server does all of that for you, hands each device an address in the 100.64.0.0/10 range, and gets out of the way. The actual traffic is still Wireguard, peer to peer where it can be, and you are not trusting their servers with your packets.

I installed it on the gateway box, my laptop, my phone, and the NAS. Four tailscale up commands and an SSO login each, and suddenly every one of those devices could see every other one by name, regardless of which network they were on. No forwarded ports. No dynamic DNS. No coffee-shop firewall caring, because it is all outbound 443 and UDP as far as the local network is concerned.

A datacentre aisle with networking gear

Subnet routers, so I didn't have to install it everywhere

The catch with a mesh VPN is that you want the agent on every device, and some devices won't take one. My smart plugs, the printer, an old NAS that runs an OS frozen in time: none of those will ever run Tailscale.

The answer is a subnet router. You pick one box on the LAN, in my case the gateway, and tell it to advertise the local subnet into the tailnet:

tailscale up --advertise-routes=192.168.1.0/24 --accept-routes

Approve the route in the admin console, and now anything on the tailnet can reach the dumb devices on my home LAN through that one node, as if they had joined the mesh themselves. The printer thinks it is on the home network. My phone, three hundred miles away, thinks so too. Both are right, in the way that matters.

One thing worth getting right: enable IP forwarding on the subnet router or the routes advertise but nothing actually passes. net.ipv4.ip_forward=1 in sysctl, and the equivalent for v6 if you care. The CLI warns you about this now, which it did not always, and I have definitely lost an evening to it in the past.

ACLs, where the actual security lives

Removing the forwarded ports is only half the win. The other half is that a flat mesh where everything can reach everything is its own kind of bad idea. Tailscale's ACLs are a JSON policy file in the admin console, and they default-deny once you start writing them, which is the right default.

{
  "acls": [
    { "action": "accept", "src": ["group:admins"], "dst": ["*:*"] },
    { "action": "accept", "src": ["tag:phone"], "dst": ["tag:server:443,22"] }
  ],
  "tagOwners": {
    "tag:server": ["group:admins"],
    "tag:phone": ["group:admins"]
  }
}

My phone can reach the servers on 443 and 22 and nothing else. The servers cannot initiate connections back to my laptop. The dumb LAN devices, reachable only through the subnet router, are gated by the same rules. It is the segmentation I always meant to build with VLANs and never finished, except this one took twenty minutes and reads like a sentence.

A close-up of a patch panel

MagicDNS, the small thing that changes the daily experience

The feature I underrated completely is MagicDNS. Turn it on and every device is reachable by its short name, so ssh nas just works from anywhere, no hosts file, no remembering the 100.x address. It quietly rewires how you think about the network, because the distinction between "at home" and "out" stops mattering. The NAS is nas. It is always nas. Where I happen to be standing is no longer part of the address.

The honest caveats

It is not all free. The coordination server is theirs, and whilst the data plane is end-to-end encrypted Wireguard, your device metadata and the right to mint keys live with Tailscale. For a homelab I am comfortable with that trade; if I were not, Headscale is an open-source control server that speaks the same protocol, and it is on my list for a rainy weekend.

The other caveat is that this is a single sign-on dependency. If my identity provider has a bad day, my ability to add a new device has a bad day too. The existing tunnels keep working, so it is not catastrophic, but it is a thing to know rather than discover.

None of that outweighs the result. The router has no forwarded ports. The services are all still there. And the next time I read about some IoT botnet sweeping the internet for exposed admin panels, it will not be sweeping mine, because there is nothing on the doormat to find.