Plans to implement Funnel? #387

Closed
opened 2025-12-29 01:28:03 +01:00 by adam · 29 comments
Owner

Originally created by @julianfairfax on GitHub (Dec 3, 2022).

Feature request

Are there plans to implement support for tailscale's Funnel?

I can't actually use headscale, as the whole reason I'm using tailscale is that I can't do port forwarding, and thus, my running head scale server would be unreachable by all devices.

Using tailscale though, I find the Funnel useful, as I run a Nextcloud server, and want to share links to my files with people not on my tailnet.

It would thus be cool to have this feature in headscale, for those who can use it!

Originally created by @julianfairfax on GitHub (Dec 3, 2022). <!-- Headscale is a multinational community across the globe. Our common language is English. Please consider raising the feature request in this language. --> **Feature request** <!-- A clear and precise description of what new or changed feature you want. --> <!-- Please include the reason, why you would need the feature. E.g. what problem does it solve? Or which workflow is currently frustrating and will be improved by this? --> Are there plans to implement support for tailscale's Funnel? I can't actually use headscale, as the whole reason I'm using tailscale is that I can't do port forwarding, and thus, my running head scale server would be unreachable by all devices. Using tailscale though, I find the Funnel useful, as I run a Nextcloud server, and want to share links to my files with people not on my tailnet. It would thus be cool to have this feature in headscale, for those who can use it!
adam added the enhancement label 2025-12-29 01:28:03 +01:00
adam closed this issue 2025-12-29 01:28:03 +01:00
Author
Owner

@kradalby commented on GitHub (Dec 7, 2022):

We cannot really implement Tailscale's Funnel per se as it is not a public infrastructure like DERP. The way it works is roughly by setting up a connection between your node and the Tailscale Funnel ingress via your tailnet. This means that the tailnet must be hosted on tailscale.com.

In theory we could run our own "Headscale Funnel" infrastructure, but we have no capacity to do that.

or empower users to set this up themselves, but that still requires you to have a server with a public IP etc. For the record, this can already be done with a couple of lines of config and https://github.com/samhocevar/rinetd.

@kradalby commented on GitHub (Dec 7, 2022): We cannot really implement Tailscale's Funnel per se as it is not a public infrastructure like DERP. The way it works is roughly by setting up a connection between your node and the Tailscale Funnel ingress _via_ your tailnet. This means that the tailnet must be hosted on tailscale.com. In _theory_ we could run our own "Headscale Funnel" infrastructure, but we have no capacity to do that. or empower users to set this up themselves, but that still requires you to have a server with a public IP etc. For the record, this can already be done with a couple of lines of config and https://github.com/samhocevar/rinetd.
Author
Owner

@nikicat commented on GitHub (Aug 25, 2023):

If I understand correctly one of the main Funnel features is the automatic mapping of a subdomain to an exposed service with automatic certificate issuing (using letsencrypt for user-provided domain).
I would certainly use such a feature if Headscale implemented it.

@nikicat commented on GitHub (Aug 25, 2023): If I understand correctly one of the main Funnel features is the automatic mapping of a subdomain to an exposed service with automatic certificate issuing (using letsencrypt for user-provided domain). I would certainly use such a feature if Headscale implemented it.
Author
Owner

@rallisf1 commented on GitHub (Aug 26, 2023):

I guess it could be implemented via 3rd party services like ngrok. My favorite is cloudflare tunnel. It is free, cloudflared is open source and all you really need is a domain on cloudflare.

@rallisf1 commented on GitHub (Aug 26, 2023): I guess it could be implemented via 3rd party services like ngrok. My favorite is cloudflare tunnel. It is free, cloudflared is open source and all you really need is a domain on cloudflare.
Author
Owner

@nikicat commented on GitHub (Aug 27, 2023):

Yes, I want something like you mentioned @rallisf1 , but hosted on my own server, not a third-party service, that's why I'm actually using headscale instead of tailscale.

@nikicat commented on GitHub (Aug 27, 2023): Yes, I want something like you mentioned @rallisf1 , but hosted on my own server, not a third-party service, that's why I'm actually using headscale instead of tailscale.
Author
Owner

@rallisf1 commented on GitHub (Aug 28, 2023):

Yes, I want something like you mentioned @rallisf1 , but hosted on my own server, not a third-party service, that's why I'm actually using headscale instead of tailscale.

This would require a reverse proxy and a dns server. Reverse proxy is easy, I already run headscale behind caddy. You'd need some form of integration with headscale though to generate the config for the Funnels. The DNS server must be public facing, be set as the designated nameserver for the domain you own (different than the magicDNS domain) and also integrated with headscale. Most registrars require at least 2 nameservers though, plus it's hell of a lot easier to just use a 3rd party DNS service that provides an API, like cloudflare...

@rallisf1 commented on GitHub (Aug 28, 2023): > Yes, I want something like you mentioned @rallisf1 , but hosted on my own server, not a third-party service, that's why I'm actually using headscale instead of tailscale. This would require a reverse proxy and a dns server. Reverse proxy is easy, I already run headscale behind caddy. You'd need some form of integration with headscale though to generate the config for the Funnels. The DNS server must be public facing, be set as the designated nameserver for the domain you own (different than the magicDNS domain) and also integrated with headscale. Most registrars require at least 2 nameservers though, plus it's hell of a lot easier to just use a 3rd party DNS service that provides an API, like cloudflare...
Author
Owner

@nikicat commented on GitHub (Aug 28, 2023):

Reverse proxy, dns server, and a certificate manager (for https support) - all this should ideally be integrated into a single application. btw, the domain used for forwarding could be a 2nd level domain (or even deeper) so it should not be a problem to have only one NS for that.

@nikicat commented on GitHub (Aug 28, 2023): Reverse proxy, dns server, and a certificate manager (for https support) - all this should ideally be integrated into a single application. btw, the domain used for forwarding could be a 2nd level domain (or even deeper) so it should not be a problem to have only one NS for that.
Author
Owner

@rallisf1 commented on GitHub (Aug 28, 2023):

Reverse proxy, dns server, and a certificate manager (for https support) - all this should ideally be integrated into a single application.

I am strongly against this. There are battle tested open source packages that will do a better job than any 1st party implementation, plus I bet there is no capacity to even consider that. Integration, docs and a docker-compose.yml for the lazy is all that it takes.

btw, the domain used for forwarding could be a 2nd level domain (or even deeper) so it should not be a problem to have only one NS for that.

true but that means exposing your internal domains to the internet and frankly I'd never do that, even when they point to 100.x.x.x IPs.

@rallisf1 commented on GitHub (Aug 28, 2023): > Reverse proxy, dns server, and a certificate manager (for https support) - all this should ideally be integrated into a single application. I am strongly against this. There are battle tested open source packages that will do a better job than any 1st party implementation, plus I bet there is no capacity to even consider that. Integration, docs and a `docker-compose.yml` for the lazy is all that it takes. > btw, the domain used for forwarding could be a 2nd level domain (or even deeper) so it should not be a problem to have only one NS for that. true but that means exposing your internal domains to the internet and frankly I'd never do that, even when they point to 100.x.x.x IPs.
Author
Owner

@nikicat commented on GitHub (Aug 28, 2023):

I just partially understand and accept your opinion - using proven tools is a good way, but nevertheless, we need a manager program that will

  1. accept and store requests for exposing internal services
  2. create subdomain records in the dns server
  3. create a config section in the reverse proxy configuration
  4. issue a new certificate for the subdomain created
  5. monitor and keep updated all this stuff

It doesn't look like a trivial thing from my point of view.

@nikicat commented on GitHub (Aug 28, 2023): I just partially understand and accept your opinion - using proven tools is a good way, but nevertheless, we need a manager program that will 1. accept and store requests for exposing internal services 2. create subdomain records in the dns server 3. create a config section in the reverse proxy configuration 4. issue a new certificate for the subdomain created 5. monitor and keep updated all this stuff It doesn't look like a trivial thing from my point of view.
Author
Owner

@renne commented on GitHub (Dec 23, 2023):

I suggest to run Tailscale exit nodes on servers with public static IP-adresses.

For Funnel requests Headscale just needs to push the necessary DNAT rules for opening and forwarding ports to the Tailscale exit node.

Lego can be used by Headscale to configure the primary DNS-server of your domain provider.

That way one only needs to rent a small VPS (1 vCPU, 512 MB RAM, 1 GB storage) to run an "Funnel" gateway.

For security reasons I suggest to run the TLS-server on your application servers instead of the Tailscale exit node (in my opinion the Tailscale exit node is not a secure host because the server provider has access).

@renne commented on GitHub (Dec 23, 2023): I suggest to run Tailscale exit nodes on servers with public static IP-adresses. For Funnel requests Headscale just needs to push the necessary DNAT rules for opening and forwarding ports to the Tailscale exit node. [Lego](https://github.com/go-acme/lego) can be used by Headscale to configure the primary DNS-server of your domain provider. That way one only needs to rent a small VPS (1 vCPU, 512 MB RAM, 1 GB storage) to run an "Funnel" gateway. For security reasons I suggest to run the TLS-server on your application servers instead of the Tailscale exit node (in my opinion the Tailscale exit node is not a secure host because the server provider has access).
Author
Owner

@hoijui commented on GitHub (Feb 21, 2024):

I am also interested in this feature.
While I am an IT person, I only have very basic networking knowledge (mostly just IPv4 basics).
We have a tech-related non-profit (NPO) - promoting/pushing Open Source Hardware - which rents a (virtual) server.
Personally I have a low-power-consumption mini server at home, behind a CGNAT. I need it to be publicly reachable, providing web-serving, SSH server, email-server and things like that, at some point. Most importantly though, I want to use it for "hosting" distributed services nodes, like Tor, IPFS and such. This same setup should then be used by others that are part of the NPO.
It would be nice to be able to host Headscale ourselfs, and allow all our members (for now me, for testing) to have their own public server at home, providing both fail-safety and backups within the organization in a distributed manner, as well as (probably most important) build consciousness amongst the members for what distributed means, what the benefits are, that it is possible to some extend already, and what is missing.

I understand maybe 50% of the conversation in this issue. I personally would like to have a section somewhere in the docu of Headscale, that deals with this topic, explaining that the exact feature "funnel" as it is in Tailscale does not exist, but ... "you can build something similar in different ways, for example ...".
What do you think?
I'd be happy to dummy-test such a section.

@hoijui commented on GitHub (Feb 21, 2024): I am also interested in this feature. While I am an IT person, I only have very basic networking knowledge (mostly just IPv4 basics). We have a tech-related non-profit (NPO) - promoting/pushing Open Source Hardware - which rents a (virtual) server. Personally I have a low-power-consumption mini server at home, behind a CGNAT. I need it to be publicly reachable, providing web-serving, SSH server, email-server and things like that, at some point. Most importantly though, I want to use it for "hosting" distributed services nodes, like Tor, IPFS and such. This same setup should then be used by others that are part of the NPO. It would be nice to be able to host Headscale ourselfs, and allow all our members (for now me, for testing) to have their own public server at home, providing both fail-safety and backups within the organization in a distributed manner, as well as (probably most important) build consciousness amongst the members for what distributed means, what the benefits are, that it is possible to some extend already, and what is missing. I understand maybe 50% of the conversation in this issue. I personally would like to have a section somewhere in the docu of Headscale, that deals with this topic, explaining that the exact feature "funnel" as it is in Tailscale does not exist, but ... "you can build something similar in different ways, for example ...". What do you think? I'd be happy to dummy-test such a section.
Author
Owner

@rallisf1 commented on GitHub (Feb 21, 2024):

@hoijui it's not so much a technical problem as an economic one. For Funnels to work you either need a server with a public IP (2 of them if you want to host your own private nameservers) or 3rd party services (DNS + Proxy). Let's say you want to self-host everything. Although running a DNS and proxy is dirt cheap on resources, traffic is not and that's gonna be double than a normal web/application server because of tunelling remote connections. Economically it makes more sense to just host the damn thing you need in a VPS altogether and skip the VPN.

Tailscale (meaning the SaaS) makes money and can afford this service, most of us cannot.

Should there be a guide about it for those who don't care about the cost? Sure, but there are a gazzilion ways to accomplish this, thus there will still be people who want help with e.g. Apache and GoDaddy instead of Caddy and Cloudflare, and it will still not be an integration.

@rallisf1 commented on GitHub (Feb 21, 2024): @hoijui it's not so much a technical problem as an economic one. For Funnels to work you either need a server with a public IP (2 of them if you want to host your own private nameservers) or 3rd party services (DNS + Proxy). Let's say you want to self-host everything. Although running a DNS and proxy is dirt cheap on resources, traffic is not and that's gonna be double than a normal web/application server because of tunelling remote connections. Economically it makes more sense to just host the damn thing you need in a VPS altogether and skip the VPN. Tailscale (meaning the SaaS) makes money and can afford this service, most of us cannot. Should there be a guide about it for those who don't care about the cost? Sure, but there are a gazzilion ways to accomplish this, thus there will still be people who want help with e.g. Apache and GoDaddy instead of Caddy and Cloudflare, and it will still not be an integration.
Author
Owner

@hoijui commented on GitHub (Feb 21, 2024):

I understand that it is an economical problem, and thus Headscale can not provide it for its community. My NPO though, could provide it for its members, as we are a small community, and people accessing our servers would also be fairly limited, meaning: in total, I could imagine it would not be a huge load on our server(s), to establish the incoming connections for our NATed server from our hosted server with the static IP.
If you say it is not possible/makes no sense to document how to do it anyway, because too complex/too many options, then.. well.. it is so. :-)

@hoijui commented on GitHub (Feb 21, 2024): I understand that it is an economical problem, and thus Headscale can not provide it for its community. My NPO though, could provide it for its members, as we are a small community, and people accessing our servers would also be fairly limited, meaning: in total, I could imagine it would not be a huge load on our server(s), to establish the incoming connections for our NATed server from our hosted server with the static IP. If you say it is not possible/makes no sense to document how to do it anyway, because too complex/too many options, then.. well.. it is so. :-)
Author
Owner

@stratself commented on GitHub (Aug 1, 2024):

I propose an example "funnel" with my own stack (archive.org link), using Tailscale nodes and a TCP proxy to route traffic from a VPS towards a HTTPS reverse proxy on a Pi behind NAT. Traefik is said reverse proxy in both cases.

I also set the Pi to use the VPS as an exit node, so outgoing requests can also come from the VPS itself and not from my residential IP.

With the right DNS records and routings, this should allow you to host webservices. Automating this stack to spin up any service from any node in the tailnet is a harder story though... I'm not sure its aptness for the TOR/IPFS use case as @hoijui mentioned. Feel free to contact me for more discussions

Edit: 20102025, new website URL

@stratself commented on GitHub (Aug 1, 2024): I propose an example "funnel" with my own [stack](https://muoi.me/~stratself/articles/tailscale-notes/) ([archive.org link](https://web.archive.org/web/20240804112532/https://skedastically.me/articles/tailscale-notes)), using Tailscale nodes and a TCP proxy to route traffic from a VPS towards a HTTPS reverse proxy on a Pi behind NAT. Traefik is said reverse proxy in both cases. I also set the Pi to use the VPS as an exit node, so outgoing requests can also come from the VPS itself and not from my residential IP. With the right DNS records and routings, this should allow you to host webservices. Automating this stack to spin up any service from any node in the tailnet is a harder story though... I'm not sure its aptness for the TOR/IPFS use case as @hoijui mentioned. Feel free to contact me for more discussions Edit: 20102025, new website URL
Author
Owner

@hoijui commented on GitHub (Aug 1, 2024):

ehh cool, thank you for the article, @skedastically !

@hoijui commented on GitHub (Aug 1, 2024): ehh cool, thank you for the article, @skedastically !
Author
Owner

@qm3ster commented on GitHub (Aug 2, 2024):

@skedastically FYI link times out for me right now.

@qm3ster commented on GitHub (Aug 2, 2024): @skedastically FYI [link](https://skedastically.me/articles/tailscale-notes) times out for me right now.
Author
Owner

@LeapGM commented on GitHub (Mar 9, 2025):

Hey folks! I just found headscale and I'm looking to test it out as a tailscale alternative :)

I've just implemented a funnel/tunnel solution using tailscale & NPM (Nginx Proxy Manager), so I can use my own secure domain for all services in my tailscale network, no matter what server they're running on. NPM handles Let's Encrypt certs, including renewals. I'm currently testing it out, and I'm adding a script, using Cloudflare Tunnel, to be able to easily toggle public access to any service.

Once I have it all working and stable enough, I'm thinking I'll post it as a repo. Then it's time to see if it works with headscale! Headscale looks like a great initiative, and I would love replacing tailscale with open source.

@LeapGM commented on GitHub (Mar 9, 2025): Hey folks! I just found headscale and I'm looking to test it out as a tailscale alternative :) I've just implemented a funnel/tunnel solution using tailscale & NPM (Nginx Proxy Manager), so I can use my own secure domain for all services in my tailscale network, no matter what server they're running on. NPM handles Let's Encrypt certs, including renewals. I'm currently testing it out, and I'm adding a script, using Cloudflare Tunnel, to be able to easily toggle public access to any service. Once I have it all working and stable enough, I'm thinking I'll post it as a repo. Then it's time to see if it works with headscale! Headscale looks like a great initiative, and I would love replacing tailscale with open source.
Author
Owner

@hoijui commented on GitHub (Mar 10, 2025):

Nice @LeapGM ! :-)
... you'll post a script?

possibly also interesting for some folks here:
https://github.com/samyk/pwnat

The only tool/technique to punch holes through firewalls/NATs where multiple clients & server can be behind separate NATs without any 3rd party involvement.

@hoijui commented on GitHub (Mar 10, 2025): Nice @LeapGM ! :-) ... you'll post a script? possibly also interesting for some folks here: https://github.com/samyk/pwnat > The only tool/technique to punch holes through firewalls/NATs where multiple clients & server can be behind separate NATs without any 3rd party involvement.
Author
Owner

@salemgolemugoo commented on GitHub (Apr 3, 2025):

Hey folks! I just found headscale and I'm looking to test it out as a tailscale alternative :)

I've just implemented a funnel/tunnel solution using tailscale & NPM (Nginx Proxy Manager), so I can use my own secure domain for all services in my tailscale network, no matter what server they're running on. NPM handles Let's Encrypt certs, including renewals. I'm currently testing it out, and I'm adding a script, using Cloudflare Tunnel, to be able to easily toggle public access to any service.

Once I have it all working and stable enough, I'm thinking I'll post it as a repo. Then it's time to see if it works with headscale! Headscale looks like a great initiative, and I would love replacing tailscale with open source.

Any updates? I would love to check your solution

@salemgolemugoo commented on GitHub (Apr 3, 2025): > Hey folks! I just found headscale and I'm looking to test it out as a tailscale alternative :) > > I've just implemented a funnel/tunnel solution using tailscale & NPM (Nginx Proxy Manager), so I can use my own secure domain for all services in my tailscale network, no matter what server they're running on. NPM handles Let's Encrypt certs, including renewals. I'm currently testing it out, and I'm adding a script, using Cloudflare Tunnel, to be able to easily toggle public access to any service. > > Once I have it all working and stable enough, I'm thinking I'll post it as a repo. Then it's time to see if it works with headscale! Headscale looks like a great initiative, and I would love replacing tailscale with open source. Any updates? I would love to check your solution
Author
Owner

@hkfuertes commented on GitHub (Apr 3, 2025):

Hey folks! I just found headscale and I'm looking to test it out as a tailscale alternative :)

I've just implemented a funnel/tunnel solution using tailscale & NPM (Nginx Proxy Manager), so I can use my own secure domain for all services in my tailscale network, no matter what server they're running on. NPM handles Let's Encrypt certs, including renewals. I'm currently testing it out, and I'm adding a script, using Cloudflare Tunnel, to be able to easily toggle public access to any service.

Once I have it all working and stable enough, I'm thinking I'll post it as a repo. Then it's time to see if it works with headscale! Headscale looks like a great initiative, and I would love replacing tailscale with open source.

Places I have seen with a solution, but I don't think I like that one... what I have seen is a node avaliable on the internet and connected to the network (tailscale or headscale, it does not matter) and NPM (or Caddy) just pointing to the ts's ip of the services.... so from the Web --> internet node with NPM -- {tailscale} --> service... but in the end all the traffic will go through the node... Is your script different? that would be awesome! headscale control just delegating the connection to direct link....

I have to test my own aproach to see how slow it feels...

@hkfuertes commented on GitHub (Apr 3, 2025): > Hey folks! I just found headscale and I'm looking to test it out as a tailscale alternative :) > > I've just implemented a funnel/tunnel solution using tailscale & NPM (Nginx Proxy Manager), so I can use my own secure domain for all services in my tailscale network, no matter what server they're running on. NPM handles Let's Encrypt certs, including renewals. I'm currently testing it out, and I'm adding a script, using Cloudflare Tunnel, to be able to easily toggle public access to any service. > > Once I have it all working and stable enough, I'm thinking I'll post it as a repo. Then it's time to see if it works with headscale! Headscale looks like a great initiative, and I would love replacing tailscale with open source. Places I have seen with a solution, but I don't think I like that one... what I have seen is a node avaliable on the internet and connected to the network (tailscale or headscale, it does not matter) and NPM (or Caddy) just pointing to the ts's ip of the services.... so from the Web --> internet node with NPM -- {tailscale} --> service... but in the end all the traffic will go through the node... Is your script different? that would be awesome! headscale control just delegating the connection to direct link.... I have to test my own aproach to see how slow it feels...
Author
Owner

@tgrushka commented on GitHub (May 4, 2025):

@hoijui I agree with you, this should be simpler. I think tailscale doesn't want their headscale maintainers to implement a feature that they think would hurt their profits. I do not agree with @rallisf1 that you need all this infrastructure to do it. See this project: https://github.com/anderspitman/SirTunnel

I'm trying to make this work with Caddy on a VPS. Should be really simple -- have Caddy serve all the requests, then use script like SirTunnel to automate setting up tunnels in ssh and proxying them via Caddy.

It seems like the original request was related to this -- why can't we just "funnel" requests through headscale / our own tailnet?

I'm guessing it's a business decision of tailscale, and not a technical one.

And it's nonsensical that it would require any infrastructure on tailscale's part at all. That's not even related to the issue. It's fully technically achievable in headscale via tailnet -- even if it would require proxying with Caddy -- that's fine with me. But the "funnel" feature could be made to work simply. I think it's just a matter of priority.

Something like this should not have to be outsourced. Sure, it makes sense for large companies to outsource to tailscale, but not individuals that don't have large coffers.

@tgrushka commented on GitHub (May 4, 2025): @hoijui I agree with you, this should be simpler. I think tailscale doesn't want their headscale maintainers to implement a feature that they think would hurt their profits. I do not agree with @rallisf1 that you need all this infrastructure to do it. See this project: https://github.com/anderspitman/SirTunnel I'm trying to make this work with Caddy on a VPS. Should be really simple -- have Caddy serve all the requests, then use script like SirTunnel to automate setting up tunnels in ssh and proxying them via Caddy. It seems like the original request was related to this -- why can't we just "funnel" requests through headscale / our own tailnet? I'm guessing it's a business decision of tailscale, and not a technical one. And it's nonsensical that it would require any infrastructure on tailscale's part at all. That's not even related to the issue. It's fully technically achievable in headscale via tailnet -- even if it would require proxying with Caddy -- that's fine with me. But the "funnel" feature could be made to work simply. I think it's just a matter of priority. Something like this should not have to be outsourced. Sure, it makes sense for large companies to outsource to tailscale, but not individuals that don't have large coffers.
Author
Owner

@stratself commented on GitHub (May 8, 2025):

I think the better approach would be to bring your own Funnel ingress (as a Tailscale node), that you expose to the public internet (e.g. as a Docker on a VPS), and with your own FQDN. Which would requires two things from the Tailscale client:

  • tailscale cert to accept custom domains. As Tailscale uses the DNS-01 challenge, I guess they provision the *.ts.net certs via their own infra and push it to desired nodes. So this is something headscale can reverse-engineer/emulate e.g. using lego-acme and the provider's API key.
  • A baked-in "Funnel ingress" feature that does SNI routing to your target (AFAICT this is what Tailscale Inc's relays do). Ideally you can choose your own ingress nodes, etc... This is mainly a feature request on their side.

Since Tailscale already acts as a layer-4 router (via serve --tcp) as well as an HTTP reverse proxy this should be fairly straightforward. I guess it hasn't been done mainly because Tailscale wouldn't want to manage your DNS records, amongst other things.

@stratself commented on GitHub (May 8, 2025): I think the better approach would be to bring your own Funnel ingress (as a Tailscale node), that you expose to the public internet (e.g. as a Docker on a VPS), and with your own FQDN. Which would requires two things from the Tailscale client: - `tailscale cert` to accept custom domains. As Tailscale [uses the DNS-01 challenge](https://tailscale.com/kb/1153/enabling-https#provision-tls-certificates-for-your-devices), I guess they provision the `*.ts.net` certs via their own infra and push it to desired nodes. So this is something headscale can reverse-engineer/emulate e.g. using `lego-acme` and the provider's API key. - A baked-in "Funnel ingress" feature that does SNI routing to your target (AFAICT this is what Tailscale Inc's relays do). Ideally you can choose your own ingress nodes, etc... This is mainly a feature request on their side. Since Tailscale already acts as a layer-4 router (via `serve --tcp`) as well as an HTTP reverse proxy this should be fairly straightforward. I guess it hasn't been done mainly because Tailscale wouldn't want to manage *your* DNS records, amongst other things.
Author
Owner

@jandrews377 commented on GitHub (Jul 17, 2025):

You can roll your own simple solution using a public exit node (eg cheap vm with a public ip) and use rinetd to forward ingress traffic through the tailnet. The traffic will appear on the tailnet as though its come from the local interface on the vm, therefore the ACL rule to lock down ingress traffic back to another host on your tailnet becomes straightforward. You then access (or share) the public IP and port combination with external users to access services running on your tailnet.

@jandrews377 commented on GitHub (Jul 17, 2025): You can roll your own simple solution using a public exit node (eg cheap vm with a public ip) and use rinetd to forward ingress traffic through the tailnet. The traffic will appear on the tailnet as though its come from the local interface on the vm, therefore the ACL rule to lock down ingress traffic back to another host on your tailnet becomes straightforward. You then access (or share) the public IP and port combination with external users to access services running on your tailnet.
Author
Owner

@Xinayder commented on GitHub (Jul 21, 2025):

How is this different than having a public-facing server (e.g. a VPS), connected to the Tailnet and acting as a reverse proxy to the local-facing servers?

Why would I need rinetd?

@Xinayder commented on GitHub (Jul 21, 2025): How is this different than having a public-facing server (e.g. a VPS), connected to the Tailnet and acting as a reverse proxy to the local-facing servers? Why would I need rinetd?
Author
Owner

@jandrews377 commented on GitHub (Jul 21, 2025):

How is this different than having a public-facing server (e.g. a VPS), connected to the Tailnet and acting as a reverse proxy to the local-facing servers?

Why would I need rinetd?

No different. When reverse proxying, you would be routing a port request on the default interface (eg eth0) to port on another interface (in our case tailscale0). rinetd is just another tool to make this easy. Use nginx, iptables DNAT rule or anything else you are comfortable with. I suggested rinetd because it's 'ergonomically' easy to use. The same people asking for 'Funnel' would be the same people who would appreciate the ergonomics of the mechanism.

@jandrews377 commented on GitHub (Jul 21, 2025): > How is this different than having a public-facing server (e.g. a VPS), connected to the Tailnet and acting as a reverse proxy to the local-facing servers? > > Why would I need rinetd? No different. When reverse proxying, you would be routing a port request on the default interface (eg eth0) to port on another interface (in our case tailscale0). rinetd is just another tool to make this easy. Use nginx, iptables DNAT rule or anything else you are comfortable with. I suggested rinetd because it's 'ergonomically' easy to use. The same people asking for 'Funnel' would be the same people who would appreciate the ergonomics of the mechanism.
Author
Owner

@stratself commented on GitHub (Jul 26, 2025):

Reverse-proxies, rinetd1 , TCP routing2 , tailscale serve --tcp, ... are all probable methods with their own quirks. What sets Funnel apart is it being a one-time setup without needing third-party software that works on top of (rather than integrate directly with) Tailscale.

To that end I've opened https://github.com/tailscale/tailscale/issues/15946 to request the Funnel ingress feature on Tailscale clients themselves. Hopefully with this done, an open-source implementation can be provided for Headscale to coordinate against. Maybe, just maybe, Headscale can re-use this code so it can be a Funnel relay alongside being a control server + DERP too.


  1. mentioned as early as 2022 - https://tailscale.com/blog/introducing-tailscale-funnel ↩︎

  2. from my comment above ↩︎

@stratself commented on GitHub (Jul 26, 2025): Reverse-proxies, rinetd[^1], TCP routing[^2], tailscale serve --tcp, ... are all probable methods with their own quirks. What sets Funnel apart is it being a one-time setup without needing third-party software that works on top of (rather than integrate directly with) Tailscale. To that end I've opened `https://github.com/tailscale/tailscale/issues/15946` to request the Funnel ingress feature on Tailscale clients themselves. Hopefully with this done, an open-source implementation can be provided for Headscale to coordinate against. Maybe, just maybe, Headscale can re-use this code so it can be a Funnel relay alongside being a control server + DERP too. [^1]: mentioned as early as 2022 - https://tailscale.com/blog/introducing-tailscale-funnel [^2]: from my comment [above](https://github.com/juanfont/headscale/issues/1040#issuecomment-2262807617)
Author
Owner

@Janhouse commented on GitHub (Jul 28, 2025):

I looked at how Pangolin does it and was pleasantly surprised that they use Traefik HTTP configuration endpoint. This gave me the idea to make a standalone solution so I could use it with Headscale and my existing Traefik proxy.

So I made a simple nextjs service that generates Traefik config and provides admin panel to manage it.

All the work is handled by Traefik, including DNS challenge for letsencrypt, or you can add Cloudflare proxy in front, or you can use both Cloudflare and Letsencrypt in split DNS scenarios where you use Cloudflare for public access but still use Letsencrypt for internal network.

It could become a single docker-compose file shipping with traefik + tailscale + service, place it on some VPS and it would be ready. In my opinion this would probably be convenient enough for people already self hosting headscale.

Here is example on how it works so far: https://www.youtube.com/watch?v=ag0B1-lrOXY

I'll tidy it up and make it available on Github if anyone is interested.

Image Image Image
@Janhouse commented on GitHub (Jul 28, 2025): I looked at how Pangolin does it and was pleasantly surprised that they use Traefik HTTP configuration endpoint. This gave me the idea to make a standalone solution so I could use it with Headscale and my existing Traefik proxy. So I made a simple nextjs service that generates Traefik config and provides admin panel to manage it. All the work is handled by Traefik, including DNS challenge for letsencrypt, or you can add Cloudflare proxy in front, or you can use both Cloudflare and Letsencrypt in split DNS scenarios where you use Cloudflare for public access but still use Letsencrypt for internal network. It could become a single docker-compose file shipping with traefik + tailscale + service, place it on some VPS and it would be ready. In my opinion this would probably be convenient enough for people already self hosting headscale. Here is example on how it works so far: https://www.youtube.com/watch?v=ag0B1-lrOXY I'll tidy it up and make it available on Github if anyone is interested. <img width="1219" height="491" alt="Image" src="https://github.com/user-attachments/assets/bc39027d-310d-477a-9100-8fd99834e007" /> <img width="1221" height="408" alt="Image" src="https://github.com/user-attachments/assets/8ff026c7-4706-432d-8d71-3797305b67e0" /> <img width="1191" height="813" alt="Image" src="https://github.com/user-attachments/assets/726edfc9-c475-4213-b146-70f69ddff007" />
Author
Owner

@NoX1De commented on GitHub (Sep 1, 2025):

I'll tidy it up and make it available on Github if anyone is interested.

@Janhouse Please do!

@NoX1De commented on GitHub (Sep 1, 2025): > > I'll tidy it up and make it available on Github if anyone is interested. > @Janhouse Please do!
Author
Owner

@renne commented on GitHub (Sep 1, 2025):

@Janhouse How do you synchronize the configuration of the Traefik proxy of the VPS and the local LAN?

@renne commented on GitHub (Sep 1, 2025): @Janhouse How do you synchronize the configuration of the Traefik proxy of the VPS and the local LAN?
Author
Owner

@Janhouse commented on GitHub (Sep 1, 2025):

@renne alright, I did not really clean it up, just pushed it here: https://github.com/Janhouse/traefik-proxy-admin

It is still a bit rough and don't mind the README, it is somewhat vibe-coded. 😁
There is example docker compose and once you run the service, it has some additional instructions.

@NoX1De the idea is to run Traefik and Tailscale client on VPS. And when you add the dynamic configuration entries pointing to Tailscale nodes, it will be routed by Tailscale. But also you can run this container separately from the VPS Traefik instance (in LAN or wherever) and just point to the dynamic configuration URL, still routed by Tailscale client.

Also it would be nice to tie it together with Headscale ACL management so it would open the necessary ports for the VPS node to access. Maybe something to consider in the future.

@Janhouse commented on GitHub (Sep 1, 2025): @renne alright, I did not really clean it up, just pushed it here: https://github.com/Janhouse/traefik-proxy-admin It is still a bit rough and don't mind the README, it is somewhat vibe-coded. 😁 There is example docker compose and once you run the service, it has some additional instructions. @NoX1De the idea is to run Traefik and Tailscale client on VPS. And when you add the dynamic configuration entries pointing to Tailscale nodes, it will be routed by Tailscale. But also you can run this container separately from the VPS Traefik instance (in LAN or wherever) and just point to the dynamic configuration URL, still routed by Tailscale client. Also it would be nice to tie it together with Headscale ACL management so it would open the necessary ports for the VPS node to access. Maybe something to consider in the future.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#387