Skip to content

TCP Tunnels

Give a database, game server, SSH or any raw TCP service a public host and port, reachable from anywhere, on an address that never changes.

Summary

One command gives any TCP service on your machine a public address such as example.eu.localport.dev:47266, reachable from anywhere. Databases, game servers, SSH, message brokers and protocols you wrote yourself. Reserve the port, set the subdomain, and the address is permanent.

What is a TCP tunnel?#

A TCP tunnel is a public host and port for a service on your machine. Localport accepts connections on that port and carries them to the port your service listens on. The bytes are not parsed, rewritten or inspected in transit, so any protocol behaves as it does on your own network.

The agent connects outward from your machine. Nothing on your network accepts an inbound connection, so there is no port forwarding, no firewall rule and no static IP address. It works behind carrier-grade NAT, on networks you do not administer, and on mobile connections.

An HTTP tunnel gives you a URL. A TCP tunnel gives you a host and a port, and a client needs both.

You need a Localport account, the Localport agent, and a service listening on a local TCP port.

Create a tunnel#

1. Open dashboard.localport.io and go to Tunnels.

2. Click New.

3. Enter a name, choose a region, and click Create Tunnel.

  • Name identifies the tunnel in the dashboard. It does not appear in the public address.
  • Region is EU, US or Asia Pacific, and it forms part of the address. Choose the region closest to the clients that will connect.
  • Custom Domain serves the tunnel on a domain you own. Optional, and can be attached later.
  • Force HTTPS and Delivery apply to HTTP tunnels only.

The protocol is not set here. A tunnel becomes a TCP tunnel when the agent connects with the tcp protocol.

Create your tunnel in two steps, then copy the command the dashboard builds for you.

Get your connect command#

Creating the tunnel opens the Connect step, which assembles the command for your service. The Connect button on the tunnel reopens it.

  • Preset fills in the protocol and port for you. Select your service, or select Custom and enter them yourself.
  • Protocol is tcp for anything that is not a web app. Select tls when your service holds its own certificate.
  • Local Address is where the agent delivers traffic. It defaults to localhost and accepts another machine on your network.
  • Name identifies this connection in the agent output. Leave it blank to skip.
  • Run without the live UI replaces the live panel with plain log lines. Use it on a server, in CI, and inside Docker or systemd.
  • Token is the tunnel's credential, already in the command. Treat it like a password.

For a Minecraft server on port 25565:

localport tcp 25565 --token tok_k8f2 --region eu

tcp is the protocol, 25565 is the local port, --token authenticates the tunnel, and --region matches the region you selected. Every flag is documented in the CLI reference.

Keep the token off shared command lines

On a machine other people use, a token passed as an argument appears in the process list. Set LOCALPORT_TOKEN instead, or point LOCALPORT_TOKEN_FILE at a file only your user can read. See Environment Variables.

Run the tunnel#

Run the command in a terminal.

Run the command and your public host and port appear under Forwarding.

Forwarding is the public address. Local is the port traffic is delivered to. Bandwidth and Connections update as traffic arrives, and each open connection is listed with its source address, duration and bytes transferred.

The address answers while the command runs. Press Ctrl+C to stop it, and run the command again to restore the same address.

Your permanent host and port#

Both parts of the address are set in the tunnel's settings.

Port is assigned when the tunnel connects and can change on the next connection. Click Reserve to hold the number.

Subdomain is the label in front of the address. Enter the label you want and the dashboard checks availability as you type. A subdomain is 12 characters or more, and a label is unique across every region.

Reserve the port and set the subdomain in the tunnel's settings.

Reserving a port requires the admin role. Moving the tunnel to another region releases the reserved port, and a new one is assigned in the new region.

To serve the tunnel on a domain you own, see Custom Domains.

Fix the address before you distribute it

A game server address in a group chat, an SSH config entry and a connection string in a teammate's .env are all difficult to update afterwards. Reserve the port and set the subdomain first.

Connect a client#

Distribute the host and the port. The tcp:// prefix identifies the protocol and is not part of the address.

example.eu.localport.dev:47266

Each client takes the same two values in its own syntax:

# PostgreSQL
psql -h example.eu.localport.dev -p 47266 -U myuser mydb

# SSH
ssh user@example.eu.localport.dev -p 47266

# Confirm the address answers
nc -vz example.eu.localport.dev 47266

Clients connect to the tunnel address as they would to any other host and port.

Connections are not closed for inactivity. A database connection pool or an SSH session stays open until one side closes it.

Access controls#

Anyone with the host and port, until you restrict it. A TCP tunnel carries bytes, so request-level controls do not apply. Two address rules do.

Choose who can reach your tunnel, from the tunnel's own settings.
ControlWhat it does
Inbound IP WhitelistAdmits only the addresses and CIDR ranges you list. Every other connection is closed without a response, so the port presents as closed. IP Allowlists
Network IPsLimits the addresses your own tunnel may connect from, so a leaked token cannot serve your service from elsewhere.

Both are under Network & Security. Each accepts exact addresses and CIDR ranges, and allows every address when left blank. The HTTP Protection controls on the same page inspect HTTP requests and have no effect on a TCP tunnel.

An IP allowlist suits a database or an SSH port reached from known machines. It does not suit a game server, where clients connect from addresses you cannot predict.

Control access by identity

A fleet is a group of your machines that is private by default. Every caller proves who it is before the connection is accepted, and reaches only the devices you grant it. Detailed guide: Remote Access.

Share a local database#

PostgreSQL listens on 5432. On the machine holding the database:

localport tcp 5432 --token tok_k8f2 --region eu

A teammate connects with the tunnel address and their usual credentials:

psql -h example.eu.localport.dev -p 47266 -U myuser mydb

The data never leaves your machine, and no copy is exported.

A database connection is not encrypted by default

The tunnel carries exactly what the client sends, so a PostgreSQL session without TLS crosses the internet in plaintext, credentials included. Enable TLS in PostgreSQL, and set an inbound IP allowlist to the addresses your teammates connect from.

Common uses#

Only the port changes.

  • Game servers. Minecraft on 25565, Terraria on 7777, Valheim on 2456, with no router configuration. See the game server guide.
  • Databases. PostgreSQL on 5432, so a teammate or a staging environment can query the copy on your machine.
  • SSH. Port 22, for shell access to a machine on a network you cannot reach directly.
  • A remote-controlled browser. Chrome started with --remote-debugging-port=9222 accepts Playwright and Puppeteer over that port, with its cookies, extensions and signed-in sessions.
  • Remote desktops. VNC on 5900 or RDP on 3389.
  • Devices in the field. MQTT sensors, a 3D printer, a NAS. See the homelab and IoT guides.
  • Protocols you wrote yourself. The bytes arrive exactly as sent.

Forward to another machine#

The agent delivers to localhost by default. To reach a service on another host, a container, a NAS or a Raspberry Pi, pass the address to --local with a tcp:// scheme.

localport --token tok_k8f2 --local tcp://192.168.1.50:5432 --region eu

The Local Address field in the connect sheet writes the same flag. Include the port. The agent dials the address exactly as written, and tcp://192.168.1.50 fails with missing port in address. One machine can front an entire home network this way, which the homelab guide covers in full.


Frequently asked questions#

What is the difference between a TCP tunnel and an HTTP tunnel?

An HTTP tunnel understands HTTP. It terminates HTTPS with a publicly trusted certificate, gives you a https:// URL, and can check a password, a header or a webhook signature on every request. A TCP tunnel carries raw bytes and gives you a host and a port. Every protocol that is not HTTP needs that pair. See HTTP Tunnels.

Can I use the same port every time?

Yes. Click Reserve in the Port field of the tunnel's settings and the number is held for that tunnel, so the address is identical after every restart. Set your own subdomain as well and the full host and port never change.

Can I choose my own subdomain for a TCP tunnel?

Yes. Enter it in the Subdomain field of the tunnel's settings and the address becomes example.eu.localport.dev. Availability is checked as you type, and a subdomain is 12 characters or more.

Is TCP tunnel traffic encrypted?

The link between your machine and Localport is encrypted. Beyond that a TCP tunnel is a faithful pipe and carries exactly what your service sends, so a plaintext protocol stays plaintext end to end. Use a protocol that encrypts itself, such as SSH or a database with TLS enabled, and run it with the tls protocol so the encrypted bytes pass through untouched.

My service already has its own TLS certificate. Does that work?

Yes. Run it with the tls protocol instead of tcp and the encrypted bytes pass through untouched, so the certificate clients see is still yours. The subdomain, the reserved port and the IP allowlists all behave the same way. The CLI reference lists every protocol.

How do I host a Minecraft server without port forwarding?

Run localport tcp 25565 --token YOUR_TOKEN --region eu on the machine running the server, then distribute the host and port shown under Forwarding. The connection is outbound from your machine, so no router configuration and no static IP is involved. Reserve the port first so the address stays the same. See the game server guide.

Can I expose Ollama or another local model server?

Ollama serves an HTTP API, so use an HTTP tunnel and reach it over HTTPS with no port in the address. A TCP tunnel carries it as well, and gives up the certificate and the per-request controls. See the local LLM guide.

How many clients can connect at once?

As many as your service handles. Each inbound connection is carried to your local port independently, and the live panel reports the connection count and the bandwidth of each one.

Does a TCP tunnel work behind NAT, CGNAT or a corporate firewall?

Yes. The tunnel is an outbound connection from your machine, the same kind a browser makes, so nothing has to be opened inbound. It works on home routers, on carrier-grade NAT, on university networks and on mobile connections.

Can I put a web app on a TCP tunnel?

You can, and you give up three things an HTTP tunnel provides. The publicly trusted certificate, the https:// URL with no port in it, and the checks that run on every request. Use an HTTP tunnel for anything that serves web traffic.