multiplex-tunnel-transport
v1.4.0
Published
tcp/http tunnel with multiplexed transport (wsmux + tlsmux)
Downloads
316
Maintainers
Readme
multiplex-tunnel-transport
A TCP/HTTP reverse-tunnel with stream multiplexing: a single persistent connection between the client (behind NAT) and the server (public), carrying many logical streams — one per inbound HTTP request. No socket pool, no per-request dial-back, no NAT re-traversal.
Two transports ship behind a shared interface, selectable via config:
wsmux(default) — frames over the existing socket.io control channel. No extra ports. Works through any HTTP-only proxy.yamux— a yamux-style binary mux over one persistent TLS connection on the agent port. Lower overhead, real per-stream credit-window backpressure.
Install
npm install multiplex-tunnel-transportUsage
Server (public, in front of the tunnel)
import { TunnelServer } from 'multiplex-tunnel-transport';
const server = new TunnelServer({
serverPrivateKey: '/path/to/server.key',
serverPublicKey: '/path/to/server.crt',
httpsPrivateKey: '/path/to/https.key',
httpsPublicKey: '/path/to/https.crt',
transport: 'wsmux', // or 'yamux'
});
server.open();
// HTTPS listens on :4000 (public). For yamux, an additional TLS data
// channel listens on :4001.Client (behind NAT, forwards to a local service)
import { TunnelManager } from 'multiplex-tunnel-transport';
const manager = new TunnelManager({
remoteUrl: 'https://your-server.example.com:4000/',
serverPrivateKey: '/path/to/server.key',
serverPublicKey: '/path/to/server.crt',
localPort: 3001, // local service to forward tunneled requests to
});
manager.open();The server tells the client which transport to use during the socket.io handshake — clients don't configure this themselves.
Architecture
┌────────────────────────┐
public HTTPS request ──▶ │ TunnelServer │
(e.g. curl :4000) │ - HTTPS :4000 │
│ - socket.io control │
│ - TLS agent :4001 │
│ (yamux only) │
└─────────┬──────────────┘
│
one persistent multiplexed
connection (wsmux or tlsmux)
│
┌─────────▼──────────────┐
│ TunnelClient │
│ - opens N streams │
│ - pipes each to │
│ localhost:<port> │
└────────────────────────┘Each public HTTP request → one logical mux stream → bridged to the local service. Backpressure is per-stream (credit window, default 1 MiB).
Configuration
| Field | Where | Default | Description |
| -------------------------------------- | ------ | -------------------- | ---------------------------------------------------------------------------- |
| transport | server | 'wsmux' | 'wsmux' (frames over socket.io) or 'yamux' (binary mux over TLS). |
| localPort | client | 3001 | Local TCP port to forward tunneled requests to. |
| serverPrivateKey / serverPublicKey | both | — | RSA keypair used for JWT auth on the control channel and (yamux) TLS. |
| httpsPrivateKey / httpsPublicKey | server | — | TLS keypair for the public HTTPS server. |
| socketio | both | see below | Pass-through to the underlying socket.io Server / socket.io-client. User values override the package defaults. |
Tuning socket.io
Both TunnelServer and TunnelManager accept a socketio option that's forwarded directly to the socket.io constructor — full type-safety via Partial<ServerOptions> (server) and Partial<ManagerOptions & SocketOptions> (client).
Client defaults (override any of these via socketio):
| Option | Default | Notes |
| ------------------------- | ----------- | ------------------------------------------ |
| reconnection | true | |
| reconnectionAttempts | Infinity | retry forever — set a number to cap |
| reconnectionDelay | 1000 | initial backoff (ms) |
| reconnectionDelayMax | 10000 | max backoff (ms) |
| timeout | 20000 | connect timeout (ms) |
| transports | ['websocket'] | |
new TunnelManager({
remoteUrl: 'https://...',
serverPrivateKey, serverPublicKey,
socketio: {
reconnectionAttempts: 5, // give up after 5 attempts instead of forever
reconnectionDelayMax: 30000,
timeout: 30000,
},
});The Authorization: Bearer <jwt> header is set internally and cannot be overridden — any extraHeaders you supply are merged with it.
Server defaults: cors: { origin: '*' }. Override or add anything socket.io's Server accepts:
new TunnelServer({
serverPrivateKey, serverPublicKey,
httpsPrivateKey, httpsPublicKey,
socketio: {
cors: { origin: 'https://my-app.com' },
pingInterval: 25000,
pingTimeout: 60000,
maxHttpBufferSize: 5_000_000,
},
});License
Apache 2.0
