mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 21:33:02 +02:00
Adds an nginx-side rate limit on POST /login so a brute-force or DoS attempt can't pin the box on the bcrypt-shaped credential check inside rousette/PAM. Configuration: - Keyed on $binary_remote_addr (per source IP), 5 requests/minute sustained with a burst of 3 nodelay, a real user fumbling their password three times in a row sails through; the 4th attempt in the same window returns 429. - GET /login is unmetered (the keyed map yields the empty string, which limit_req treats as "no key, no limit"), so a 401-driven HX-Redirect bouncing the user back to the login page doesn't eat into the budget. - 32k zone (~500 IPs, the minimum nginx accepts). At cache saturation an attacker rotating addresses still tops out around ~2500 attempts/min, all serialised through bcrypt one at a time. - 429 instead of the default 503 keeps the response out of the /50x.html error_page rewrite (which auto-refreshes and would loop a throttled client straight back to /login). Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
33 lines
1.1 KiB
Plaintext
33 lines
1.1 KiB
Plaintext
# Must be at server scope, not on an inner location: client_max_body_size
|
|
# does not inherit into a nested location that declares its own proxy_pass,
|
|
# and the http-level 1m default would silently apply and reject firmware
|
|
# uploads with 413.
|
|
client_max_body_size 256m;
|
|
|
|
location / {
|
|
include /etc/nginx/webui-proxy.conf;
|
|
}
|
|
|
|
# burst=3 nodelay: three POSTs land back-to-back; the next needs a
|
|
# fresh token (~12 s at 5r/m) or 429s.
|
|
location = /login {
|
|
limit_req zone=webui_login burst=3 nodelay;
|
|
include /etc/nginx/webui-proxy.conf;
|
|
}
|
|
|
|
# Keep proxy_request_buffering on (the default). Streaming the body races
|
|
# the Go handler's response close, producing RST instead of FIN at
|
|
# Content-Length and a client-visible 502. nginx spools the body to
|
|
# /var/cache/nginx/client-body during the upload instead.
|
|
location = /firmware/upload {
|
|
proxy_read_timeout 600s;
|
|
include /etc/nginx/webui-proxy.conf;
|
|
}
|
|
|
|
# Liveness probe — nginx-only, no upstream call. Used by the watchdog
|
|
# div in base.html and the reboot-overlay poller.
|
|
location = /device-status {
|
|
access_log off;
|
|
return 204;
|
|
}
|