Skip to content

cmd/tailcat: add forward subcommand - #62

Open
Audi-dask wants to merge 1 commit into
tailscale:mainfrom
Audi-dask:cmd-forward
Open

cmd/tailcat: add forward subcommand#62
Audi-dask wants to merge 1 commit into
tailscale:mainfrom
Audi-dask:cmd-forward

Conversation

@Audi-dask

@Audi-dask Audi-dask commented Sep 2, 2026

Copy link
Copy Markdown

What does this change do?

Add a tailcat forward subcommand for exposing TCP ports served by a
Tailcat server as ordinary local TCP listeners.

This is useful for browsers, database clients, IDEs, and other
applications that only support regular host:port connections and do
not provide Tailcat, SOCKS, or stdio proxy integration.

The <addrblob> argument is the address blob printed by tailcat serve,
typically a value beginning with tc.

Related to #14.

Examples

Start a Tailcat server:

tailcat serve 8080
# Server listening with new address: tcXXXXXXXXX

Forward the served port to the same local port:

tailcat forward tcXXXXXXXXX 8080

This forwards:

127.0.0.1:8080 -> Tailcat -> remote localhost:8080

Use a different local port:

tailcat forward tcXXXXXXXXX 18080:8080

Forward multiple ports:

tailcat serve 3306,6379
# Server listening with new address: tcXXXXXXXXX

tailcat forward tcXXXXXXXXX 3306:3306 6379:6379

Bind the local listener to a specific address:

tailcat forward --bind=192.168.1.100 tcXXXXXXXXX 18080:8080

Use --bind=0.0.0.0 only when intentionally allowing connections
from other network interfaces:

tailcat forward --bind=0.0.0.0 tcXXXXXXXXX 18080:8080

Design

  • Reuses one Tailcat client for all forwarded ports.
  • Uses the existing Client.DialTCPPort API.
  • Uses the existing ProxyConns helper.
  • Supports both <remote> and <local>:<remote> mappings.
  • Supports multiple local-to-remote port mappings.
  • Binds to 127.0.0.1 by default.
  • Supports an explicit local bind address with --bind.
  • Does not change the Tailcat protocol or server behavior.
  • Does not introduce a new dependency.

Testing

  • Added unit tests for local and remote port mapping parsing.
  • Added CLI command tree coverage for the forward subcommand.
  • Added an end-to-end TCP forwarding test using the existing local DERP,
    STUN, and Tailcat server test environment.
  • The end-to-end test waits for the local listener by retrying TCP
    connections instead of parsing diagnostic logs.

Tested with:

GOMAXPROCS=2 go test ./...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant