http_registerHTTP / HTTPS tunnels
Publish a local web service on a fixed subdomain. The server issues Let's Encrypt certificates automatically and gives you request logs and replay.
Publish a local HTTP / TCP service on a fixed public domain — or mirror a remote port to your machine through a direct P2P connection. No public IP, no network changes.
cargo install --git https://github.com/zeaphoo/telesh telesh// 01 — Features
telesh is both a publisher and a visitor: push your local services out to the internet, or pull remote services in. The control plane carries only small messages; the data plane runs on its own QUIC / yamux connections.
http_registerPublish a local web service on a fixed subdomain. The server issues Let's Encrypt certificates automatically and gives you request logs and replay.
tcp_registerMap any TCP service — SSH, databases, game servers — to a public port on the server. No gateway code to write.
iroh · QUICHole-punched QUIC via iroh. Traffic flows peer to peer and never touches the server; if hole punching fails it falls back to an encrypted relay.
lookup + mirrorMap a remote host's port onto a local listening port and debug a remote environment as if it were local. Reconnects after drops.
127.0.0.1:16345A long-running agent discovers local listening ports; toggle publishing and watch a live request log at 127.0.0.1:16345.
server.tomlOne server.toml starts the control plane, the data plane and an embedded iroh relay, with ACME, TLS and QUIC address discovery.
// 02 — How it works
One long-lived connection carries only small messages (login, subdomains, directory, keepalive); the actual bytes travel on an independent data plane. The control protocol can evolve while the forwarding path keeps its raw throughput.
The agent dials out to the server. Public traffic arrives at the edge and is forwarded to your local port over the data plane.
The server only handles directory lookup and token checks; the payload travels over a hole-punched QUIC connection, not through the server.
Control plane
WebSocket · JSON
login / subdomains / directory / keepalive
Data plane
QUIC · yamux
public forwarding and P2P payload
Authorization
Short-lived tokens
verified online, scoped to account/name
// 03 — Use cases
Whenever there is a missing path between local and remote, telesh closes the gap.
Point Stripe / GitHub / payment callbacks straight at your laptop, inspect headers and responses live, and replay with one click.
Expose internal SSH / RDP on a public port via a TCP tunnel and reach your machines from anywhere.
Hand a colleague or client a fixed domain and let them view your local build in a browser — no test deployment needed.
Mirror a staging database port to your machine and connect with your usual client, without a bastion or port forwarding.
Map the NAS, media library or smart-home hub at home to your machine over P2P — no router port forwarding.
Let a device dial out and register with the server, then reach its debug endpoints and monitoring pages in reverse.
// 04 — Quick start
The CLI has a single flag (the data directory); everything else happens in the local UI.
Install from source with cargo, or grab the single-file binary for your platform from Releases.
One line is enough. If the config file is missing, a default one is generated for you.
The agent discovers local listening ports; pick HTTP / TCP / P2P for the ones you want to publish.
Fixed at http://127.0.0.1:16345. It only listens on loopback and is never exposed.
1 · Install
# Install from source (requires Rust 1.91+)
cargo install --git https://github.com/zeaphoo/telesh telesh2 · Configure
# The control server to connect to; default port is 9009
control_server = "tunnel.example.com:9009"3 · Start
# Uses the default data directory ~/.telesh
$ telesh
info agent starting server=tunnel.example.com:9009 ui=127.0.0.1:16345Want to host the server yourself? See Server deployment
// 05 — Compare
Beyond publishing to the internet, telesh adds the reverse path: pulling a remote port safely down to your machine.
| telesh | ngrok | frp | Cloudflare Tunnel | |
|---|---|---|---|---|
| Open source · fully self-hostable | open-source client | |||
| No public IP required | ||||
| Direct P2P (payload bypasses the server) | ||||
| Mirror a remote port locally | ||||
| Control plane / data plane separation | ||||
| Fixed domain + automatic HTTPS | configure yourself |
Compiled from each project's public documentation, for reference only. Corrections welcome on GitHub.
// 06 — FAQ
telesh publishes local ports to the internet like ngrok / frp, and also mirrors remote ports back to your machine. Connections prefer a direct P2P hole punch and only fall back to an encrypted relay when that fails; the server keeps its control plane and data plane on separate channels.
The machine running the agent does not need a public IP — it dials out from behind NAT. You only need one machine with a public address to run telesh-server, or you can use a server someone else has deployed.
In P2P mode the payload travels over the hole-punched QUIC connection and does not pass through the server; it only falls back to the encrypted relay when a direct path cannot be established. Public HTTP / TCP tunnel traffic is forwarded through the server's edge.
Devices and accounts log in with an Ed25519 key pair using a challenge–response flow, creating the account on first login (TOFU). To reach a service, the server issues a short-lived opaque access token scoped to account/name; the agent verifies it online with the server. The server only stores token hashes, so there is no key to protect on the data plane.
telesh is written in Rust and ships as a single binary with no runtime dependencies. It runs on Linux, macOS and Windows, and works inside containers, where it discovers only the ports inside the container.
A single long-running agent manages many tunnels at once: the same local port can be published as HTTP, TCP and P2P, and you can declare multiple mirror entries — no need for a separate process per port.
Three commands to get going; the rest happens in the GUI.