| Crates.io | vane |
| lib.rs | vane |
| version | 1.2.8 |
| created_at | 2025-09-11 15:53:27.594197+00 |
| updated_at | 2025-09-12 13:10:53.356144+00 |
| description | A lightweight Rust-based web proxy server with advanced routing, rate limiting, and HTTP/3 support. |
| homepage | |
| repository | https://github.com/canmi21/vane |
| max_upload_size | |
| id | 1834012 |
| size | 262,163 |
Vane is a modern, high-performance web proxy and server written entirely in Rust. It serves as a reverse proxy, handling HTTP, HTTPS, and HTTP/3 traffic with built-in features like dynamic routing, failover, rate limiting, CORS management, and automatic TLS certificate renewal. Designed for simplicity and security, Vane draws inspiration from tools like Nginx, OpenResty, and Caddy but reimplements their capabilities in pure Rust for better safety, portability, and minimalism.
Unlike traditional servers, Vane avoids dependencies on external scripting languages or libraries like LuaJIT (used in OpenResty) or OpenSSL. Instead, it leverages Rust's ecosystem—such as Axum for routing, Tokio for async I/O, and rustls for TLS—to deliver a fully memory-safe, thread-safe implementation. This results in a tiny Docker image (~5MB) built on scratch (no shell, no OS utils), making it ideal for edge deployments, microservices, and security-conscious environments.
*) matching, prefix-based specificity scoring, and multiple backend targets for automatic failover (tries backups on 5xx errors or connection failures).Vane positions itself as a Rust-native alternative to established web servers, focusing on security, minimalism, and modern features without sacrificing performance.
vs. Nginx: Nginx is battle-tested and highly optimized for performance, often considered at its optimization ceiling for C-based servers. However, Vane reimplements key Nginx features (e.g., reverse proxying, routing, rate limiting) in Rust, avoiding C's memory issues. Vane adds built-in HTTP/3, automatic cert renewal, and wildcard path matching with specificity scoring—features that require modules or custom configs in Nginx. While Nginx excels in raw throughput for simple static serving, Vane's async Rust core handles dynamic workloads efficiently without plugins.
vs. OpenResty: OpenResty extends Nginx with LuaJIT for scripting advanced logic like rate limiting, failover routing, wildcard matching, and custom middleware. Vane replicates these "plugins" natively in Rust: rate limiting with governor (no Lua scripts), failover via ordered target lists, wildcard (*) path matching with prefix scoring to resolve ambiguities, and middleware chains for CORS/HSTS/Alt-Svc. By ditching LuaJIT, Vane eliminates JIT overhead, potential scripting vulnerabilities, and dependency bloat. It's fully compiled, safer, and more predictable.
vs. Caddy: Caddy is Go-based, automatic HTTPS-focused, and user-friendly with its Caddyfile config. Vane matches Caddy's auto-TLS but uses a separate cert daemon (lazy-acme) for renewal, allowing decoupled management. Vane's TOML configs are more structured for complex routing/rate limits, and its Rust foundation offers better performance in async I/O-heavy scenarios (e.g., proxies). Unlike Caddy's larger binary (~10-15MB), Vane's Docker image is ~5MB on scratch—no Go runtime bloat.
In summary, while Nginx/OpenResty shine in legacy ecosystems and Caddy in simplicity, Vane stands out for its 100% Rust purity, rustls TLS (no OpenSSL vulnerabilities), and extreme minimalism. It's perfect for environments prioritizing security and small footprints, like containers or edge computing.
Vane's architecture is modular, asynchronous, and built around Rust's ecosystem for web serving. Here's a breakdown based on the codebase:
Entry Point (main.rs): Initializes logging, environment variables (via dotenvy), and a global "shield" rate limiter (30 req/s). Loads configs, handles first-run setup (creates example configs/certs), spawns a background cert renewal task (hourly checks via Tokio interval, refreshes via ACME if >24h old, restarts on success), and starts servers.
Configuration (config.rs): Loads from .env and TOML files. Main config.toml maps domains to per-domain TOML files (e.g., example.com.toml). Supports env vars for ports, cert dir/server, log level. Validates HTTPS/TLS configs.
ACME Client (acme_client.rs): Fetches certs/keys from a lazy-acme server with retries (5 attempts, 5s delay). Decodes base64 responses and saves PEM files.
Middleware Chain (middleware.rs): A series of Axum middlewares for request processing:
* wildcard.Routing and Path Matching (routing.rs, path_matcher.rs): Finds best route by scoring path patterns (exact segments > wildcards, longer prefixes preferred). Resolves ambiguities (equal scores = error). Returns ordered targets for failover.
Proxying (proxy.rs): Forwards requests to backends. Buffers body for reuse, cleans spoofable IP headers, adds X-Forwarded-For. Tries targets sequentially on failure (connection errors or 5xx). Uses hyper client with rustls.
Rate Limiting Details (ratelimit.rs): Finds best-matching limiter by path score. Separate maps for route/override rules.
TLS Resolver (tls.rs): Dynamic SNI-based cert resolution with rustls. Loads PEM certs/keys per domain.
Setup and Errors (setup.rs, error.rs): First-run creates dirs, self-signed certs (or ACME fetch), embedded status pages. Serves custom HTML error pages (400-500 range).
Servers (server/mod.rs): Runs HTTP (TCP), HTTPS (TCP with rustls), and HTTP/3 (QUIC with quinn/h3). Binds ports from env, layers middleware on Axum routers.
State (state.rs): Shared Arc
Models (models.rs): TOML-deserializable structs for configs (domains, routes, rate limits, CORS, etc.).
This design ensures scalability: async tasks for renewals, middleware for extensibility, and compiled logic for speed/security.
We recommend running Vane via Docker Compose for easy deployment and management.
Create a docker-compose.yml file:
services:
vane:
image: canmi/vane:latest
container_name: vane
networks:
- internal
env_file:
- ./.env
ports:
- "80:80/tcp"
- "443:443/tcp"
- "443:443/udp"
volumes:
- /opt/vane:/root/vane
restart: unless-stopped
networks:
internal:
driver: bridge
Create a .env file with your settings:
# Log level: debug, info, warn, error
LOG_LEVEL=info
# Ports to bind (HTTP and HTTPS/HTTP3)
BIND_HTTP_PORT=80
BIND_HTTPS_PORT=443
# Absolute path to main config (use /root for Docker)
CONFIG=/root/vane/config.toml
# Directory for ACME certificates
CERT_DIR=/root/vane/cert
# URL to lazy-acme server for cert renewal (optional for self-signed mode)
CERT_SERVER=http://your.certserver.com:port
Mount your configs/certs to /opt/vane on the host.
Run: docker compose up -d.
config.toml): Maps domains to files, e.g.:
[domains]
"example.com" = "example.com.toml"
example.com.toml): See embedded example in code for full options.For development, build from source: cargo build --release.
AGPL-3.0 (see LICENSE file).
For more details, visit the repository: https://github.com/canmi21/vane.