tcptun

Native protocol

How native works, and how to run it end to end.

Use native for tcptun-to-tcptun carriers, mux, and reverse publish. mixed / socks5 stay as authenticated local hops.

Native protocol

How native works, and how to run it end to end.

native is tcptun’s private tunnel protocol for tcptun-to-tcptun deployments. One JSON topology describes server and client; the runtime validates auth, transport, security, mux, and reverse publish before listening.

01

native

Token

The only tunnel protocol in v0.5.0. raw + mux + reality or tls with carrier.mode=auto binds TCP and UDP on one address; outbound carrier.prefer selects adaptive, quic, or tcp. Resumable streams can preserve eligible TCP flows across carrier replacement.

Interop
tcptun ↔ tcptun
Default security
REALITY or TLS, carrier.mode auto/tcp/quic
Mux
Required for auto and QUIC carriers
tcptun config native --server proxy.example.com --port 9443
01

What it is

A token-authenticated tunnel that carries TCP and UDP. The server exposes a native inbound; the client usually listens as mixed/socks5 locally and forwards through a native outbound.

02

When to use it

Use native when both ends run tcptun and you want low overhead, mux, automatic QUIC/TCP REALITY, resumable TCP streams, forced QUIC, or reverse publish of services behind NAT.

03

What you configure

Match users[].id with token, set address as host:port arrays, choose transport (prefer raw), optional security, and optional mux. Everything else is ordinary tcptun route / inbound / outbound wiring.

Core concepts

Keep these rules in mind when reading or writing native configs.

Topology

Typical path: app → local mixed :1080 → native outbound → internet → native :9443 → direct. Server and client are two configs that share credentials and security parameters.

Authentication

Server inbound users[].id must equal client outbound token. Generate long random tokens; never reuse example values like change-me in production.

Address

address is always a string array of host:port. Multiple outbound addresses race as candidate entry points for the same logical service; they are not load balancing (use balance for that).

Transport

raw is the default and best for throughput. ws / h2 / h3 are available when you need path-based fronting; QUIC mode requires raw.

Security (v0.5.0)

With native + raw + mux + security.type=reality or tls + carrier.mode=auto, the inbound binds TCP and UDP on one address. Outbound carrier.prefer selects adaptive/quic/tcp. carrier.mode=tcp|quic forces a single carrier.

Mux & resume

mux.enabled enables multiplexing and dual carriers. Optional mux.resume preserves eligible TCP streams. carrier.mode selects auto/tcp/quic independently of mux pooling knobs.

Appmixed :1080native outboundnative :9443direct

Native usage tutorial

Follow these steps for a first working native tunnel. The browser generator and URI tools on this page can replace the CLI generate / export steps if you prefer.

step01

Install tcptun

Install a binary for your platform, or use the one-line installer / npm package.

curl -fsSL https://tcptun.com/install.sh | sh
tcptun --version
step02

Generate a native pair

Create matching server.json and client.json with REALITY keys and a shared token. Prefer the CLI on the server host, or use the browser generator on this site.

tcptun config native --server proxy.example.com --port 9443 --server-name example.com --dest example.com:443
# writes server.json and client.json in the current directory (CLI defaults may vary by version flags)
step03

Edit the real endpoints

On the server config, set the native inbound listen address. On the client, set the outbound address to the public host:port, and keep token identical to users[].id.

# server inbound address → where this machine listens
# client outbound address → public host:port clients dial
# users[].id  ===  token
step04

Validate before start

config check compiles the topology without opening ports. Fix any missing keys, bad tags, or REALITY mismatches here.

tcptun config check --config server.json
tcptun config check --config client.json
step05

Start server, then client

Bring the edge up first. Then start the client so the local mixed proxy can dial the tunnel.

tcptun --config server.json
tcptun --config client.json
step06

Test the local proxy

With the client running, apps should use the local mixed inbound (default 127.0.0.1:1080).

curl -x socks5h://127.0.0.1:1080 https://example.com -I
# or point your system / app proxy to 127.0.0.1:1080

Use case

Worked native examples.

Complete server / client pairs for native. Copy a pair, replace placeholders, validate, then start the server before the client.

native

REALITY · carrier.mode=auto (recommended)

v0.5.0 default: native + raw + mux + security.type=reality + carrier.mode=auto. TCP and QUIC on one address; outbound carrier.prefer defaults to adaptive.

When: Both ends run tcptun v0.5.0 and you want automatic dual carriers without certs or a second port.

  1. Generate with --server-name and --dest (HTTPS + HTTP/3 capable camouflage).
  2. Ensure mux.enabled and carrier.mode=auto so automatic carriers activate.
  3. Pair private_key / public_key and short ids; open TCP and UDP on the listen port.
  4. Optional: set mux.resume=true on both peers for resumable TCP streams.
tcptun config native --server proxy.example.com --port 9443 --server-name example.com --dest example.com:443
tcptun config check --config server.json
tcptun --config server.json
tcptun --config client.json
server-native-reality-auto.json
Generating Reality keys and credentials…