OpenShield-L7 โ
An L7-protected reverse web proxy, written in Rust. OpenShield-L7 is a filter: it sits in front of your destination web servers (ip:port), terminates ports 80/443, and forwards only clean traffic onward. It never hosts content itself โ the only bytes it originates are block pages, challenge pages, and the admin API.
One binary (openshield-l7), one global config file, one YAML file per proxied site. No database, no external services.
๐ก๏ธ Built for PingLess Studios by AnAverageBeingGitHub Repo (currently private) ยท MIT License
Key Features โ
๐ Hostname Routing on 80/443 โ
Many sites share one pair of listeners. Exact and wildcard (*.example.com) host matching, case-insensitive, port- and trailing-dot-tolerant. SNI-based certificate selection on 443. Unknown hosts get 421 โ bare-IP scanners never reach a site.
๐ Optional Per-Site TLS โ
Per-site cert/key with SNI routing (HTTP/2 + HTTP/1.1), HTTPโHTTPS 308 redirect, optional HSTS. Sites without TLS config simply never get a cert.
๐งฑ L7 WAF โ
SQLi, XSS, path traversal, and RCE pattern sets, scanner/bad-UA blocking, heuristic bot scoring, plus per-site custom regex rules over URI / query / body / method / any header. All matching is linear-time (regex crate) โ no ReDoS, and input is percent-decoded once before matching.
๐ฆ Rate + Connection Limits โ
Per-IP and per-site sliding-window request limits, concurrent in-flight connection caps, and automatic temp-bans with escalating durations for repeat offenders (doubling up to 24h). Auto-mitigation tightens all of a site's limits by a configured factor when its RPS crosses a threshold, renewing while the flood continues.
๐ Blacklists / Whitelists โ
A global ACL evaluated before any site logic, plus a per-site ACL. CIDRs or plain IPs, IPv4 and IPv6; the whitelist always wins.
๐งฉ JS Proof-of-Work Challenges โ
SHA-256 PoW page with HMAC-signed clearance cookies (osc_clear) and server-signed, self-authenticating seeds โ fully stateless: the server keeps nothing per client. Modes: off / auto (verdict-driven) / on (challenge everything).
๐ Monthly Quotas + Speed Caps โ
Per-site monthly byte quotas (persisted to disk, reset on a configurable day of month; over-quota sites serve 509 or drop connections) plus sustained bytes/sec token-bucket caps per site and per client IP.
๐ต๏ธ Transparent Client-IP Forwarding โ
Five forward modes (none / X-Forwarded-For / X-Real-Ip / Forwarded / custom header), HAProxy PROXY protocol v1/v2, and a Linux IP_TRANSPARENT mode where the origin's socket table shows the real client IP with zero origin configuration. Trusted-proxy-aware resolution walks the XFF chain right-to-left.
๐ฅ Hot-Reload Per-Site Configs โ
A file watcher re-parses only the changed file (~300 ms debounce). A broken edit never affects other sites โ the last good config keeps serving for the broken one. API writes and file edits are the same pipeline.
๐ก Token-Secured Admin API + SSE โ
REST control surface and a live Server-Sent Events telemetry stream on 127.0.0.1:9090, role-gated (admin / operator / readonly), with deep per-site analytics: top IPs/paths/UAs/rule hits, latency percentiles, and per-minute RPS/bandwidth series.
Quick Start โ
cargo build --release && ./target/release/openshield-l7 runFirst run writes a documented default config.yaml and prints one admin token โ once. Add a site file, and you're proxying. The full 30-second path is in Quick Start.
Architecture โ
One Request's Path โ
Listener โ resolve client IP (trusted-proxy aware) โ hostname โ site config snapshot โ inspector chain (first non-Allow verdict wins) โ challenge page / block page, or forward to the origin over a pooled keep-alive connection with byte metering and throttling applied to the response stream. Every request produces exactly one telemetry event on the bus, consumed by the metrics engine, the REST analytics endpoints, and the SSE stream.
Comparison โ
Factual positioning against the two common self-hosted alternatives: nginx + ModSecurity (CRS) and a hand-assembled Cloudflare-free stack (nginx + fail2ban + limit_req + scripts).
| Capability | OpenShield-L7 | nginx + ModSecurity | Cloudflare-free DIY stack |
|---|---|---|---|
| Deployment | One Rust binary, one global YAML + one YAML per site | nginx + module + CRS ruleset + tuning | nginx + fail2ban + cron + scripts |
| WAF engine | Fixed pattern families + custom rules, linear-time regex (no ReDoS) | OWASP CRS on PCRE โ powerful but ReDoS-prone, heavy FP tuning | Whatever you wire together |
| Rate limiting | Per-IP + per-site sliding windows, escalating auto-bans, RPS-triggered auto-mitigation | limit_req fixed zones; no auto-ban, no auto-tightening | limit_req + fail2ban regexes on logs (seconds of lag) |
| Bot challenges | Built-in stateless JS proof-of-work with HMAC clearance cookies | None built in | External (e.g. Anubis, custom pages) |
| Client-IP forwarding | 5 header modes + PROXY v1/v2 + IP_TRANSPARENT (origin sees real IP, zero origin config) | XFF headers only | XFF (+ PROXY with extra modules) |
| Bandwidth quotas | Monthly per-site byte quotas, persisted, 509/close on exceed | Not built in | Not built in |
| Speed caps | Sustained bps token buckets per site and per IP | limit_rate per connection only | limit_rate per connection only |
| Hot reload | Per-file, validated, failure-isolated, atomic swap; API and file edits are one pipeline | Full config reload; one bad file breaks the whole reload | Same as nginx |
| Admin surface | Token REST API + SSE events + per-site analytics (tops, latency percentiles, series) | Access logs | Access logs + your own parsing |
| Content hosting | Never โ reverse proxy only | Yes (it's a web server) | Yes |
| Maturity | New, small codebase you can read end-to-end | Battle-tested everywhere | Varies |
Bottom line: if you want a focused L7 filter in front of existing web servers โ with challenges, quotas, transparent client IP and a live API built in rather than bolted on โ OpenShield-L7 replaces a pile of moving parts with one binary. If you need a general-purpose web server or a decade of CRS rule coverage, nginx + ModSecurity remains the incumbent.
Verified Numbers โ
From the automated e2e + attack battery (Testing & Benchmarks, testing/RESULTS.md):
| Metric | Result |
|---|---|
| Unit tests | 215 passed (cargo test --workspace) |
| E2E battery | 85 / 85 passed (routing, TLS/SNI, XFF modes, WAF, limits, PoW, quotas, API roles, hot reload, bans, SSE, keep-alive, WebSocket, PROXY v1/v2, transparent mode, graceful shutdown) |
| Attack scenarios | 8 / 8 passed (HTTP flood ร2, random-Host flood ร2, POST flood, slowloris, WAF sweep, XFF spoofing) |
| HTTP flood absorbed | 152,735 rps loopback, 100% 429 โ benign site kept 100% 200 at p95 2.3 ms |
| Random-Host flood | 150,426 rps โ 100% 421, legitimate site untouched |
| Proxied throughput (loopback, protections ON) | 67,666 rps (p50 0.66 ms, p99 1.88 ms, zero errors in 541,881 requests) |
Next Steps โ
- Installation โ โ Build, systemd, sysctls, verification.
- Quick Start โ โ Proxying a site in 30 seconds.
- Configuration Reference โ โ Every config value, every default.
- CLI Reference โ โ
run/validate/gen-token/gen-cert. - Admin API โ โ Auth, roles, every endpoint, SSE.
- Architecture โ โ Crates, data flow, threading, event bus.
- Transparent Client IP โ โ
IP_TRANSPARENTdeep dive.
