На русском тута тык
Lightweight reverse proxy built on Axum (Rust) that protects your backend from crawlers, simple bots, and overload:
- IP-based Rate Limiting
- Antibot challenges: PoW, CAPTCHA (Cloudflare Turnstile or any custom), Custom
- Proper
X-Forwarded-Forchain handling - Transparent request proxying to the target backend
- Optional HTTPS support
cargo build --release[
{
"url": "http://localhost:8080", // your backend address
"proxy_host": "0.0.0.0:3000", // address:port the proxy listens on
"is_blacklist_rate_limit": true, // true = blacklist mode (only listed paths are limited), false = whitelist
"rate_limit": {
"/api": { "limit": 10, "window": 5 } // 10 requests per 5 seconds
},
"default_rate_limit": { "limit": 20, "window": 10 },
"is_blacklist_antibot": false, // true = only listed paths require challenge
"antibot": {
"/login": "CAPTCHA",
"/register": "PoW"
},
"default_antibot": "PoW",
"is_secure": false,
"cert_path": "",
"cert_key_path": ""
}
]File .SECRETKEY (64 random bytes):
Place challenge and error templates in the templates/ directory:
templates/
├── captcha.html ← Cloudflare Turnstile / hCaptcha / any slider captcha
├── pow.html ← Proof-of-Work challenge page
├── custom.html ← your own custom challenge page
├── 429.html ← Too Many Requests
├── 500.html ← Internal Server Error
├── 502.html ← Bad Gateway
└── 504.html ← Gateway Timeout
- Slider-based.
- Detects mouse behavior
- Client must find a nonce such that the first N bits of SHA256(
token + nonce) are zeros. - Solution is sent via POST →
/powver:
{ "token": "random_str", "nonce": 123456, "bits": 20 }Configure in config.json:
"antibot": {
"/somepath": {
"type": "Custom",
"verify_url": "https://your-service/verify",
"secret_key": "supersecret123"
}
}The proxy will forward secret_key + user token to your verification endpoint via POST → /tokenver.
- Tracks real client IP (even behind multiple proxies)
limit— max requests allowedwindow— time window in seconds- Prefix path matching via Trie (e.g.,
/api/v1/protects the entire subtree)
Set "is_secure": true and provide certificate paths:
"cert_path": "/path/to/fullchain.pem",
"cert_key_path": "/path/to/privkey.pem"All headers are forwarded except:
hostcontent-lengthconnectiontransfer-encodingdatecontent-encoding
Automatically appends:
X-Forwarded-For: <client_ip>, <previous_proxy>, ...
After successful challenge completion, a signed cookie is set:
checked=1
- Lifetime: 36 hours
