{"slug":"tailscale-funnel-command","title":"tailscale funnel command","tags":["tailscale"],"agent_summary":"Last validated: Jan 26, 2026","trigger_phrases":[],"runnable":false,"markdown":"\r\n# tailscale funnel command\r\n\r\nLast validated: Jan 26, 2026\r\n\r\nThe CLI commands for both Tailscale Funnel and Tailscale Serve have changed in the 1.52 version of the Tailscale client. If you've used Funnel or Serve in previous versions, we recommend reviewing the CLI documentation.\r\n\r\n`tailscale funnel` lets you share a local service over the internet. You can also choose to use [Tailscale Serve](https://tailscale.com/docs/features/tailscale-serve) using the [`tailscale serve`](https://tailscale.com/docs/reference/tailscale-cli/serve) command to limit sharing within your tailnet.\r\n\r\n```shell\r\ntailscale funnel [flags] <target>\r\n```\r\n\r\nSubcommands:\r\n\r\n- [`status`](https://tailscale.com/docs/reference/tailscale-cli/funnel#get-the-status) Gets the status\r\n- [`reset`](https://tailscale.com/docs/reference/tailscale-cli/funnel#reset-tailscale-funnel) Resets the configuration\r\n\r\nTo explore various use cases and examples, refer to [Tailscale Funnel examples](https://tailscale.com/docs/reference/examples/funnel).\r\n\r\n## [Funnel command flags](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#funnel-command-flags)\r\n\r\nAvailable flags:\r\n\r\n- `--bg` Determines whether the command should run as a background process.\r\n- `--https=<port>` Expose an HTTPS server at the specified port (default).\r\n- `--proxy-protocol=<version>` PROXY protocol version (1 or 2) for TCP forwarding.\r\n- `--set-path=<path>` Appends the specified path to the base URL for accessing the underlying service.\r\n- `--tcp=<port>` Expose a TCP forwarder to forward TCP packets at the specified port.\r\n- `--tls-terminated-tcp=<port>` Expose a TCP forwarder to forward TLS-terminated TCP packets at the specified port.\r\n- `--yes` Update without interactive prompts.\r\n\r\nThe `tailscale funnel` command accepts a target that can be a file, directory, text, or most commonly, the location to a service running on the local machine. The location to the local service can be expressed as a port number (for example, `3000`), a partial URL (for example, `localhost:3000`), or a full URL including a path (for example, `tls-terminated-tcp://localhost:3000/foo`).\r\n\r\n## [Use HTTPS and HTTP servers](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#use-https-and-http-servers)\r\n\r\n```shell\r\ntailscale funnel --https=<port> <target> [off]\r\n```\r\n\r\nThe `funnel` offers an HTTPS server that has a few modes: a reverse proxy, a file server, and a static text server. HTTPS traffic is secured using an automatically provisioned TLS certificate. By default, termination is done by your node's Tailscale daemon itself.\r\n\r\n- `--https=<port>` Specifies the port to listen on. For Funnel, you must use one of the allowed ports: `443`, `8443`, or `10000`.\r\n\r\n- `--set-path` Is a slash-separated URL path. The root-level mount point would simply be `/` and would be matched by making a request to `https://my-node.example.ts.net/`, for example. For more information on how these path patterns are matched, refer to the Go [ServeMux](https://pkg.go.dev/net/http#ServeMux) documentation. Our mount points behave similarly.\r\n\r\n- `<target>` Funnel provides 4 options for serving content: an HTTP reverse proxy, a file, a directory, and static text. A reverse proxy lets you forward requests to a local HTTP web server. Providing a local file path provides the ability to serve files or directories of files. Serving static text is available mostly for debugging purposes and serves a static response.\r\n  - **Reverse proxy**\r\n\r\n    To serve as a reverse proxy to a local backend, provide the location of the `<target>` argument. The location to the local service can be expressed as a port number (for example, `3000`), a partial URL (for example, `localhost:3000`), or a full URL including a path (for example, `tls-terminated-tcp://localhost:3000/foo`). Note that only `http://127.0.0.1` is currently supported for proxies.\r\n\r\n    Example: `tailscale funnel localhost:3000`\r\n\r\n  - **File server**\r\n\r\n    Provide a full, absolute path, to the file or directory of files you wish to serve. If a directory is specified, this will render a simple directory listing with links to files and subdirectories.\r\n\r\n    Example: `tailscale funnel /home/alice/blog/index.html`\r\n\r\n    Due to macOS app sandbox limitations, this option is only available when using Tailscale's [open source variant](https://tailscale.com/docs/concepts/macos-variants). If you've installed Tailscale on macOS through the Mac App Store or as a Standalone variant system extension, you can use Funnel to share ports but not files or directories.\r\n\r\n  - **Static text server**\r\n\r\n    Specifying `text:<value>` as a `<target>` configures a simple static plain-text server.\r\n\r\n    Example: `tailscale funnel text:\"Hello, world!\"`\r\n\r\n## [Use the PROXY protocol](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#use-the-proxy-protocol)\r\n\r\n```shell\r\ntailscale funnel --proxy-protocol=<version> <target>\r\n```\r\n\r\nFor most situations, users will likely use version `2`.\r\n\r\nThe [PROXY protocol](https://www.haproxy.com/blog/use-the-proxy-protocol-to-preserve-a-clients-ip-address) is a minimal network protocol that preserves information about a proxied connection (typically, the source IP address) through a proxy or load balancer and to the backend target. This lets the service that you're exposing with Funnel determine the original IP address and port for connecting clients.\r\n\r\nFor example:\r\n\r\n```shell\r\ntailscale funnel --proxy-protocol=2 --tls-terminated-tcp=443 tcp://127.0.0.1:9899\r\n```\r\n\r\nThis command will return information similar to the following:\r\n\r\n```shell\r\nAvailable on the internet:\r\n\r\n|-- tcp://funnel-test.example.ts.net:443 (TLS terminated, PROXY protocol v2)\r\n|-- tcp://100.101.102.103:443\r\n|-- tcp://[fd7a:115c:a1e0::1111:2222]:443\r\n|--> tcp://127.0.0.1:9899\r\n\r\nPress Ctrl+C to exit.\r\n```\r\n\r\nThe backend (running on `localhost:9899`) then gets the original source IP and port through the PROXY protocol.\r\n\r\n## [Use a TCP forwarder](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#use-a-tcp-forwarder)\r\n\r\n```shell\r\ntailscale funnel --tcp=<port> tcp://localhost:<local-port> [off]\r\ntailscale funnel --tls-terminated-tcp=<port> tcp://localhost:<local-port> [off]\r\n```\r\n\r\nThe `funnel` command offers a TCP forwarder to forward TLS-terminated TCP packets to a local TCP server like Caddy or other TCP-based protocols such as SSH or RDP. By default, the TCP forwarder forwards raw packets.\r\n\r\n- `--tcp=<port>` Sets up a raw TCP forwarder listening on the specified port. For Funnel, you must use one of the allowed ports: `443`, `8443`, or `10000`.\r\n\r\n- `--tls-terminated-tcp=<port>` Sets up a TLS-terminated TCP forwarder listening on the specified port. For Funnel, you must use one of the allowed ports: `443`, `8443`, or `10000`.\r\n\r\n\r\n## [Use valid certificates](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#use-valid-certificates)\r\n\r\n```shell\r\ntailscale funnel <https:target>\r\n```\r\n\r\nIf you have a valid certificate, use `https` in the `<target>` argument.\r\n\r\nExample: `tailscale funnel https://localhost:8443`\r\n\r\n## [Ignore invalid and self-signed certificate checks](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#ignore-invalid-and-self-signed-certificate-checks)\r\n\r\n```shell\r\ntailscale funnel <https+insecure:target>\r\n```\r\n\r\nIf you run a local web server using HTTPS with a self-signed or otherwise invalid certificate, you can specify `https+insecure` as a special pseudo-protocol for your `tailscale funnel` commands.\r\n\r\nExample: `tailscale funnel https+insecure://localhost:8443`\r\n\r\n## [Get the status](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#get-the-status)\r\n\r\n```shell\r\ntailscale funnel status [--json]\r\n```\r\n\r\nTo get the status of your servers, you can use the `status` subcommand. This will list all the servers that are currently running on your node.\r\n\r\n- `--json` If you wish to get the status in JSON format, you can provide the `--json` argument.\r\n\r\nExample: `tailscale funnel status --json`\r\n\r\n## [Reset Tailscale Funnel](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#reset-tailscale-funnel)\r\n\r\n```shell\r\ntailscale funnel reset\r\n```\r\n\r\nTo clear the current `tailscale funnel` configuration, use the `reset` subcommand.\r\n\r\n## [Turn Tailscale Funnel off](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#turn-tailscale-funnel-off)\r\n\r\n- `[off]` To turn off a `tailscale funnel` command, you can add `off` to the end of the command you used to turn it on. This will remove the server from the list of active servers. In `off` commands, the `<target>` argument is optional, but all original flags are required.\r\n\r\nIf this command turned on a server:\r\n\r\n```shell\r\ntailscale funnel --https=443 /home/alice/blog/index.html\r\n```\r\n\r\nYou can turn it off by running:\r\n\r\n```shell\r\ntailscale funnel --https=443 /home/alice/blog/index.html off\r\n```\r\n\r\nYou can omit the `<target>` argument, so these 2 commands are equivalent:\r\n\r\n```shell\r\ntailscale funnel --https=443 --set-path=/foo /home/alice/blog/index.html off\r\ntailscale funnel --https=443 --set-path=/foo off\r\n```\r\n\r\n## [Effects of rebooting and restarting](https://tailscale.com/docs/reference/tailscale-cli/funnel\\#effects-of-rebooting-and-restarting)\r\n\r\nIf you use the `tailscale funnel` command with the [`-bg`](https://tailscale.com/docs/reference/tailscale-cli/funnel#funnel-command-flags) flag, it runs persistently in the background until you [turn it off](https://tailscale.com/docs/reference/tailscale-cli/funnel#turn-tailscale-funnel-off). When you reboot the device or restart Tailscale from the command line using [`tailscale down`](https://tailscale.com/docs/reference/tailscale-cli#down) and [`tailscale up`](https://tailscale.com/docs/reference/tailscale-cli#up), Funnel will automatically resume sharing.\r\n\r\nIf you use the `tailscale funnel` command without the `-bg` flag, then reboot the device or restart Tailscale from the command line, you must restart Funnel manually to resume sharing.\r\n\r\n![Project Logo](https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed)\r\n\r\nAsk AI\r\n\r\nreCAPTCHA\r\n\r\nRecaptcha requires verification.\r\n\r\nprotected by **reCAPTCHA**\r\n","html":"<h1>tailscale funnel command</h1>\n<p>Last validated: Jan 26, 2026</p>\n<p>The CLI commands for both Tailscale Funnel and Tailscale Serve have changed in the 1.52 version of the Tailscale client. If you've used Funnel or Serve in previous versions, we recommend reviewing the CLI documentation.</p>\n<p><code>tailscale funnel</code> lets you share a local service over the internet. You can also choose to use <a href=\"https://tailscale.com/docs/features/tailscale-serve\">Tailscale Serve</a> using the <a href=\"https://tailscale.com/docs/reference/tailscale-cli/serve\"><code>tailscale serve</code></a> command to limit sharing within your tailnet.</p>\n<pre><code class=\"language-shell\">tailscale funnel [flags] &#x3C;target>\n</code></pre>\n<p>Subcommands:</p>\n<ul>\n<li><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#get-the-status\"><code>status</code></a> Gets the status</li>\n<li><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#reset-tailscale-funnel\"><code>reset</code></a> Resets the configuration</li>\n</ul>\n<p>To explore various use cases and examples, refer to <a href=\"https://tailscale.com/docs/reference/examples/funnel\">Tailscale Funnel examples</a>.</p>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#funnel-command-flags\">Funnel command flags</a></h2>\n<p>Available flags:</p>\n<ul>\n<li><code>--bg</code> Determines whether the command should run as a background process.</li>\n<li><code>--https=&#x3C;port></code> Expose an HTTPS server at the specified port (default).</li>\n<li><code>--proxy-protocol=&#x3C;version></code> PROXY protocol version (1 or 2) for TCP forwarding.</li>\n<li><code>--set-path=&#x3C;path></code> Appends the specified path to the base URL for accessing the underlying service.</li>\n<li><code>--tcp=&#x3C;port></code> Expose a TCP forwarder to forward TCP packets at the specified port.</li>\n<li><code>--tls-terminated-tcp=&#x3C;port></code> Expose a TCP forwarder to forward TLS-terminated TCP packets at the specified port.</li>\n<li><code>--yes</code> Update without interactive prompts.</li>\n</ul>\n<p>The <code>tailscale funnel</code> command accepts a target that can be a file, directory, text, or most commonly, the location to a service running on the local machine. The location to the local service can be expressed as a port number (for example, <code>3000</code>), a partial URL (for example, <code>localhost:3000</code>), or a full URL including a path (for example, <code>tls-terminated-tcp://localhost:3000/foo</code>).</p>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#use-https-and-http-servers\">Use HTTPS and HTTP servers</a></h2>\n<pre><code class=\"language-shell\">tailscale funnel --https=&#x3C;port> &#x3C;target> [off]\n</code></pre>\n<p>The <code>funnel</code> offers an HTTPS server that has a few modes: a reverse proxy, a file server, and a static text server. HTTPS traffic is secured using an automatically provisioned TLS certificate. By default, termination is done by your node's Tailscale daemon itself.</p>\n<ul>\n<li>\n<p><code>--https=&#x3C;port></code> Specifies the port to listen on. For Funnel, you must use one of the allowed ports: <code>443</code>, <code>8443</code>, or <code>10000</code>.</p>\n</li>\n<li>\n<p><code>--set-path</code> Is a slash-separated URL path. The root-level mount point would simply be <code>/</code> and would be matched by making a request to <code>https://my-node.example.ts.net/</code>, for example. For more information on how these path patterns are matched, refer to the Go <a href=\"https://pkg.go.dev/net/http#ServeMux\">ServeMux</a> documentation. Our mount points behave similarly.</p>\n</li>\n<li>\n<p><code>&#x3C;target></code> Funnel provides 4 options for serving content: an HTTP reverse proxy, a file, a directory, and static text. A reverse proxy lets you forward requests to a local HTTP web server. Providing a local file path provides the ability to serve files or directories of files. Serving static text is available mostly for debugging purposes and serves a static response.</p>\n<ul>\n<li>\n<p><strong>Reverse proxy</strong></p>\n<p>To serve as a reverse proxy to a local backend, provide the location of the <code>&#x3C;target></code> argument. The location to the local service can be expressed as a port number (for example, <code>3000</code>), a partial URL (for example, <code>localhost:3000</code>), or a full URL including a path (for example, <code>tls-terminated-tcp://localhost:3000/foo</code>). Note that only <code>http://127.0.0.1</code> is currently supported for proxies.</p>\n<p>Example: <code>tailscale funnel localhost:3000</code></p>\n</li>\n<li>\n<p><strong>File server</strong></p>\n<p>Provide a full, absolute path, to the file or directory of files you wish to serve. If a directory is specified, this will render a simple directory listing with links to files and subdirectories.</p>\n<p>Example: <code>tailscale funnel /home/alice/blog/index.html</code></p>\n<p>Due to macOS app sandbox limitations, this option is only available when using Tailscale's <a href=\"https://tailscale.com/docs/concepts/macos-variants\">open source variant</a>. If you've installed Tailscale on macOS through the Mac App Store or as a Standalone variant system extension, you can use Funnel to share ports but not files or directories.</p>\n</li>\n<li>\n<p><strong>Static text server</strong></p>\n<p>Specifying <code>text:&#x3C;value></code> as a <code>&#x3C;target></code> configures a simple static plain-text server.</p>\n<p>Example: <code>tailscale funnel text:\"Hello, world!\"</code></p>\n</li>\n</ul>\n</li>\n</ul>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#use-the-proxy-protocol\">Use the PROXY protocol</a></h2>\n<pre><code class=\"language-shell\">tailscale funnel --proxy-protocol=&#x3C;version> &#x3C;target>\n</code></pre>\n<p>For most situations, users will likely use version <code>2</code>.</p>\n<p>The <a href=\"https://www.haproxy.com/blog/use-the-proxy-protocol-to-preserve-a-clients-ip-address\">PROXY protocol</a> is a minimal network protocol that preserves information about a proxied connection (typically, the source IP address) through a proxy or load balancer and to the backend target. This lets the service that you're exposing with Funnel determine the original IP address and port for connecting clients.</p>\n<p>For example:</p>\n<pre><code class=\"language-shell\">tailscale funnel --proxy-protocol=2 --tls-terminated-tcp=443 tcp://127.0.0.1:9899\n</code></pre>\n<p>This command will return information similar to the following:</p>\n<pre><code class=\"language-shell\">Available on the internet:\r\n\r\n|-- tcp://funnel-test.example.ts.net:443 (TLS terminated, PROXY protocol v2)\r\n|-- tcp://100.101.102.103:443\r\n|-- tcp://[fd7a:115c:a1e0::1111:2222]:443\r\n|--> tcp://127.0.0.1:9899\r\n\r\nPress Ctrl+C to exit.\n</code></pre>\n<p>The backend (running on <code>localhost:9899</code>) then gets the original source IP and port through the PROXY protocol.</p>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#use-a-tcp-forwarder\">Use a TCP forwarder</a></h2>\n<pre><code class=\"language-shell\">tailscale funnel --tcp=&#x3C;port> tcp://localhost:&#x3C;local-port> [off]\r\ntailscale funnel --tls-terminated-tcp=&#x3C;port> tcp://localhost:&#x3C;local-port> [off]\n</code></pre>\n<p>The <code>funnel</code> command offers a TCP forwarder to forward TLS-terminated TCP packets to a local TCP server like Caddy or other TCP-based protocols such as SSH or RDP. By default, the TCP forwarder forwards raw packets.</p>\n<ul>\n<li>\n<p><code>--tcp=&#x3C;port></code> Sets up a raw TCP forwarder listening on the specified port. For Funnel, you must use one of the allowed ports: <code>443</code>, <code>8443</code>, or <code>10000</code>.</p>\n</li>\n<li>\n<p><code>--tls-terminated-tcp=&#x3C;port></code> Sets up a TLS-terminated TCP forwarder listening on the specified port. For Funnel, you must use one of the allowed ports: <code>443</code>, <code>8443</code>, or <code>10000</code>.</p>\n</li>\n</ul>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#use-valid-certificates\">Use valid certificates</a></h2>\n<pre><code class=\"language-shell\">tailscale funnel &#x3C;https:target>\n</code></pre>\n<p>If you have a valid certificate, use <code>https</code> in the <code>&#x3C;target></code> argument.</p>\n<p>Example: <code>tailscale funnel https://localhost:8443</code></p>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#ignore-invalid-and-self-signed-certificate-checks\">Ignore invalid and self-signed certificate checks</a></h2>\n<pre><code class=\"language-shell\">tailscale funnel &#x3C;https+insecure:target>\n</code></pre>\n<p>If you run a local web server using HTTPS with a self-signed or otherwise invalid certificate, you can specify <code>https+insecure</code> as a special pseudo-protocol for your <code>tailscale funnel</code> commands.</p>\n<p>Example: <code>tailscale funnel https+insecure://localhost:8443</code></p>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#get-the-status\">Get the status</a></h2>\n<pre><code class=\"language-shell\">tailscale funnel status [--json]\n</code></pre>\n<p>To get the status of your servers, you can use the <code>status</code> subcommand. This will list all the servers that are currently running on your node.</p>\n<ul>\n<li><code>--json</code> If you wish to get the status in JSON format, you can provide the <code>--json</code> argument.</li>\n</ul>\n<p>Example: <code>tailscale funnel status --json</code></p>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#reset-tailscale-funnel\">Reset Tailscale Funnel</a></h2>\n<pre><code class=\"language-shell\">tailscale funnel reset\n</code></pre>\n<p>To clear the current <code>tailscale funnel</code> configuration, use the <code>reset</code> subcommand.</p>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#turn-tailscale-funnel-off\">Turn Tailscale Funnel off</a></h2>\n<ul>\n<li><code>[off]</code> To turn off a <code>tailscale funnel</code> command, you can add <code>off</code> to the end of the command you used to turn it on. This will remove the server from the list of active servers. In <code>off</code> commands, the <code>&#x3C;target></code> argument is optional, but all original flags are required.</li>\n</ul>\n<p>If this command turned on a server:</p>\n<pre><code class=\"language-shell\">tailscale funnel --https=443 /home/alice/blog/index.html\n</code></pre>\n<p>You can turn it off by running:</p>\n<pre><code class=\"language-shell\">tailscale funnel --https=443 /home/alice/blog/index.html off\n</code></pre>\n<p>You can omit the <code>&#x3C;target></code> argument, so these 2 commands are equivalent:</p>\n<pre><code class=\"language-shell\">tailscale funnel --https=443 --set-path=/foo /home/alice/blog/index.html off\r\ntailscale funnel --https=443 --set-path=/foo off\n</code></pre>\n<h2><a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#effects-of-rebooting-and-restarting\">Effects of rebooting and restarting</a></h2>\n<p>If you use the <code>tailscale funnel</code> command with the <a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#funnel-command-flags\"><code>-bg</code></a> flag, it runs persistently in the background until you <a href=\"https://tailscale.com/docs/reference/tailscale-cli/funnel#turn-tailscale-funnel-off\">turn it off</a>. When you reboot the device or restart Tailscale from the command line using <a href=\"https://tailscale.com/docs/reference/tailscale-cli#down\"><code>tailscale down</code></a> and <a href=\"https://tailscale.com/docs/reference/tailscale-cli#up\"><code>tailscale up</code></a>, Funnel will automatically resume sharing.</p>\n<p>If you use the <code>tailscale funnel</code> command without the <code>-bg</code> flag, then reboot the device or restart Tailscale from the command line, you must restart Funnel manually to resume sharing.</p>\n<p><img src=\"https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed\" alt=\"Project Logo\"></p>\n<p>Ask AI</p>\n<p>reCAPTCHA</p>\n<p>Recaptcha requires verification.</p>\n<p>protected by <strong>reCAPTCHA</strong></p>\n"}