CHAN.RUN

Products
Restunnel
Architecture

Protocol

Protocol

Restunnel uses the Noise Protocol Framework for transport encryption and a custom binary message protocol for tunnel operations.

Why Noise, Not TLS

TLS requires the server to respond to any client's handshake — even unauthenticated ones. This creates a fingerprintable surface. Port scanners can identify TLS servers, probe for vulnerabilities, and build target lists.

Noise (specifically Noise_IK) provides:

  • Identity-first handshake — The client must prove it holds an authorized key in the very first message. No anonymous connections possible.
  • Silent rejection — The server sends no response to unauthorized clients. The port appears closed to scanners.
  • Mutual authentication — Both hub and exit node verify each other's identity.
  • Forward secrecy — Ephemeral keys per session.
  • No certificate infrastructure — No CAs, no Let's Encrypt, no certificate expiration.

Handshake

The tunnel runs over raw TCP on port 9000. The Noise handshake uses X25519 keys for Diffie-Hellman key exchange.

Enrollment (first connection):

  1. Node knows the hub's public key from the QR code / enrollment URL
  2. Node initiates Noise_IK handshake
  3. Hub accepts the handshake (node's key is unknown but allowed during enrollment)
  4. Node sends ENROLL message with the one-time token
  5. Hub validates the token, stores the node's public key, burns the token
  6. Hub sends ENROLL_OK — enrollment complete

Reconnection (subsequent connections):

  1. Node initiates Noise_IK handshake using stored keys
  2. Hub checks the node's public key against its authorized list
  3. If recognized → tunnel established
  4. If unknown → silent drop, no response

Message Protocol

After the Noise handshake, the encrypted channel carries binary-framed messages:

┌──────────┬──────────┬───────────┬──────────────┐
│ Type (1B)│ ID (4B)  │ Len (4B)  │ Payload      │
└──────────┴──────────┴───────────┴──────────────┘

The ID field is the stream identifier — it multiplexes many TCP streams over a single tunnel per exit node.

Message Types

TypeNameDirectionPurpose
0x01ENROLLNode → HubOne-time enrollment (token + public key)
0x02ENROLL_OKHub → NodeEnrollment accepted
0x03PINGBothKeepalive (every 30s)
0x04PONGBothKeepalive response (must reply within 10s)
0x10CONNECTHub → NodeOpen TCP connection to target host
0x11CONNECT_OKNode → HubTCP connection established
0x12CONNECT_FAILNode → HubConnection failed (with reason)
0x20DATABothRaw TCP data for a stream
0x21CLOSEBothClose a stream
0x30STATUSNode → HubPeriodic status (IP, battery, bandwidth)

Enrollment Failure

There is no ENROLL_FAIL message. If the token is invalid or expired, the hub silently drops the connection — consistent with the "invisible to unauthorized" security model.

Stream Multiplexing

A single Noise session between hub and exit node carries many logical TCP streams simultaneously. The ID field in CONNECT, DATA, and CLOSE messages identifies which stream a frame belongs to.

When a SOCKS5 client on the server connects to example.com:443 through the proxy, the hub:

  1. Assigns a new stream ID
  2. Sends CONNECT example.com:443 to the exit node with that ID
  3. The exit node opens a TCP connection to the target
  4. All subsequent DATA and CLOSE frames use the same stream ID

This means one exit node can handle hundreds of concurrent connections over a single tunnel.

Keepalive

Both sides send PING every 30 seconds. The other side must respond with PONG within 10 seconds. If no response arrives, the connection is considered dead and the node begins reconnecting with exponential backoff.