Tailscale funnel

Tailscale lets you put all your devices on their own private network so they can join, if the ACLs allow it. It's usually nice and comforting knowing that all of your devices can then be isolated from the internet, with no ports needing to be open to the world.

Sometimes, however, you need something from the spooky, non-Tailscale wide internet to gain access to your device.

You may need to receive a webhook from GitHub. Maybe you want to briefly test a website you're working on using a co-worker's phone. Or maybe you even want to host your personal blog or a small Mastodon server on your own computer.

For all of this to work, however, you will need an address that other parties can access. Surprisingly, not everyone uses Tailscale. (We're working on it.) So you'll need a publicly routable IP address, a TLS certificate (hopefully!), and then necessarily a DNS name for the certificate. Tailscale gives you a DNS name and supports your Tailscale node by getting its own Let's Encrypt certificate for that DNS name, but your Tailscale IP addresses aren't publicly routable, so those webhooks from GitHub or ActivityPub can't reach you . You're not really on the Internet without a public IP address.

Yes, you can create a $5/month virtual machine somewhere and forward a port from its public internet IP address to your tail network with a single line in your rinetd.conf file. But is it fun? Do you really need (another) Linux VM in your life?

Here's something more fun: Tailscale Funnel. You can now expose stuff from your Tailscale node to the spooky big internet and we'll deliver it to you through Tailscale.

How it works

"My VPN is exposed to the internet!!?" we hear you scream. We're also the worried type, so let's see how it works. Hope you find it less scary.

First, rest assured that Tailscale Funnel is disabled by default and double opt-in: it must be both enabled in the Tailscale Admin Console by a tailnet administrator and enabled on the device running Tailscale.

When enabled, two things happen:

The first thing we do is set up public DNS records for your node.tailnet.ts.net MagicDNS name to point to the public IP addresses of the new servers we are currently using. These new funnel interfaces (funends?) are geo-replicated around the world, similar to how we manage DERP servers around the world. Tailscale Funnel runs on separate services, virtual machines and networks from DERP, but they are similar in that they are both hosted by Tailscale. (Like DERP, which you can run yourself, you can also do a rinetd thing yourself for this, if you find that more fun.)

The second thing we do is add these Funnel entry nodes to the list of Tailscale peers in your network. On nodes where Tailscale Funnel is enabled, you will see them in the tailscale --json service status. These peers will be named funnel-ingress-node and are sent with a set of bits marking them as funnel peers. This bit prevents them from having packet-level access to your tail network. The only thing they are allowed to do is offer your node a channelized TCP connection, which your node can accept or reject, depending on how it is configured.

(This magical piece will make an appearance in a future blog post; stay tuned!)

The way Funnel entry nodes are allowed to send a connection offer to your nodes uses Tailscale's inter-node "peerapi" mechanism that we originally added for Taildrop. With peerapi, each Tailscale node allocates an ephemeral port number reserved for its inter-node RPC port. These peerapi RPCs are then just HTTP requests on that port. TCP connections to this port are then intercepted by Tailscale after WireGuard® decryption, before they reach your operating system. In fact, they are never delivered to your OS: we handle packets and TCP internally with gVisor's network stack, just like we do for Tailscale SSH.

When someone accesses node.tailnet.ts.net in their browser (or another client), a traditional DNS response then points to one of our funnel VMs, ideally in a region near your knot.

We then accept these TCP connections from en...

Tailscale funnel

Tailscale lets you put all your devices on their own private network so they can join, if the ACLs allow it. It's usually nice and comforting knowing that all of your devices can then be isolated from the internet, with no ports needing to be open to the world.

Sometimes, however, you need something from the spooky, non-Tailscale wide internet to gain access to your device.

You may need to receive a webhook from GitHub. Maybe you want to briefly test a website you're working on using a co-worker's phone. Or maybe you even want to host your personal blog or a small Mastodon server on your own computer.

For all of this to work, however, you will need an address that other parties can access. Surprisingly, not everyone uses Tailscale. (We're working on it.) So you'll need a publicly routable IP address, a TLS certificate (hopefully!), and then necessarily a DNS name for the certificate. Tailscale gives you a DNS name and supports your Tailscale node by getting its own Let's Encrypt certificate for that DNS name, but your Tailscale IP addresses aren't publicly routable, so those webhooks from GitHub or ActivityPub can't reach you . You're not really on the Internet without a public IP address.

Yes, you can create a $5/month virtual machine somewhere and forward a port from its public internet IP address to your tail network with a single line in your rinetd.conf file. But is it fun? Do you really need (another) Linux VM in your life?

Here's something more fun: Tailscale Funnel. You can now expose stuff from your Tailscale node to the spooky big internet and we'll deliver it to you through Tailscale.

How it works

"My VPN is exposed to the internet!!?" we hear you scream. We're also the worried type, so let's see how it works. Hope you find it less scary.

First, rest assured that Tailscale Funnel is disabled by default and double opt-in: it must be both enabled in the Tailscale Admin Console by a tailnet administrator and enabled on the device running Tailscale.

When enabled, two things happen:

The first thing we do is set up public DNS records for your node.tailnet.ts.net MagicDNS name to point to the public IP addresses of the new servers we are currently using. These new funnel interfaces (funends?) are geo-replicated around the world, similar to how we manage DERP servers around the world. Tailscale Funnel runs on separate services, virtual machines and networks from DERP, but they are similar in that they are both hosted by Tailscale. (Like DERP, which you can run yourself, you can also do a rinetd thing yourself for this, if you find that more fun.)

The second thing we do is add these Funnel entry nodes to the list of Tailscale peers in your network. On nodes where Tailscale Funnel is enabled, you will see them in the tailscale --json service status. These peers will be named funnel-ingress-node and are sent with a set of bits marking them as funnel peers. This bit prevents them from having packet-level access to your tail network. The only thing they are allowed to do is offer your node a channelized TCP connection, which your node can accept or reject, depending on how it is configured.

(This magical piece will make an appearance in a future blog post; stay tuned!)

The way Funnel entry nodes are allowed to send a connection offer to your nodes uses Tailscale's inter-node "peerapi" mechanism that we originally added for Taildrop. With peerapi, each Tailscale node allocates an ephemeral port number reserved for its inter-node RPC port. These peerapi RPCs are then just HTTP requests on that port. TCP connections to this port are then intercepted by Tailscale after WireGuard® decryption, before they reach your operating system. In fact, they are never delivered to your OS: we handle packets and TCP internally with gVisor's network stack, just like we do for Tailscale SSH.

When someone accesses node.tailnet.ts.net in their browser (or another client), a traditional DNS response then points to one of our funnel VMs, ideally in a region near your knot.

We then accept these TCP connections from en...

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow