feat: add global and burst rate limiters
Three layers of rate limiting, all disabled by default, opt-in via config: 1. Per-IP (existing): 30 req/min per IP 2. Global: server-wide limit across all IPs - Lock-free atomic counter for minimal overhead - Returns 503 when exceeded - Prevents pool exhaustion from distributed attacks 3. Burst: per-IP burst + sustained windows - Blocks rapid-fire abuse within seconds - Returns 429 with X-RateLimit-Reason header - Example: 5 req/5s burst, 60 req/min sustained Config: [global_rate_limit] requests = 0 # disabled by default window = "1m" [burst_rate_limit] burst = 0 # disabled by default burst_window = "5s" sustained = 0 sustained_window = "1m" Env overrides: GLOBAL_RATE_LIMIT_REQUESTS, GLOBAL_RATE_LIMIT_WINDOW, BURST_RATE_LIMIT_BURST, BURST_RATE_LIMIT_BURST_WINDOW, BURST_RATE_LIMIT_SUSTAINED, BURST_RATE_LIMIT_SUSTAINED_WINDOW Full test coverage: concurrent lock-free test, window expiry, disabled states, IP isolation, burst vs sustained distinction.
This commit is contained in:
parent
91ab76758c
commit
13040268d6
7 changed files with 657 additions and 18 deletions
|
|
@ -66,3 +66,28 @@ requests = 30
|
|||
window = "1m"
|
||||
# How often to clean up stale IP entries (env: RATE_LIMIT_CLEANUP_INTERVAL)
|
||||
cleanup_interval = "5m"
|
||||
|
||||
[global_rate_limit]
|
||||
# Server-wide rate limit across ALL IPs. Prevents pool exhaustion from
|
||||
# distributed attacks even when per-IP limits are bypassed via VPNs.
|
||||
# Returns 503 when exceeded. Set to 0 to disable.
|
||||
# Env: GLOBAL_RATE_LIMIT_REQUESTS
|
||||
requests = 0
|
||||
# Env: GLOBAL_RATE_LIMIT_WINDOW
|
||||
window = "1m"
|
||||
|
||||
[burst_rate_limit]
|
||||
# Per-IP burst + sustained rate limiting. More aggressive than the standard
|
||||
# per-IP limiter. Blocks rapid-fire abuse even if the per-minute limit isn't hit.
|
||||
# Returns 429 with X-RateLimit-Reason header. Set burst to 0 to disable.
|
||||
#
|
||||
# Example: burst=5, burst_window="5s" means max 5 requests in any 5-second span.
|
||||
# sustained=60, sustained_window="1m" means max 60 requests per minute.
|
||||
# Env: BURST_RATE_LIMIT_BURST
|
||||
burst = 0
|
||||
# Env: BURST_RATE_LIMIT_BURST_WINDOW
|
||||
burst_window = "5s"
|
||||
# Env: BURST_RATE_LIMIT_SUSTAINED
|
||||
sustained = 0
|
||||
# Env: BURST_RATE_LIMIT_SUSTAINED_WINDOW
|
||||
sustained_window = "1m"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue