guides

Stop forwarding ports: remote access to your homelab without exposing it

Most of what we write here ends the same way: don’t forward that port, use a VPN instead. We’ve said it about NAS boxes, about firewalls, and about the 49,000 Plex servers that got caught with a ten-week-old patch available.

We’ve never explained how. This is that guide.

A network switch rack with tangled cables
Photo: cell105, CC BY 2.0.

What’s actually wrong with port forwarding

Forwarding a port doesn’t “let you in from outside”. It lets everyone in from outside, and then relies on that one service’s login to sort out who’s allowed.

That’s the whole bet. The service has to be correctly configured, fully patched, and free of pre-authentication bugs, continuously, forever. Every incident we’ve covered this year failed on the third one. The Plex chain, the GitLab regex bugs, the PHP RCEs: all pre-auth, so the login you were relying on never got consulted.

Scanning for open ports is also free and constant. Nobody has to find you interesting. Shadowserver had 49,000 exposed Plex hosts catalogued before the exploit went public, which is how we know how many there were.

A VPN changes the shape of the problem. Instead of a service exposed to everyone and defended by a password, you have one tunnel exposed to people holding a key, and everything behind it is on a private network again.

The three approaches

Tailscale is a managed control plane on top of WireGuard. The tunnels are real WireGuard; what Tailscale adds is key distribution and peer discovery, which is the genuinely annoying part. It works behind CGNAT without forwarding anything.

Self-hosted WireGuard is the same tunnel without the middleman. No external dependency, full control, and you do the key management and usually need one inbound port open on your router.

Cloudflare Tunnel exposes specific HTTP services publicly without opening ports. Different tool for a different job: it’s for things you want strangers to reach, not for getting yourself onto your own network.

For most people reading this, Tailscale is the right default and the rest of this guide uses it. The honest tradeoff is at the bottom.

Setting it up

Install it on the machine you want to reach and the machine you’re reaching from, sign in with the same account on both, and that’s the working case. Fifteen minutes against roughly an hour for self-hosted WireGuard, mostly because you skip generating and distributing keys.

The two features that actually matter for a homelab are the ones people skip.

Subnet router: reach things that can’t run Tailscale

Your NAS might run it. Your printer, your IoT gear, your switch’s web interface and your ISP router won’t.

A subnet router is one machine on your LAN advertising the whole network to the rest of your tailnet. Anything on that subnet becomes reachable, whether or not it’s heard of Tailscale.

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

Swap in your actual subnet. Then approve the route in the admin console, because advertising is a request, not a grant. That approval step is the usual reason this appears not to work.

Put it on something that’s always on. A Pi, a NAS, a small always-up VM. Not your laptop.

Exit node: route everything through home

sudo tailscale up --advertise-exit-node

Approve it the same way, then pick it on a client to send all traffic through that machine. Useful on hotel and café Wi-Fi.

Be clear about what it does. It protects traffic between you and your exit, and it makes you appear to come from home. It is not anonymity: the exit node’s operator and ISP are still part of the picture, and when that’s your own house, they’re you and your own ISP. Which is the point, but worth stating.

What it costs

The free Personal plan covers up to 6 users with unlimited devices, 50 tagged resources and 3 ACL groups. It’s non-commercial use only.

Older comparisons claiming a three-device free limit are out of date, and that figure is still repeated in a lot of blog posts. Paid plans start at $8 per user per month.

For a household this is comfortably inside the free tier and likely to stay there.

The tradeoff we should state plainly

Tailscale’s control plane is a service someone else runs. Your traffic doesn’t flow through it, the tunnels are direct WireGuard, but coordination and device authorisation do depend on it. If that company changes its terms, its pricing or its mind, you’re affected.

That should sound familiar. It’s the same dependency we spend this site arguing against with media servers and photo storage.

The reason we still recommend it: the alternative isn’t self-hosted WireGuard for most people, it’s a forwarded port. A managed control plane you could migrate off is a dramatically better position than a service listening on a public address with a pre-auth bug you haven’t heard about yet.

If you want no third party at all, self-hosted WireGuard is genuinely the better answer and the extra hour is the whole cost. That’s the right call if you’re already comfortable with keys and firewall rules, or if this is protecting something where an outside dependency isn’t acceptable.

A common middle path: WireGuard on the router for your own devices, Tailscale on a NAS as a subnet router for everything else.

Once it’s working

Go close the ports. The VPN doesn’t help while the old forward is still there, and a surprising number of setups end up with both because nobody went back to undo the first one.

Check from outside your network: your phone on mobile data, Tailscale off, trying to reach whatever used to be forwarded. If it answers, the forward is still live.

Then do it once a year, because routers acquire port forwards the way drawers acquire cables.

Sources: Tailscale’s current pricing and plan limits, Tailscale’s own comparison with WireGuard, which is worth reading knowing who wrote it.

Leave a comment

Your email address will not be published. Required fields are marked *