Dada una configuración simple de autenticación básica HTTP en Nginx (1.14.1 al momento de escribir este artículo) como esta:
server {
...
location / {
auth basic "HTTP Auth Required";
auth basic user file "/path/to/htpasswd";
}
}
... ¿cómo se aplicaría una limitación de velocidad a los intentos fallidos de inicio de sesión? Por ejemplo, si hay 10 intentos fallidos de inicio de sesión en 30 segundos, me gustaría evitar que esa IP de origen acceda al sitio durante una hora. Esperaría hacer uso de limit_req_zone
directivas relacionadas, pero no pude encontrar una manera de conectarme al estado de autenticación de la solicitud.
Esto es bastante sencillo en HAproxy con tablas stick y ACL usando algo como el siguiente ejemplo de trabajo.
userlist users
user me password s3cr3t
frontend https.local
...
# Set up the stick table to track our source IPs, both IPv4 & IPv6
stick-table type ipv6 size 100k expire 1h store http_req_rate(30s)
# Check if the user has authenticated
acl auth_ok http_auth(users)
# Track the client IP
http-request track-sc0 src
# Deny the connection if it exceeds 10 requests within the defined
# stick-table period AND if the client isn't authenticated already
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10 } !auth_ok
# Define the auth realm if the users isn't authenticated and made it this far
http-request auth realm Authorization\ Required unless auth_ok
¿Es esto posible con Nginx sin tener que utilizar el un mecanismo de autenticación externo?auth_request
enfoque y tener que aplicar la solicitud que limita a un location
bloque
Respuesta1
También puedes usar fail2ban y luego una cárcel para nginx.
Respuesta2
limit_req_status 429;
auth_basic "-";
auth_basic_user_file "...";
error_page 401 = @nein;
proxy_intercept_errors on; # not needed if not proxying
location / {
# note you cannot use a short circuiting `return` here.
try_files /dev/null =204;
}
location @nein {
internal ;
limit_req zone=<zone>;
# this is the magic trick, `try_files` takes place AFTER `limit_req`.
try_files /dev/null =401;
}
Nota: esto solo tiene efecto DESPUÉS de una autenticación fallida, por lo que debe jugar con el límite de ráfaga para retrasar las siguientes solicitudes. Ni siquiera estoy seguro de si es posible proteger las cosas de esta manera contra ataques de fuerza bruta.