← All articles
Tailscale Funnel

Tailscale Funnel: Expose Homelab Services Publicly Without Port Forwarding

Networking 2026-02-15 · 10 min read tailscale funnel networking remote-access https
By HomeLab Starter Editorial TeamHome lab enthusiasts covering hardware setup, networking, and self-hosted services for home and small office environments.

You want to share a service from your homelab with someone who isn't on your network. Maybe it's a demo app you're building, a Grafana dashboard for a client, or a Jellyfin instance for your family. The traditional path is port forwarding, dynamic DNS, TLS certificates, and hoping your ISP hasn't put you behind CGNAT. If they have, you're stuck — no amount of router configuration will make inbound connections work. Even if port forwarding does work, you've just exposed your home IP to the world and opened a hole in your firewall. There has to be a better way.

Photo by GuerrillaBuzz on Unsplash

Tailscale Funnel is that better way. It's a feature built into Tailscale that lets you expose local services to the public internet through Tailscale's relay infrastructure. Anyone on the internet can reach your service at a https://machine-name.tailnet-name.ts.net URL — with automatic HTTPS, no domain name required, and no inbound ports. Your home IP stays hidden. It works through CGNAT, double NAT, and corporate firewalls. If your machine can reach the internet at all, Funnel works.

Tailscale logo

Why Funnel Instead of Port Forwarding

Port forwarding has been the default for decades, but it comes with real problems for homelabbers:

Tailscale Funnel eliminates all of these. No router configuration, no DNS setup, no certificate management. You run one command and your service is live on the public internet with HTTPS.

How Funnel Works

When you enable Funnel for a service, Tailscale's DERP (Designated Encrypted Relay for Packets) relay servers accept incoming HTTPS connections from the public internet on your behalf. The request arrives at Tailscale's infrastructure, gets forwarded through the encrypted Tailscale tunnel to your machine, and your machine proxies it to the local service.

The flow looks like this:

Public user → https://mybox.tail1234.ts.net → Tailscale DERP relay → WireGuard tunnel → Your machine → localhost:8080

Key points:

Prerequisites

Before setting up Funnel, you need:

Funnel only works with HTTPS on port 443 from the public internet's perspective. Your local service can run on any port — Tailscale handles the mapping.

Like what you're reading? Subscribe to HomeLab Starter — free weekly guides in your inbox.

Setting Up Funnel

Step 1: Install Tailscale

If you don't already have Tailscale installed:

# Linux (one-line install)
curl -fsSL https://tailscale.com/install.sh | sh

# Start and authenticate
sudo tailscale up

Follow the authentication URL to add the device to your tailnet.

Step 2: Enable Funnel in the Admin Console

Funnel requires a policy change in your tailnet's ACL configuration. Go to the Tailscale admin console at login.tailscale.com, navigate to Access Controls, and add the Funnel policy:

{
  "nodeAttrs": [
    {
      "target": ["autogroup:member"],
      "attr": ["funnel"]
    }
  ]
}

This allows all members of your tailnet to use Funnel. You can restrict it to specific devices by using device tags instead of autogroup:member.

Step 3: Enable HTTPS Certificates

In the admin console, go to DNS and ensure HTTPS Certificates is enabled. This lets Tailscale provision Let's Encrypt certificates for your devices.

Step 4: Start Funnel

With a service running on port 8080, expose it publicly:

# Expose local port 8080 to the public internet
sudo tailscale funnel 8080

That's it. Tailscale outputs the public URL:

Available on the internet:

https://mybox.tail1234.ts.net/
|-- proxy http://127.0.0.1:8080

Funnel started and running in the background.
Press Ctrl+C to stop.

Anyone on the internet can now visit https://mybox.tail1234.ts.net and reach your service.

Step 5: Configure Multiple Services with serve

For more complex setups, use tailscale serve to map paths and ports, then enable Funnel on top:

# Serve a local app on the Tailscale HTTPS endpoint
sudo tailscale serve --bg https+insecure://localhost:3000

# Serve static files from a directory
sudo tailscale serve --bg /docs /var/www/docs

# Serve a specific path to a different backend
sudo tailscale serve --bg /grafana http://localhost:3000

# Now enable Funnel to make it public
sudo tailscale funnel --bg 443

Check what's currently configured:

sudo tailscale serve status

Step 6: Run as a Persistent Background Service

By default, tailscale funnel runs in the foreground. Use the --bg flag to run it in the background, persisting across reboots:

# Start Funnel in the background (persists across reboots)
sudo tailscale funnel --bg 8080

To stop it:

sudo tailscale funnel --bg off

HTTPS and TLS Handling

One of Funnel's best features is zero-effort HTTPS. Here's how it works:

If your local service already uses HTTPS (self-signed or otherwise), use https+insecure:// in the serve config to connect to it without certificate verification:

sudo tailscale serve --bg https+insecure://localhost:8443

Limitations You Should Know

Funnel is powerful but has real constraints:

HTTPS on port 443 only. The public internet can only reach your Funnel on port 443. No custom ports, no TCP/UDP pass-through, no SSH access. This is web traffic only.

Bandwidth goes through Tailscale's relays. Unlike Tailscale's peer-to-peer connections, Funnel traffic always flows through DERP relays. This means your throughput is limited by the relay capacity. For a personal blog or dashboard, this is fine. For streaming 4K video to dozens of users, it's not.

You don't control the domain name. Your public URL is machine-name.tailnet-name.ts.net. You can't use a custom domain. If you need app.yourdomain.com, you need Cloudflare Tunnel or a similar reverse proxy.

Single node per URL. Each Funnel URL maps to one machine. There's no built-in load balancing or failover across multiple backend servers.

No authentication layer. Unlike Cloudflare Tunnel with Cloudflare Access, Funnel doesn't provide an authentication layer in front of your service. Your application needs to handle its own authentication. Anyone on the internet can reach the endpoint.

Rate limiting. Tailscale may apply rate limits to Funnel traffic. This isn't well-documented, but don't expect to run a high-traffic production site through it.

Comparison: Funnel vs Cloudflare Tunnel vs Port Forwarding vs ngrok

Feature Tailscale Funnel Cloudflare Tunnel Port Forwarding ngrok
Custom domain No (*.ts.net only) Yes (your domain) Yes (with DDNS) Paid plans only
Domain/account required Tailscale account Cloudflare account + domain Router access ngrok account
Setup time 1 minute 15-30 minutes 30-60 minutes 5 minutes
HTTPS Automatic Automatic Manual (Let's Encrypt) Automatic
Home IP hidden Yes Yes No Yes
Works through CGNAT Yes Yes No Yes
DDoS protection No Yes No No
Auth layer included No Yes (Cloudflare Access) No Yes (paid)
Bandwidth Relayed (limited) Cloudflare edge Your upload speed Relayed (limited)
Custom ports No (443 only) Yes Yes Yes
Non-HTTP traffic No Limited (TCP with WARP) Yes Yes (TCP tunnels)
WebSocket support Yes Yes Yes Yes
Cost Free Free Free Free (limited) / $10+/mo
Persistence Built-in (--bg) systemd service Router config Paid plans

When to Choose Tailscale Funnel

When to Choose Cloudflare Tunnel Instead

When to Stick with Port Forwarding

Security Considerations

Funnel puts your service on the public internet. Treat it accordingly:

Your application must handle authentication. Funnel provides no auth layer. If your service has a login page, great. If it doesn't, the entire internet can access whatever is behind that port.

Keep services updated. A publicly exposed Nextcloud or Grafana instance is a target. Apply security patches promptly.

Minimize your attack surface. Only expose services that are designed for public access. Don't funnel your Proxmox web UI or database admin panel.

Use application-level rate limiting. Since Funnel doesn't provide rate limiting at the network level, your application should handle brute-force protection, API rate limits, and abuse prevention.

Monitor access logs. Check your application's access logs for unusual traffic patterns. You're on the public internet now — scanners and bots will find you.

# Good candidates for Funnel
- A personal blog or portfolio site
- A demo app for a client
- A file sharing service with authentication (e.g., FileBrowser)
- A webhook receiver for CI/CD

# Bad candidates for Funnel
- Proxmox or hypervisor management UI
- Database admin tools (phpMyAdmin, pgAdmin)
- Anything without authentication
- High-bandwidth media streaming

Real-World Use Cases

Sharing a Dev Server with a Client

You're building a web app locally and want to show a client the progress:

# Your app runs on port 3000
npm run dev -- --port 3000

# Expose it publicly
sudo tailscale funnel 3000

Send the client the ts.net URL. They see your app in real time. When the meeting is over, Ctrl+C.

Webhook Receiver for GitHub or Stripe

Many APIs require a public HTTPS endpoint for webhooks. Instead of deploying to a server:

# Your webhook handler listens on port 4000
sudo tailscale funnel 4000

Set the webhook URL to https://mybox.tail1234.ts.net/webhooks in GitHub or Stripe. Webhooks hit your local machine directly.

Temporary File Sharing

Need to share files with someone quickly?

# Serve a directory of files
sudo tailscale serve --bg /share /home/user/shared-files

# Make it public
sudo tailscale funnel --bg 443

Send them the URL. Turn off Funnel when they've downloaded what they need.

Home Assistant Dashboard for Family

Give family members access to a Home Assistant dashboard without VPN setup or Tailscale on their devices:

sudo tailscale funnel 8123

They visit the URL in their browser and log in to Home Assistant. No app installation, no VPN configuration, no port forwarding on the router.

Funnel + Tailscale Serve: The Full Picture

Funnel and Serve are related but distinct:

You can use serve without Funnel for private HTTPS access to your services across your tailnet. Adding Funnel on top makes the same endpoint public. Think of it as a visibility toggle: serve = private HTTPS, funnel = public HTTPS.

# Private only (tailnet members can access via HTTPS)
sudo tailscale serve --bg 8080

# Public (anyone on the internet can access)
sudo tailscale funnel --bg 8080

The Bottom Line

Tailscale Funnel occupies a specific niche: the fastest way to put a homelab service on the public internet with zero infrastructure setup. No domain, no DNS, no certificates, no port forwarding, no firewall rules. One command, and you're live.

It's not a replacement for Cloudflare Tunnel if you need custom domains, DDoS protection, or an authentication layer. It's not a replacement for port forwarding if you need raw TCP/UDP access or maximum bandwidth. But for quick sharing, webhook receivers, demos, and "I just need a public URL for this thing" scenarios, nothing else comes close to Funnel's simplicity.

If you're already running Tailscale for remote access to your homelab — and you probably should be — Funnel is sitting right there, one command away, waiting for the next time someone asks "can you send me a link to that?"

Get free weekly tips in your inbox. Subscribe to HomeLab Starter