onifast-relay is the unified connectivity gateway of the Onifast stack. It enables remote agents (servers running behind NAT) to expose their services publicly through the Onifast gateway server using persistent WebSocket connections β similar in concept to ngrok or Cloudflare Tunnels, but self-hosted and integrated with the panel.
π onifast-relay
WebSocket-based port relay gateway. Persistent reverse HTTP tunnels, TCP streams, and protocol-peeking routers.
Port Allocations
| Port | Visibility | Description |
|---|---|---|
| 4052 | Public | Unified Gateway β Agent WebSocket dial-in, Management API, and Smart TCP peeking |
| 4053 | Public | Web Proxy Output β forwards public HTTP/HTTPS traffic directly to registered web relay agents |
Web Proxy Relay (Port 4053)
Agents register by dialing ws://gateway:4052/relay?subdomain=<name>&secret=<key>. The gateway validates the secret against the Tunnels bucket in the panel database.
Client Browser β Port 4053 (handleWebProxyRequest)
β Match pool by Host header
WebSocket Pool [agent1_conn, agent2_conn, ...]
β Pipe HTTP request β agent via WS β Response back β Client
Agent (on remote server) β localhost:80 (or any local port)
The gateway implements a robust draining strategy: if a worker WebSocket is stale (returns an error), the gateway automatically tries the next available worker rather than returning a 502 immediately.
TCP Tunnel (Port 4052)
For raw TCP tunneling (SSH, databases, etc.), agents dial ws://gateway:4052/tunnel?subdomain=<name>&secret=<key>. The gateway uses a CONNECT <port>\n prefix to instruct the agent which local port to connect to.
Dynamic Port Prefix Routing
Use p<port>.agentsubdomain.example.com to specify a target port dynamically:
# Route to SSH (22) on the agent
p22.myserver.onifast.com
# Route to MySQL (3306) on the agent
p3306.myserver.onifast.com
Static Port Forwarding
Permanent TCP listener-to-tunnel mappings, managed via the panel and stored in onifast-relay.db:
CREATE TABLE PortForwards (
listen_port INTEGER PRIMARY KEY,
tunnel_host TEXT, -- agent subdomain
target_port INTEGER,
active BOOLEAN
);
Example: port 33060 always forwards to myserver agent's port 3306, enabling direct MySQL access from anywhere.
Smart Subdomain Routing (Port 4052)
Port 4052 listens on raw TCP and peeks at the first bytes to determine the protocol:
- If the first 4 bytes match an HTTP method (
GET,POST,PUT,DELE), treat as HTTP β route to the HTTP mux (dial handlers, management API). - Otherwise, treat as raw TCP β extract
Hostheader or SNI, find the matching pool, and pipe over WebSocket.
Management API Endpoints (on Port 4052)
| Path | Method | Description |
|---|---|---|
/relay?subdomain=<s>&secret=<k> |
WS Upgrade | Agent dial-in endpoint for web proxy relays |
/tunnel?subdomain=<s>&secret=<k> |
WS Upgrade | Agent dial-in endpoint for raw TCP tunnels |
/status |
GET | Query gateway status, stats, and version details |
/relay/pools |
GET | Get active web relay worker counts (JSON) |
/tunnel/pools |
GET | Get active TCP tunnel worker counts (JSON) |
/portforwards/list |
GET | List static port forwards |
/portforwards/add |
POST | Add a static port forward mapping |
/portforwards/delete |
POST | Remove a static port forward mapping |
Worker Connection Pool
Each subdomain maintains a pool of up to 100 WebSocket connections. When a request arrives:
- One connection is taken from the pool (
chan *websocket.Conn). - The HTTP request or raw TCP stream is piped over it.
- If the pool is full when an agent reconnects, the oldest connection is evicted (FIFO eviction policy).
- Stale pools (no activity for >1 minute) are automatically garbage-collected by a background routine.
Telegram Alerts
The relay broadcasts tunnel state triggers to the panelβs notification API:
- π’ Web Proxy Connected β First worker connects for a subdomain.
- π’ Tunnel Connected β First worker connects for a TCP tunnel.
- π΄ Web Proxy Disconnected β All workers gone for >1 minute (triggers stale cleanup).
Systemd Service Daemon
[Unit]
Description=Onifast Relay Gateway
After=network.target
[Service]
ExecStart=/home/root/go/cmd/onifast-relay/onifast-relay
Restart=always
[Install]
WantedBy=multi-user.target
Firewall Rules
Open gateway ports in your firewall configuration:
# Open gateway control & smart peek ports
ufw allow 4052/tcp
ufw allow 4053/tcp
# Reload
ufw reload