tunnel CLI and its QUIC data-plane engine drive the tunnel
modality. There is no typed Tunnel SDK class today.
A programmatic client, which embeds a tunnel in your own process, is
Preview. See Programmatic API (Preview) at the
bottom. For shipping work, use the CLI documented here.
Install
Save a key
A tunnel uses an API key (rtk_…). Create the key in the Tunnel console
on the API keys page, then save it on the machine:
TUNNEL_AUTHTOKEN instead.
The CLI also reads the old RNP_AUTHTOKEN variable.
tunnel login opens the browser to sign in. Use it only for key and domain
commands. The CLI does not save the sign-in session.
The CLI was named
rnp before. The CLI still runs when you start it as rnp,
and it shows one warning line.Command surface
The commands
claim, devices, topup and logout are removed. Use
tunnel domains add and tunnel keys.
http — expose a local service
localhost:<local-port>. It prints the public URL and runs until
you interrupt it.
int
required
The local TCP port to expose (e.g.
3000).string
The public hostname, for example
acme.rnp.sh or your own domain
(tunnel.example.com). Add the domain on the Domains page of the Tunnel
console, or with tunnel domains add, before you use it.tcp, udp and connect — private raw services
tunnel tcp and tunnel udp share a raw service privately under a name.
tunnel connect reaches it from another machine. The other machine uses a key
of the same organization, or a key that is bound to the name.
p2p — direct peer-to-peer
Two peers run with the same pair-id. They discover each other through the
control-plane rendezvous and connect directly. The edge brokers candidates
but never carries bytes. Across NATs, set the TUNNEL_STUN env var to a
reflector, so each side can gather its public candidate.
string
required
A shared secret that both peers know. It gates the direct tunnel and keys the
rendezvous.
int
(share) The local service port to expose to the peer.
int
(connect) A local port to listen on. The CLI pipes connections to it through
to the peer’s shared service.
string
default:"tcp"
(share)
tcp, udp, or http.string
The STUN reflector
host:port for reflexive candidate gathering. You can set
TUNNEL_STUN instead.When the punch fails
Two subscribers of one carrier NAT often cannot reach each other directly. The connect side can then route through the relay:--relay over plain TCP. That port is the sharer’s ordinary raw
TCP tunnel on the PoP.
Endpoint-independent (cone) NATs punch through directly. Symmetric NATs fall
back to the relayed path.
status
status uses the saved key. It does not need a sign-in.
Config
The CLI keeps its config file in your user config directory (mode0600).
The file holds the API key (authtoken), the control-plane base URL, and
optional named tunnels for tunnel start. A flag wins over an environment
variable, and an environment variable wins over the file.
Environment variables
Each variable has theTUNNEL_ prefix. The CLI also reads the old RNP_
name of each variable when the TUNNEL_ name is not set.
Data-plane engine flags
tunnel http execs the QUIC engine (tunnel-engine)
with the resolved arguments. You rarely call the engine directly, but the
surface is:
Remote desktop on the same transport
A remote-desktop client (a fork of an open-source remote-desktop project) runs its network transport over this same raw-QUIC relay instead of its own rendezvous/relay. To enable it, point the client’squic-relay-server option
at a host:port that runs the tunnel module:
- The controlled box registers its device id as a slug (
"proto":"quick") and parks bidi work streams. - The controller dials the box by slug. The edge splices the two QUIC streams.
- The remote-desktop client’s own message framing and end-to-end encryption ride unchanged on top. The edge only secures the QUIC hop to the PoP. It never sees cleartext.
Programmatic API (Preview)
- TypeScript (Preview)
- Python (Preview)
Related
- Tunnel overview — wire model & architecture
- Cookbook — task snippets
- Recipes — worked examples