SkillAgentSearch skills...

Rustunnel

**Rustunnel** is a open-source tunnel service written in Rust that replicates the core functionality of ngrok. It exposes local services running behind NAT/firewalls to the public internet through a relay server self-hosted or our managed service.

Install / Use

/learn @joaoh82/Rustunnel
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

rustunnel

CI License: AGPLv3 Rust

rustunnel logo

A ngrok-style secure tunnel server written in Rust. Expose local services through a public server over encrypted WebSocket connections with TLS termination, HTTP/TCP proxying, a live dashboard, Prometheus metrics, and audit logging.

You can self-host or use our managed service.


Table of Contents


Hosted service

You can use rustunnel without running your own server. We operate a global fleet of public edge servers that you can connect to immediately.

Available regions

| Region ID | Server | Location | Control plane | Status | |-----------|--------|----------|---------------|--------| | eu | eu.edge.rustunnel.com | Helsinki, FI | :4040 | Live | | us | us.edge.rustunnel.com | Hillsboro, OR | :4040 | Live | | ap | ap.edge.rustunnel.com | Singapore | :4040 | Live |

The client auto-selects the nearest region by default. Use --region <id> to connect to a specific one. The legacy address edge.rustunnel.com is a CNAME to eu.edge.rustunnel.com and will continue to work for backward compatibility.

Getting an auth token

Sign up for a free account at rustunnel.com — no waiting list, no manual approval.

  1. Create an account at rustunnel.com
  2. Go to Dashboard → API Keys and create a token
  3. Copy the token — it is shown only once

Plans:

| Plan | Price | Tunnels | Custom subdomains | TLS/HTTPS | |------|-------|---------|-------------------|-----------| | Free | $0 | Up to 3 | — | ✓ | | Pay-as-you-go | $3/mo minimum + $0.10/GB | Unlimited | ✓ | ✓ | | Self-host | Free (run your own server) | Unlimited | ✓ | ✓ |

The free plan is a great way to get started. Upgrade to pay-as-you-go from your dashboard whenever you need custom subdomains or unlimited tunnels.

Quick start with the hosted server

Once you have a token, run the setup wizard:

rustunnel setup
# Tunnel server address [edge.rustunnel.com:4040]: (press Enter)
# Auth token: <paste your token>
# Region [auto / eu / us / ap] (default: auto): (press Enter)

Then expose a local service:

# HTTP tunnel — auto-selects the nearest region
rustunnel http 3000

# Connect to a specific region
rustunnel http 3000 --region eu

# Custom subdomain
rustunnel http 3000 --subdomain myapp

# TCP tunnel — e.g. expose a local database
rustunnel tcp 5432

The client prints the public URL as soon as the tunnel is established:

  Selecting nearest region… eu 12ms · us 143ms · ap 311ms → eu (Helsinki, FI) 12ms
✓ tunnel open  https://abc123.eu.edge.rustunnel.com

Architecture overview

rustunnel architecture

                        ┌──────────────────────────────────────────┐
                        │           rustunnel-server               │
                        │                                          │
Internet ──── :80 ─────▶│  HTTP edge (301 → HTTPS)                 │
Internet ──── :443 ────▶│  HTTPS edge  ──▶ yamux stream ──▶ client │
Client ───── :4040 ────▶│  Control-plane WebSocket (TLS)           │
Browser ──── :8443 ────▶│  Dashboard UI + REST API                 │
Prometheus ─ :9090 ────▶│  Metrics endpoint                        │
Internet ── :20000+ ───▶│  TCP tunnel ports (one per TCP tunnel)   │
                        └──────────────────────────────────────────┘
                                          │ yamux multiplexed streams
                                          ▼
                              ┌─────────────────────┐
                              │   rustunnel client   │
                              │  (developer laptop)  │
                              └──────────┬──────────┘
                                         │ localhost
                                         ▼
                                ┌────────────────┐
                                │  local service  │
                                │  e.g. :3000    │
                                └────────────────┘

Requirements

To build

| Requirement | Version | Notes | |---|---|---| | Rust toolchain | 1.76+ | Install via rustup | | pkg-config | any | Needed by reqwest (TLS) | | libssl-dev | any | On Debian/Ubuntu: apt install libssl-dev | | Node.js + npm | 18+ | Only needed to rebuild the dashboard UI |

To run the server in production

| Requirement | Notes | |---|---| | Linux (Ubuntu 22.04+) | systemd service included | | TLS certificate + private key | PEM format (Let's Encrypt recommended) | | Public IP / DNS | Wildcard DNS *.tunnel.yourdomain.com → server IP required for HTTP tunnels |


Local development setup

Build

# Clone the repository
git clone https://github.com/joaoh82/rustunnel.git
cd rustunnel

# Compile all workspace crates (debug mode)
cargo build --workspace

# Or use the Makefile shortcut
make build

Run tests

The integration test suite spins up a real server on random ports and exercises auth, HTTP tunnels, TCP tunnels, and reconnection logic. It requires a running PostgreSQL instance.

# Start the local PostgreSQL container (once per machine, persists across reboots)
make db-start

# Full suite (unit + integration)
make test

# With output visible
TEST_DATABASE_URL=postgres://rustunnel:test@localhost:5432/rustunnel_test \
  cargo test --workspace -- --nocapture

# Stop PostgreSQL when you no longer need it
make db-stop

make db-start runs deploy/docker-compose.dev-deps.yml which starts a Postgres 16 container on localhost:5432. The make test target injects TEST_DATABASE_URL automatically. If you run cargo test directly, export the variable first:

export TEST_DATABASE_URL=postgres://rustunnel:test@localhost:5432/rustunnel_test

Run the server locally

Generate a self-signed certificate for local testing:

mkdir -p /tmp/rustunnel-dev

openssl req -x509 -newkey rsa:2048 -keyout /tmp/rustunnel-dev/key.pem \
  -out /tmp/rustunnel-dev/cert.pem -days 365 -nodes \
  -subj "/CN=localhost"

A ready-made local config is checked into the repository at deploy/local/server.toml. It points to the self-signed cert paths above and has auth disabled for convenience. Start the server with it directly:

cargo run -p rustunnel-server -- --config deploy/local/server.toml

Key settings in deploy/local/server.toml:

| Setting | Value | |---|---| | Domain | localhost | | HTTP edge | :8080 | | HTTPS edge | :8443 | | Control plane | :4040 | | Dashboard | :4041 | | Auth token | dev-secret-change-me | | Auth required | false | | TLS cert | /tmp/rustunnel-dev/cert.pem | | TLS key | /tmp/rustunnel-dev/key.pem | | Database | /tmp/rustunnel-dev/rustunnel.db |

Run the client locally

With the server running, expose a local service (e.g. something on port 3000):

# HTTP tunnel
cargo run -p rustunnel-client -- http 3000 \
  --server localhost:4040 \
  --token dev-secret-change-me \
  --insecure

# TCP tunnel
cargo run -p rustunnel-client -- tcp 5432 \
  --server localhost:4040 \
  --token dev-secret-change-me \
  --insecure

--insecure skips TLS certificate verification. Required when using a self-signed certificate locally. Never use this flag against a production server.

The client will print a public URL, for example:

http tunnel  →  http://abc123.localhost:8080
tcp  tunnel  →  tcp://localhost:20000

Testing the HTTP tunnel locally

The tunnel URL uses a subdomain (e.g. http://abc123.localhost:8080). Browsers won't resolve *.localhost subdomains by default, so you have two options:

Option A — curl with a Host header (no setup required)

curl -v -H "Host: abc123.localhost" http://localhost:8080/

**Option B — wildcard DNS

Related Skills

View on GitHub
GitHub Stars595
CategoryDevelopment
Updated12h ago
Forks40

Languages

Rust

Security Score

100/100

Audited on Mar 31, 2026

No findings