NRelay
W.I.P Ngrok Alternative: Self-hosted and open-source OOB reverse tunnel (TCP/UDP/SNI/HTTP/MC)
Install / Use
/learn @sammwyy/NRelayREADME
NRelay
A super fast reverse tunnel system written in Rust that allows you to expose local services to the internet through secure tunnels. Similar to ngrok or Cloudflare Tunnel, but self-hosted.
What is NRelay?
Do you want to show your local web server to a friend? Or open up a local Minecraft server to play with others? Maybe test webhooks without deploying?
NRelay is a reverse proxy tunneling solution that consists of a relay server (running on a public server) and clients (running locally). It allows you to expose local development servers, APIs, or any network service to the internet without port forwarding or firewall configuration.
Key Features
- Multiple Protocol Support: HTTP, HTTPS (TLS/SNI), TCP, UDP, Minecraft, and SSH - all in one tool
- Flexible Routing: Hostname-based routing for HTTP/HTTPS, port-based for TCP/UDP
- Self-Hosted: Run it on your own infrastructure with complete control
- High Performance: Built with Rust and Tokio for blazing fast async I/O
- Token-Based Security: Each tunnel gets its own unique authentication token
- Origin Management: Easily organize and manage multiple relay server configurations
- Admin API: RESTful API for programmatic tunnel management
- Protocol Sniffing: Automatically routes traffic based on intelligent protocol detection
Supported Tunnel Types
| Protocol | Exposure Mode | Default Port | Routing Method | |----------|---------------|--------------|----------------| | HTTP | Hostname | 80 | Host header | | HTTPS/TLS | Hostname | 443 | SNI (Server Name Indication) | | TCP Raw | Port | 20000-30000 | Direct port mapping | | UDP Raw | Port | 30000-40000 | Direct port mapping | | Minecraft | Port | 25565 | Handshake parsing | | SSH | Port | 20000-30000 | Direct port mapping |
Requirements
Server Requirements
- Rust: 1.70 or higher
- Operating System: Linux, macOS, or Windows
- Public IP Address: Required for the relay server
- Open Ports:
- Control port (default: 7000)
- Admin API port (default: 7001)
- Protocol-specific ports (80 for HTTP, 443 for HTTPS, etc.)
Client Requirements
- Rust: 1.70 or higher
- Network Access: Ability to connect to the relay server's control port
Installation
Prerequisites
Make sure you have Rust installed. If not, install it from rustup.rs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Building from Source
Clone the repository and build all components:
git clone https://github.com/sammwyy/NRelay.git
cd NRelay
# Build all workspace members
cargo build --release
# Binaries will be available in target/release/
# - nrelay (CLI tool)
# - nrelay_server (Relay server)
# - nrelay_client (Tunnel client)
Installing Binaries
# Install all binaries to ~/.cargo/bin/
cargo install --path nrelay
cargo install --path nrelay_server
cargo install --path nrelay_client
💡 Pro Tip: Make sure
~/.cargo/binis in your PATH to run the binaries from anywhere!
Usage
1. Running the Relay Server
On your public server, start the relay server:
# Set admin API token
export ADMIN_TOKEN="your-secret-admin-token"
# Run the server
nrelay_server \
--control-port 7000 \
--admin-port 7001 \
--domain yourdomain.com
Server Options:
--control-port: Port for client control connections (default: 7000)--admin-port: Port for admin API (default: 7001)--admin-iface: Interface to bind admin API (default: 0.0.0.0)--domain: Base domain for hostname-based tunnels--admin-token: Bearer token for admin API authentication (can use env var)
2. Configuring an Origin (Client)
Add your relay server as an "origin":
nrelay origin add myserver \
--server relay.yourdomain.com:7000 \
--admin-url http://relay.yourdomain.com:7001 \
--token your-secret-admin-token \
--kind server
Origin Modes:
--kind server(self-hosted): CLI acts as ADMIN, directly connects to relay server. Use this for personal/self-hosted deployments.--kind service(SaaS mode, default): CLI acts as USER, requests permissions from a backend service. Used for team/business deployments with dashboard authentication. (Note: SaaS backend not yet implemented)
💡 Pro Tip: For self-hosted deployments, always use
--kind serverto avoid permission errors!
List configured origins:
nrelay origin list
Set default origin:
nrelay origin set-default myserver
💡 Pro Tip: Once you set a default origin, you won't need to specify
--originin your tunnel commands!
3. Creating Tunnels
HTTP Tunnel
Expose a local HTTP server:
# Expose localhost:8080 via HTTP
nrelay http localhost:8080
# Output: Your tunnel is available at http://{tunnel-id}.yourdomain.com
HTTPS Tunnel
Expose a local HTTPS server:
nrelay https localhost:8443
TCP Tunnel
Expose a local TCP service:
# Expose local SSH server
nrelay tcp localhost:22
# Output: Your tunnel is available at relay.yourdomain.com:25432
Minecraft Server
Expose a Minecraft server:
nrelay minecraft localhost:25565
💡 Pro Tip: The Minecraft tunnel runs on port 25565 by default, so your friends can connect directly without specifying a port!
Custom Options
# Specify origin
nrelay http localhost:3000 --origin myserver
# With custom configuration
nrelay tcp localhost:5432 --origin production-relay
4. Managing Origins
# List all origins
nrelay origin list
# Remove an origin
nrelay origin remove myserver
# Show origin details
nrelay origin show myserver
Architecture
┌─────────────────────────────────────────┐
│ Public Internet Traffic │
│ (HTTP/HTTPS/TCP/UDP/Minecraft/SSH) │
└─────────────────┬───────────────────────┘
│
▼
┌────────────────────────────────────────┐
│ NRelay Server (Public) │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Protocol Listeners │ │
│ │ - HTTP:80 │ │
│ │ - HTTPS:443 │ │
│ │ - TCP: 20000-30000 │ │
│ │ - UDP: 30000-40000 │ │
│ │ - Minecraft: 25565 │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Tunnel Registry │ │
│ │ (In-memory state) │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Admin API (:7001) │ │
│ │ - POST /tunnels │ │
│ │ - Bearer token auth │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Control Port (:7000) │ │
│ │ - Client connections │ │
│ │ - Protobuf protocol │ │
│ └─────────────────────────────────┘ │
└─────────────────┬──────────────────────┘
│ Control Protocol
│ (Protobuf over TCP)
▼
┌────────────────────────────────────────┐
│ NRelay Client (Local) │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Control Connection │ │
│ │ - Receives tunnel requests │ │
│ │ - Spawns tunnel handlers │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Tunnel Handlers │ │
│ │ - Bidirectional proxy │ │
│ │ - Per-connection spawning │ │
│ └─────────────────────────────────┘ │
└─────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Local Service │
│ (localhost:8080, :3000, etc.) │
└─────────────────────────────────────────┘
How It Works
- Tunnel Creation: Client calls admin API to create tunnel, receives unique token
- Control Connection: Client establishes persistent connection to relay server
- Incoming Traffic: External request arrives at relay server
- Protocol Sniffing: Server extracts routing info (Host header, SNI, etc.)
- Tunnel Matching: Server identifies which tunnel should handle the request
- Connection Request: Server sends
OpenTunnelRequestto client via control connection - Tunnel Connection: Client spawns handler, connects back to server with tunnel token
- Bidirectional Proxy: Data flows: External ↔ Server ↔ Client ↔ Local Service
Project Structure
NRelay/
├── nrelay/ # CLI tool for tunnel management
├── nrelay_server/ # Relay server (gateway)
├── nrelay_client/ # Tunnel client
├── nrelay_core/ # Shared types and protocol definitions
├── nrelay_proto_http/ # HTTP protocol sniffer
├── nrelay_proto_sni/ # TLS/SNI sniffer
├── nrelay_proto_tcp/ # TCP proxy handler
├── nrelay_proto_udp/ # UDP proxy handler
└── nrelay_proto_mc/ # Minecraft protocol handler
Configuration
Origin Configuration
Origins are stored in ~/.nrelay/origins.toml:
[[origins]]
name = "myserver"
server = "relay.example.com:7000"
admin_url = "http://relay.example.com:7001"
admin_token = "your-admin-token"
kind = "server" # "server" for self-hosted, "service" for SaaS (not yet implement
Related Skills
node-connect
336.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
336.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.0kCommit, push, and open a PR
