DOCS · TUNNEL TYPES

Six protocols. One CLI.

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.

1 HTTP / HTTPS

The default. Random subdomain on the free tier; reserved subdomain on Pro. Server-side TLS is handled — your local service stays plain HTTP.

Random subdomain (free)

mytunnel http 3000
 https://kind-otter-7f.21tunnel.com → localhost:3000

Subdomain changes on each restart unless you reserve it.

Reserved subdomain Pro

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.

Custom domain

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.

2 TCP + reserved port

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).

Random port

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

Reserved port Pro

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.

Real examples

# 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

3 UDP

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.

Minecraft Bedrock

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.

DNS over UDP

mytunnel udp 53 --public-port 31300

Then any client can query:

dig @abc.21tunnel.com -p 31300 example.com

WireGuard endpoint behind NAT

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).

Random UDP port

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.

4 gRPC

Sugar over TCP mode that prints a grpcurl-ready line on connect. Server speaks HTTP/2 directly to the public client; no edge translation.

Default port (50051)

mytunnel grpc
 tcp://abc.21tunnel.com:30417 → localhost:50051
🚪 Try it:  grpcurl -plaintext abc.21tunnel.com:30417 list

Custom port + reserved public port

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.

5 SSH

Sugar over TCP that prints a copy-pasteable ssh -p <port> user@host line. Defaults to local port 22 and the current $USER.

Default (port 22, current user)

mytunnel ssh
 tcp://abc.21tunnel.com:30417 → localhost:22
🚪 Connect from anywhere:  ssh -p 30417 vikas@abc.21tunnel.com

Custom port + user override

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.

6 HTTP/3

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.

Verify h3 is working

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.

What you get

  • Faster first byte over lossy networks (no TCP head-of-line blocking).
  • Quicker reconnect after IP changes (connection migration).
  • Zero CLI flag — every HTTP tunnel is HTTP/3-eligible automatically.

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.

Next