Expose local servers
to the internet

One command. No port forwarding, no configuration files. Your local port instantly becomes a public address on tun.expose.2bd.net.

$ curl -sSL https://expose.2bd.net/install.sh | sh
$ expose 22
 
Tunnel is up!
tun.expose.2bd.net:23100 → 127.0.0.1:22
 
Connect to: tun.expose.2bd.net:23100
 
$ ssh -p 23100 you@tun.expose.2bd.net
Install expose How it works

How it works

Three steps and your local service is reachable from anywhere.

1

Install

One-liner for Linux & macOS, or grab a static binary for your platform. No dependencies, no daemons.

2

Expose a port

Run expose 22. The backend picks a random free public port and prints tun.expose.2bd.net:PORT.

3

Share the address

Anyone on the internet can connect to tun.expose.2bd.net:PORT — it lands on your local service. Stop the process and the tunnel is gone.


Features

Small, fast, and opinionated about not getting in your way.

🎲

Random public ports

Each tunnel gets a random free port in 1000–60000. Well-known ports (80, 443, 8080, 25565, …) and busy local ports are never used.

🔌

Any TCP protocol

SSH, Minecraft, HTTP, PostgreSQL, VNC — expose works with any TCP service, encrypted or not.

📦

Single static binary

One ~6 MB binary, zero dependencies. Linux, macOS and Windows; amd64 and arm64.

🔒

Encrypted control channel

The tunnel is set up and carried over a WebSocket secured with TLS (Let's Encrypt). Your protocol's own encryption still applies.

🏠

No port forwarding

Works from behind NAT and CGNAT. The client connects outbound — nothing to open on your router.

🪶

Simple by design

No accounts, no dashboards, no plans, no telemetry. One command — and stop the process whenever you want.


Use cases

Anything that listens on a local port.

🖥️ SSH into your home machine

Remote into a laptop or server at home without touching the router.

expose 22
ssh -p 23100 you@tun.expose.2bd.net

🌐 Share a web app or test webhooks

Let Stripe, GitHub or a friend see your dev server instantly.

expose 3000
# → tun.expose.2bd.net:48211

🎮 Game servers

Minecraft, Valheim, S&T — share the address with friends.

expose 25565
# server address: tun.expose.2bd.net:17342

🗄️ Internal services

Databases, admin panels, APIs on your LAN — temporarily reachable from outside.

expose 5432 --bind 192.168.1.20

Install

The installer detects your platform and drops a static binary into your PATH.

curl -sSL https://expose.2bd.net/install.sh | sh
linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64

Usage: expose <port> [--bind 127.0.0.1] [--server wss://expose.2bd.net/tunnel]


FAQ

Short answers to common questions.

Is it free?

Yes. There are no paid plans, quotas or speed limits — just be a good citizen and don't abuse it.

What happens when I stop the client?

The tunnel closes immediately and the public port is released back to the pool. Restarting the client gets you a new random port.

Is my traffic encrypted?

The control channel (client ↔ backend) is a TLS-secured WebSocket. The data plane is raw TCP: protocols like SSH or Minecraft encrypt their own traffic, while plain HTTP is sent unencrypted between the visitor and your service.

Why a random port instead of a fixed one?

Random ports keep tunnels unique and make the service stateless — no port reservations, no conflicts, no way to guess someone else's tunnel.

Can I choose my own port or subdomain?

Not yet. Every tunnel lives on tun.expose.2bd.net with a random port. Subdomains are reserved for the tunnel host.

What ports can I expose?

Any local TCP port from 1 to 65535. The public side is always a random port in 1000–60000, excluding well-known and locally busy ports.

What if the connection drops?

The client reconnects automatically (1s, 2s, 4s, … up to 60s between attempts). When it comes back you get a new random port — the new address is printed in the terminal.

Does expose update itself?

Yes. On start and every 30 minutes the client checks for a newer version, downloads and verifies the new binary, then restarts itself. If the binary's folder is not writable it just tells you to re-run the install one-liner.