Headscale Funnel vs Tailscale Funnel: Exposing a Homelab Without Opening 443

Julian Park

Julian Park

September 18, 2026

Headscale Funnel vs Tailscale Funnel: Exposing a Homelab Without Opening 443

I wanted a friend to open Immich for a weekend without a Tailscale install and without a port-forward on a CGNAT fiber jack. Tailscale Funnel did it in a command: a *.ts.net URL, TLS I did not request from Let’s Encrypt, traffic that never touched my router’s 443. I wanted the same trick on the house that runs Headscale. That is where people say “Headscale Funnel” as if it were the same product with a different logo. It is not.

Tailscale Funnel is a public ingress Tailscale Inc. operates. Headscale can expose a node to the world only with a public hop you own — their growing serve/funnel bits, a VPS, Cloudflare Tunnel, or a Caddy on a cheap VPS that already has 443. The house still does not open 443. Someone else’s 443 opens instead. The argument is whose.

What Tailscale Funnel actually is

Funnel is not Serve. Serve shares a port with the tailnet. Funnel publishes a hostname on Tailscale’s funnel infrastructure so a browser with no tailnet client can hit your node. The path is: public user → Tailscale funnel edge → WireGuard to your node → localhost. Your ISP sees a Tailscale connection, not an inbound 443 from the friend. The friend sees a ts.net name and a certificate Tailscale minted.

I have used it for a weekend photo dump and for a webhook I was too lazy to put on a VPS. I have also left it on for a month, which is how a homelab becomes a public app with an ACL I wrote when I was tired. Funnel has knobs. I still treat a Funnel URL like a port-forward I will forget exists, because it is one.

Limits I have hit: the node must be online, Funnel is a feature of Tailscale’s control plane and their edge, and the name is in their DNS. If Tailscale is sad, the friend is sad. If I turn the Mini PC off, the friend is sad. That is the same as a house 443, minus the CGNAT fight.

Mini PC with a single ethernet cable on a desk

What Headscale can honestly say

Headscale is a control server you run. It coordinates who is allowed on the mesh. It does not, out of the box, give you a global anycast HTTPS edge that mints photos.yourname.ts.net for strangers. Clients that speak Tailscale’s protocol join your server. Public browsers do not.

Headscale’s serve/funnel work — depending on the version you actually run — still needs a place on the internet that will accept TCP 443 or at least a path from a stranger. That place is usually:

  • A VPS you already pay for, running Caddy or nginx, reverse-proxying into a subnet router or into a node that is on the headnet.
  • A Cloudflare Tunnel / similar, which is another company’s Funnel with a different TOS.
  • A Headscale-adjacent funnel helper if your release has one, pointed at a public IP you control, not at a magic ts.net zone you do not.

I have run the VPS pattern for two years. The house never opened 443. The VPS did. Headscale told the VPS and the Mini PC they were allowed to talk. Caddy on the VPS held the Let’s Encrypt name photos.example.net. Friends typed a real domain. I rotated the Caddyfile when I wanted the hole closed. That is Funnel-shaped. It is not Tailscale Funnel. I am the edge.

If your Headscale version advertises Funnel, read what hostname it binds and whose IP answers. If the answer is the VPS you already have, you did not escape the VPS. You automated it. If the answer is “we still need you to publish 443 somewhere,” you have Serve with extra steps.

CGNAT is why either Funnel exists

The title is “without opening 443.” On Starlink and a lot of apartment fiber, you cannot open 443 even if you want to. Funnel and a VPS are the same political move: inbound lives elsewhere. Tailscale Funnel is the inbound you do not maintain. The VPS is the inbound you reboot when a cert fails at 3 a.m.

I keep relatives on paid Tailscale because they will not install a custom control-server URL. Funnel on that account is how I send a one-off link. The house Headscale net stays for machines I own. Mixing “please open this Funnel” with “please join my Headscale” is two onboarding lectures. I pick one lecture per human.

Apartment fiber terminal near a closed closet door

Abuse, logs, and who can see the bytes

Tailscale Funnel: Tailscale can see that a public session hit your funnel hostname. They encrypt to the node. I am not going to pretend I have their internal packet notes. I am going to say I am trusting a company with a public ingress, the same way I trust Cloudflare Tunnel. The friend is not on my tailnet. The ACL that matters is Funnel’s, not only the tailnet ACL.

Headscale plus my VPS: I see the Caddy logs. I see fail2ban if I bothered. I do not see Tailscale’s funnel dashboard because there is not one. I can drop the Caddy site without waiting on a SaaS flag. I can also misconfigure Caddy and expose Portainer to the world, which Funnel’s narrower “this port only” command makes slightly harder to do by accident. Slightly. I have still exposed the wrong localhost port with Funnel. The blast radius was one command I forgot to disable.

Neither path is “anonymous hosting.” DNS exists. Certificates exist. If the content is a family photo library, I use a password on Immich and I turn the hole off on Monday. If the content is a webhook, I use a secret path and I still turn it off.

Serve is the thing people want more often

If the friend can install Tailscale — or already has it — you do not need Funnel. You need an ACL and maybe Serve. I send more invite links than Funnel URLs. Funnel is for the person who will not install a client, the webhook sender who cannot run WireGuard, or the demo that has to work from a school laptop with a policy.

Headscale users already asked their humans to use a weird login URL. Asking them to install the client is the same conversation. Funnel is less necessary on a headnet of people you already trained. It is more necessary when you want a stranger and you already refused Tailscale Inc.

That is the control-plane fork in another costume. If you left Tailscale because you did not want their coordination server, using their Funnel for the public piece is a coherent hybrid — I have done it: Headscale for the house, paid Tailscale + Funnel on one throwaway node. It is also two meshes to explain. I only keep the hybrid when a relative is on the paid net anyway.

ACLs that look like a port-forward

Tailscale Funnel has its own allow list. I have Funnel-opened a port I thought was bound only to localhost and discovered the process was listening on 0.0.0.0. The Funnel did its job. The process did not. Headscale plus Caddy has the same footgun with a prettier hostname. I check ss -lntp on the node before I publish. I also check that Immich’s bind is the one I meant, not the metrics port next door.

On Headscale I still write ACLs as if Funnel did not exist, because most of the net should not be public even when one node is. A funnel on node A does not change tag:server on node B unless I make it. I have made it, once, with a too-wide group. The VPS was innocent.

A setup I will defend

House nodes: Headscale. No Funnel fantasy on the Mini PC. Public photos for a weekend: either a Caddy site on a $5 VPS that is already a subnet/exit I understand, or a Funnel on a single Tailscale node I turn off after. I do not Funnel the NAS. I do not Funnel Portainer. I do not Funnel Home Assistant without another password and a calendar reminder.

DNS: my domain on the VPS path. ts.net on the Tailscale path. I do not try to make Headscale mint ts.net names. I do not try to make Tailscale Funnel look like my domain without their docs and a day I do not have. Friends will click either. I will remember only one of them exists next month if I wrote it down.

Trade-offs

Tailscale Funnel is the fastest way to not open 443 and not run a VPS. You pay with their edge, their name, their outage, and a feature flag. Headscale Funnel, in the sense people mean it, is “I already have a public IP somewhere.” You pay with Caddy, certs, and the honesty that you are the CDN.

If you have no VPS and no Tailscale account, you do not have Funnel. You have a dream of 443 on a CGNAT. Buy one of the two hops. I buy the VPS for things that should stay up, and I borrow Tailscale Funnel for things that should die on Monday. Opening 443 on the apartment jack is the third option I still do not have.

The house stays closed. The question is only which lobby you staff.

More articles for you