Services and SSH

Choose Serve, sharing, or Funnel

Publish a loopback service inside the tailnet with Serve and distinguish it from device sharing and public Internet exposure.

tailscale serve publishes a local service to your tailnet over HTTPS, with a real certificate for the device’s ts.net name. It is the missing piece for the loopback service you built earlier.

Three features sound similar and do very different things: Serve, sharing, and Funnel. Let’s see each one, and who can reach what.

Serve: private to the tailnet

Point Serve at the loopback listener from the earlier lesson:

tailscale serve --bg localhost:3000
tailscale serve status
https://lab-server.tail4a5b6.ts.net/
|-- proxy http://localhost:3000

Serve stays private to the tailnet. Only devices in your tailnet, subject to your policy, can reach that URL. The --bg flag keeps the proxy running in the background instead of holding your terminal.

Open the reported HTTPS URL from your laptop. TLS works out of the box, because Tailscale provisions a certificate for the device name. No certbot, no self-signed warnings.

Sharing: one device, one invited user

Sharing gives a specific external Tailscale user access to one device. You send an invite, they accept it from their own tailnet, and your policies still control what they can do on that device.

This is for “my collaborator needs the staging box”. They get one machine, not your network. You do not merge two tailnets, and they do not see your other devices.

Funnel: the public Internet

Funnel is different. It publishes a local service to the public Internet. Anyone with the URL can reach it. No tailnet membership, no identity, nothing.

Treat enabling Funnel with the same seriousness as opening a port on your router, because that is what it means. If the app behind it has weak or missing authentication, you just published that weakness to the world.

Choose the smallest audience

Pick the smallest audience that solves the problem. Serve for your own tailnet. Sharing for one outside person. Funnel only when the audience really is “anyone”.

And remember that a private network does not mean logged in. The tailnet decides which devices may connect. Your application still decides which people may see what.

Practice the full cycle

Enable Serve, open the HTTPS URL from your laptop, test a denied user if you have one, then turn Serve off and confirm the route closes:

tailscale serve off
tailscale serve status
# No serve config

Publishing should be reversible. Know where the off switch is before you need it.

Lesson completed