SkillAgentSearch skills...

Ferrotunnel

Secure, embedded, API-first tunneling with public URLs, acting as a lightweight ingress and HTTP proxy focused on low-latency forwarding

Install / Use

/learn @ferro-labs/Ferrotunnel

README

FerroTunnel 🦀

CI Crates.io Documentation License Rust Version Discord

High-performance reverse tunnel you can embed in your Rust applications.

FerroTunnel multiplexes streams over a single connection (like ngrok/Cloudflare Tunnel) but ships as a library-first crate. Expose local services behind NAT, route HTTP by hostname, intercept requests with plugins with minimal memory footprint and sub-millisecond latency. Works as CLI or Client::builder() API. Written in Rust.

Prerequisites

  • Rust 1.90+: FerroTunnel uses modern Rust features for performance and safety.
  • Cargo: Required for building and installing from source.
  • Git: For cloning the repository during development.

Quick Start

CLI

# Install
cargo install ferrotunnel-cli

# Start server
ferrotunnel server --token secret

# Start client (in another terminal; token from env or secure prompt if omitted)
ferrotunnel client --server localhost:7835 --local-addr 127.0.0.1:8080 --tunnel-id my-app

Library

[dependencies]
ferrotunnel = "1.0"
tokio = { version = "1", features = ["full"] }
use ferrotunnel::Client;

#[tokio::main]
async fn main() -> ferrotunnel::Result<()> {
    let mut client = Client::builder()
        .server_addr("tunnel.example.com:7835")
        .token("my-secret-token")
        .local_addr("127.0.0.1:8080")
        .tunnel_id("my-app")
        .build()?;

    client.start().await?;

    tokio::signal::ctrl_c().await?;
    client.shutdown().await
}

HTTP/2 and Connection Pooling

FerroTunnel v1.0.3+ includes automatic HTTP/2 support and connection pooling for improved performance:

Server-side: The HTTP ingress automatically detects and handles both HTTP/1.1 and HTTP/2 connections from clients.

Client-side: Connection pooling reuses HTTP connections to local services, eliminating per-request TCP handshake overhead:

use ferrotunnel_http::{HttpProxy, PoolConfig};
use std::time::Duration;

// Create proxy with custom pool configuration
let pool_config = PoolConfig {
    max_idle_per_host: 32,           // Max idle connections per host (default: 32)
    idle_timeout: Duration::from_secs(90), // Connection idle timeout (default: 90s)
    prefer_h2: false,                 // Prefer HTTP/2 when available (default: false)
};

let proxy = HttpProxy::with_pool_config("127.0.0.1:8080".into(), pool_config);

CLI: Use default pool settings (no flags needed) or customize via the library API.

Benefits:

  • 🚀 Eliminates TCP handshake overhead per request
  • 🔄 HTTP/2 multiplexing reduces connection count
  • 🧹 Background eviction prevents resource leaks
  • 📈 Significantly improves throughput (target: 800-1000 MB/s)

gRPC Tunneling

FerroTunnel v1.0.6+ natively tunnels gRPC traffic over HTTP/2 with zero configuration.

How it works: The server-side ingress automatically detects gRPC requests by inspecting the Content-Type: application/grpc header. Detected gRPC streams are forwarded over a dedicated HTTP/2 connection to the local service, preserving HTTP/2 trailers (including grpc-status and grpc-message) end-to-end.

CLI — no special flags needed; detection is automatic:

# Expose a local gRPC server running on port 50051
ferrotunnel client --server tunnel.example.com:7835 --local-addr 127.0.0.1:50051 --tunnel-id my-grpc-service

Library:

use ferrotunnel::Client;

#[tokio::main]
async fn main() -> ferrotunnel::Result<()> {
    let mut client = Client::builder()
        .server_addr("tunnel.example.com:7835")
        .token("my-secret-token")
        .local_addr("127.0.0.1:50051")  // gRPC server port
        .tunnel_id("my-grpc-service")
        .build()?;

    client.start().await?;
    tokio::signal::ctrl_c().await?;
    client.shutdown().await
}

What is preserved end-to-end:

  • HTTP/2 stream multiplexing
  • gRPC trailers (grpc-status, grpc-message, custom metadata)
  • Streaming RPCs (server-streaming, client-streaming, bidirectional)
  • Standard gRPC status codes and error propagation

Features

| Feature | Description | |---------|-------------| | Embeddable | Use as a library with builder APIs | | HTTP/2 | Automatic HTTP/1.1 and HTTP/2 protocol detection | | Connection Pooling | Efficient connection reuse for improved performance | | Plugin System | Auth, rate limiting, logging, circuit breaker | | Dashboard | Real-time WebUI at localhost:4040 | | TLS 1.3 | Secure connections with rustls | | Mutual TLS | Client certificate authentication | | Observability | Prometheus metrics + OpenTelemetry tracing | | WebSocket | Transparent WebSocket upgrade tunneling | | gRPC | Native gRPC tunneling over HTTP/2 with trailer preservation | | TCP & HTTP | Forward both HTTP and raw TCP traffic |

Choose FerroTunnel when: You need many services over a single connection, HTTP routing, plugins, or resource efficiency.

See Architecture for detailed analysis of the multiplexing trade-off.

Security: Why Rust Matters

Traditional C/C++ tunneling solutions (OpenSSH, OpenVPN, stunnel) have suffered from 30+ critical memory safety vulnerabilities over the past decade—buffer overflows, use-after-free, double-free, race conditions, and heap corruption.

FerroTunnel eliminates these entire vulnerability classes at compile time using Rust's ownership system:

  • Zero unsafe code (#![forbid(unsafe)] at workspace level)
  • Memory safety guaranteed (no buffer overflows, use-after-free, double-free)
  • Thread safety enforced (no data races possible)
  • Pure Rust crypto (rustls instead of OpenSSL—zero legacy vulnerabilities)

Security Features:

  • TLS 1.3-only enforcement with mutual TLS support
  • Token-based authentication with constant-time comparison
  • Built-in rate limiting and frame size limits
  • Automated dependency scanning (cargo-audit in CI)

See docs/security.md for detailed CVE comparison, vulnerability analysis, and security best practices.

Ideal For

FerroTunnel's memory-safe architecture and minimal resource footprint make it perfect for security-critical and resource-constrained environments:

  • 🔐 Crypto & Blockchain Infrastructure - High security requirements, integrates seamlessly with Rust blockchain ecosystems (Solana, Polkadot, Cosmos)
  • 📡 IoT Devices - Low memory overhead (<100MB/1k tunnels), zero memory vulnerabilities, ideal for edge gateways and smart devices
  • Edge Computing - Sub-millisecond latency, efficient resource usage, compile-time safety guarantees
  • 🖥️ Embedded Systems - No garbage collector, predictable performance, cross-compilation friendly
  • 🏢 Enterprise Security - Zero unsafe code, automated dependency scanning, compliance-ready audit trails

Why it matters: Traditional C/C++ tunnels require constant security patches for memory vulnerabilities. Embedded/IoT devices often can't be easily updated, making Rust's compile-time safety guarantees essential.

CLI Reference

Server

ferrotunnel server [OPTIONS]

| Option | Env Variable | Default | Description | |--------|--------------|---------|-------------| | --token | FERROTUNNEL_TOKEN | required | Auth token | | --bind | FERROTUNNEL_BIND | 0.0.0.0:7835 | Control plane | | --http-bind | FERROTUNNEL_HTTP_BIND | 0.0.0.0:8080 | HTTP ingress | | --tcp-bind | FERROTUNNEL_TCP_BIND | - | TCP ingress | | --tls-cert | FERROTUNNEL_TLS_CERT | - | TLS certificate | | --tls-key | FERROTUNNEL_TLS_KEY | - | TLS private key |

Client

ferrotunnel client [OPTIONS]

| Option | Env Variable | Default | Description | |--------|--------------|---------|-------------| | --server | FERROTUNNEL_SERVER | required | Server address | | --token | FERROTUNNEL_TOKEN | optional | Auth token; if omitted, uses env or prompts securely | | --local-addr | FERROTUNNEL_LOCAL_ADDR | 127.0.0.1:8000 | Local service | | --tunnel-id | FERROTUNNEL_TUNNEL_ID | (auto) | Tunnel ID for HTTP routing | | --dashboard-port | FERROTUNNEL_DASHBOARD_PORT | 4040 | Dashboard port | | --tls | FERROTUNNEL_TLS | false | Enable TLS | | --tls-ca | FERROTUNNEL_TLS_CA | - | CA certificate |

See ferrotunnel-cli/README.md for all options.

Crates

| Crate | Description | |-------|-------------| | ferrotunnel | Main library with builder APIs | | ferrotunnel-cli | Unified CLI binary | | ferrotunnel-core | Tunnel logic and transport | | ferrotunnel-protocol | Wire protocol and codec | | ferrotunnel-http | HTTP/TCP ingress and proxy | | ferrotunnel-plugin | Plugin system | | ferrotunnel-observability | Metrics and dashboard | | ferrotunnel-common | Shared types |

Installation

Pre-built Binaries

Download from GitHub Releases.

From Source

cargo install ferrotunnel-cli

macOS (Homebrew)

brew tap ferro-labs/ferrotunnel
brew install ferrotunnel

Docker

Using Pull

You can pull the official image from GitHub Container Registry:

View on GitHub
GitHub Stars58
CategoryDevelopment
Updated17h ago
Forks6

Languages

Rust

Security Score

100/100

Audited on Apr 3, 2026

No findings