Menu

Introduction

tnnl exposes a service running on your machine to a public URL in one command — over HTTPS, on your own domain, behind real authentication. No reverse proxies, no port forwarding, no firewall changes.

$ tnnl http 3000
  Tunnel ready:  https://flying-bird-4024.tnnl.uz

What it does

You run a local server — a web app, an API, an SSH daemon, a database — and tnnl gives the outside world a stable, encrypted address that routes straight back to it. Useful for sharing work in progress, testing webhooks, demoing to a client, or reaching a home machine.

Unlike anonymous tunneling tools, tnnl is account-controlled: tunneling requires logging in, and an admin provisions the accounts. It's built to be self-hosted, so your traffic and your domain stay yours.

How it works

There are three pieces:

  • The server runs on a public host (e.g. tnnl.uz) with a wildcard domain. It accepts public traffic and routes each request to the right tunnel.
  • The CLI (tnnl) runs on your machine, opens one outbound connection to the server, and forwards traffic to your local port.
  • A tunnel is a single multiplexed connection (yamux) between the two. Every public request becomes a stream on that one connection — fast, ordered, and firewall-friendly because the CLI dials out (nothing needs to be open on your side).

HTTP tunnels are routed by the Host header, so many tunnels share one public port (443). TCP tunnels each get their own public port.

One connection, many requests
The CLI never needs an inbound port. It keeps a single connection open to the server and the server pushes work down it, so tnnl works from behind NAT, Wi-Fi, and corporate firewalls.

Two tunnel types

  • HTTPtnnl http 3000 gives a public HTTPS URL. Routed by hostname, so you get a friendly subdomain, a name you pick, or your own custom domain.
  • TCPtnnl tcp 22 exposes a raw byte stream (SSH, Postgres, Redis, game servers) on a dedicated public port.

Next steps