How to Install
curl -fsSL https://x-tunnel.itlinkin.com/install-client.sh | bash
/usr/local/bin/xtunnel. Requires curl.curl -fsSL https://x-tunnel.itlinkin.com/install-client.sh | bash
/usr/local/bin/xtunnel.Transparent proxy (optional)
Route all outbound traffic from this machine — including Docker containers and any process — through the tunnel transparently. No per-app proxy config needed.
# Step 1 — download the script (requires root) sudo curl -fsSL https://x-tunnel.itlinkin.com/install/xtunnel-transparent.sh -o /usr/local/sbin/xtunnel-transparent sudo chmod +x /usr/local/sbin/xtunnel-transparent # Step 2 — install (interactive: prompts for server, token, and connection mode) sudo xtunnel-transparent install # Step 3 — start sudo xtunnel-transparent start
1) REALITY — fully obfuscated, looks like Apple CDN traffic (recommended)
2) Cloudflare / ECH — server is behind Cloudflare, ECH auto-negotiated
3) Direct VPS + skip cert — self-signed cert, adds
-insecure4) Direct VPS + valid cert — valid TLS cert, adds
-fallbackUses chinadns-ng for split DNS: CN domains go via your original DNS directly; all others resolve via
tcp://1.1.1.1 through the tunnel.
Docker bridge traffic is intercepted automatically. iptables rules are cleanly removed on stop.
sudo xtunnel-transparent start # start + set DNS → 127.0.0.1 sudo xtunnel-transparent stop # stop + restore original DNS sudo xtunnel-transparent status # service status / exit IP / DNS test sudo xtunnel-transparent restart sudo xtunnel-transparent update # refresh CN domain lists sudo xtunnel-transparent uninstall
irm https://x-tunnel.itlinkin.com/install-client.ps1 | iex
%LOCALAPPDATA%\xtunnel\xtunnel.exe and adds to PATH. Run PowerShell as a normal user — no admin needed.How to Run
Config file (recommended)
xtunnel -c ~/client.json
Create ~/client.json from the sample dropped next to the binary during install (client.json.sample). Set forward to your server and token to the shared secret. Run with xtunnel -c ~/client.json.
# ~/client.json — every flag has a JSON key; CLI flags override the file
{
"mode": "client",
"listen": ["mixed://127.0.0.1:1080"],
"forward": "reality://YOUR_SERVER:8118/api",
"token": "YOUR_TOKEN",
"bond": 4,
"bond_profile": "balanced",
"min_channels": 3,
"max_channels": 8,
"max_spare": 2,
"multistream": true
}
ip, ips, sni, reality_dest, insecure, fallback, dns, ech, proxy, smuxbuf, streambuf, geo_dir, geo_update, geosite_url, geoip_url.SOCKS5 proxy (flags)
xtunnel \ -mode client \ -l socks5://127.0.0.1:1080 \ -f reality://your.server.com:8118/api \ -token YOUR_TOKEN \ -bond 4
Starts a local SOCKS5 proxy on 127.0.0.1:1080. Point your browser or system proxy there. -bond 4 allows up to 4 parallel streams per connection, added automatically when throughput plateaus.
Mixed proxy (SOCKS5 + HTTP on one port)
xtunnel \ -mode client \ -l mixed://127.0.0.1:1080 \ -f reality://your.server.com:8118/api \ -token YOUR_TOKEN \ -bond 4
Auto-detects the protocol on the same port: SOCKS5 clients (first byte 0x05) and HTTP CONNECT clients both work on 127.0.0.1:1080.
HTTP CONNECT proxy
xtunnel \ -mode client \ -l http://127.0.0.1:8080 \ -f reality://your.server.com:8118/api \ -token YOUR_TOKEN \ -bond 4
All flags
# ── Core ──────────────────────────────────────────────────────────────
-c path/to/client.json # load all flags from a JSON config file
-mode client # client or server (default client)
-f reality://host:8118/api # server address (REALITY transport, recommended)
-f wss://host:8118/api # server address (TLS, for Cloudflare-fronted servers)
-l socks5://127.0.0.1:1080 # local listener; repeat -l for several listeners
# socks5:// http:// mixed:// tcp:// tproxy:// (Linux)
-token TOKEN # must match server token
-version # print version and exit
# ── Bonding / channel pool ────────────────────────────────────────────
-bond N # max parallel streams per connection (default 8, 1 = off)
-bond-profile PROFILE # bonding aggressiveness: conservative | balanced (default) | aggressive
-min-channels N # WS channels always kept open (default 3)
-max-channels N # upper bound on WS channels (default 8)
-max-spare N # spare idle channels (default 2)
-multistream=false # disable smux multiplexing (default enabled)
-smuxbuf BYTES # smux session receive buffer (default 256MB)
-streambuf BYTES # per-stream flow-control window (default 64MB)
# ── Transport / TLS ───────────────────────────────────────────────────
-ip IP[,IP2,...] # force server IP(s), comma-separated (bypass DNS)
-sni HOST # override the SNI sent in ClientHello (default: server hostname)
-reality-dest host:443 # REALITY cover site (default www.apple.com:443; must match server)
-insecure # skip certificate verification (self-signed direct VPS)
-fallback # disable ECH, use plain TLS 1.3
-ech DOMAIN # ECH public-key lookup domain (default cloudflare-ech.com)
-dns URL # DoH resolver for ECH lookups (default https://doh.pub/dns-query)
-proxy socks5://host:port # reach the server through an upstream SOCKS5 proxy
# ── Routing / misc ────────────────────────────────────────────────────
-ips 4|6|4,6|6,4 # target IP family preference used when dialing destinations
-block 443 # UDP ports dropped locally, comma-separated (default 443, blocks QUIC)
-geo-dir DIR # geoip.dat/geosite.dat directory (default: working directory)
-geo-update 24h # geo data refresh interval
-geosite-url URL # geosite.dat download source
-geoip-url URL # geoip.dat download source
-bond-profile only scales thresholds, not the mechanism: conservative stops spawning sooner and is more sensitive to stalls (good for known-jittery lines); balanced is the default; aggressive stops later and tolerates more stall (good for lines that are clean but heavily rate-limited).