HTTP / HTTPS, TCP, UDP, gRPC, SSH, and HTTP/3 — same
mytunnel binary, same auth token, same dashboard.
Pick the protocol that fits your service; the agent figures
the rest out.
The default. Random subdomain on the free tier; reserved subdomain on Pro. Server-side TLS is handled — your local service stays plain HTTP.
mytunnel http 3000 ✓ https://kind-otter-7f.21tunnel.com → localhost:3000 Subdomain changes on each restart unless you reserve it.
Reserve a label once in the dashboard, then pass it on the CLI:
mytunnel http 3000 --subdomain myapp ✓ https://myapp.21tunnel.com → localhost:3000
Stable across restarts. Sticky subdomains
(free) try to give you back the same random label on
reconnect via the ~/.config/mytunnel/sticky-subdomains.json
cache — but only the reserved version is guaranteed.
Bring your own hostname. Register it in the dashboard, set a CNAME at your DNS provider, point the tunnel at it on launch:
mytunnel http 3000 --subdomain myapp
# DNS at your provider:
# app.acme.com CNAME abc-cname.21tunnel.com.
Edge-auth (Google OAuth gate) only applies to
*.21tunnel.com hosts. Custom domains are exempt
because cookies can't span arbitrary apexes — gate at the
origin instead.
Raw bytes. Use for databases, Redis, custom binary protocols,
or anything that's not HTTP. The server allocates a public
TCP port (or honours --public-port N if you ask).
mytunnel tcp 5432 ✓ tcp://abc.21tunnel.com:30417 → localhost:5432 Allocated from the operator's tcp_proxy_port_range
(default 30000-30999). Connect like:
psql -h abc.21tunnel.com -p 30417 -U app dbname Want the same port every time? Pass it explicitly:
mytunnel tcp 5432 --public-port 35432 ✓ tcp://abc.21tunnel.com:35432 → localhost:5432
Must lie in tcp_proxy_port_range; the server
returns PORT_UNAVAILABLE if the port is out of
range or already held by another agent. Useful for
scp -P, RDP (--public-port 3389),
fixed-port firewall allowlists.
# Postgres preview for a colleague
mytunnel tcp 5432 --public-port 35432
# Redis dev box for a teammate
mytunnel tcp 6379 --public-port 36379
# Local RDP target
mytunnel tcp 3389 --public-port 33389
# Whatever raw TCP protocol you're building
mytunnel tcp 9001 Public UDP datagrams to your localhost service. Most tunnel services charge extra for UDP; ours is in the base tier. Use cases: DNS, game servers (Minecraft Bedrock), WireGuard, VoIP, custom UDP protocols.
mytunnel udp 19132 --public-port 19132 ✓ udp://abc.21tunnel.com:19132 → localhost:19132 Friends connect with the standard Bedrock client at
abc.21tunnel.com:19132.
mytunnel udp 53 --public-port 31300 Then any client can query:
dig @abc.21tunnel.com -p 31300 example.com mytunnel udp 51820 --public-port 31820 Public peers handshake even when your host is behind a
carrier-grade NAT. Each (src_addr, src_port) is
tracked as its own session with a 60-second idle window
(matches WireGuard keepalive defaults).
Skip --public-port and the server picks a free
one from udp_proxy_port_range:
mytunnel udp 9876 ✓ udp://abc.21tunnel.com:31042 → localhost:9876 UDP is stateless; the agent uses an ephemeral per-session socket so each remote source gets its own answer path — DNS resolvers and game clients see exactly what they'd see from a direct public connection.
Sugar over TCP mode that prints a grpcurl-ready
line on connect. Server speaks HTTP/2 directly to the
public client; no edge translation.
mytunnel grpc ✓ tcp://abc.21tunnel.com:30417 → localhost:50051
🚪 Try it: grpcurl -plaintext abc.21tunnel.com:30417 list mytunnel grpc 9090 --public-port 39090 ✓ tcp://abc.21tunnel.com:39090 → localhost:9090
🚪 Try it: grpcurl -plaintext abc.21tunnel.com:39090 list Note: gRPC tunnels use TCP mode — the URL
is host:port, not https://*.21tunnel.com.
Subdomain-routed gRPC (host-header routing for HTTP/2
streams) is on the roadmap. Clients negotiate TLS+HTTP/2 + gRPC
directly with your local service.
Sugar over TCP that prints a copy-pasteable
ssh -p <port> user@host line. Defaults to
local port 22 and the current
$USER.
mytunnel ssh ✓ tcp://abc.21tunnel.com:30417 → localhost:22
🚪 Connect from anywhere: ssh -p 30417 vikas@abc.21tunnel.com mytunnel ssh 2222 --user demo
The displayed username is cosmetic — the agent doesn't
authenticate the SSH session, your sshd does.
Lock your sshd_config down before exposing
any SSH service to the public internet:
key-only auth, no root, fail2ban.
Customers don't ask for HTTP/3 explicitly — the public edge
advertises Alt-Svc: h3=":443" on HTTP/2 responses,
and compatible clients (modern Chrome / Firefox / Safari /
curl --http3) upgrade automatically on the next
request.
curl -v --http3 https://myapp.21tunnel.com/ 2>&1 | grep -iE "HTTP/3|alt-svc|using" < alt-svc: h3=":443"; ma=86400
* using HTTP/3
< HTTP/3 200 In Chrome devtools, the Protocol column on
the Network tab shows h3 after the first
response.
On self-hosted instances, enable in /etc/qnt/server.toml
under [http3]. See the
admin guide for the
full step list including the LXC iptables UDP/443 DNAT.