¿Cómo limitar los reintentos de Nginx Auth_Basic?

¿Cómo limitar los reintentos de Nginx Auth_Basic?

He protegido una carpeta web con el módulo Auth_Basic de Nginx. El problema es que podemos probar varias contraseñas hasta que funcione (ataques de fuerza bruta). ¿Hay alguna manera de limitar el número de reintentos fallidos?

Respuesta1

Por lo que yo sé,Autenticación básicaEl módulo no admite esta característica, pero puedes hacerlo usandofalla2ban.

Al realizar la prueba con un usuario inexistente, verá algo como lo siguiente en el registro de errores:

2012/08/25 10:07:01 [error] 5866#0: *1 no user/password was provided for basic authentication, client: 127.0.0.1, server: localhost, request: "GET /pma HTTP/1.1", host: "localhost:81" 2012/08/25 10:07:04 [error] 5866#0: *1 user "ajfkla" was not found in "/etc/nginx/htpasswd", client: 127.0.0.1, server: localhost, request: "GET /pma HTTP/1.1", host: "localhost:81"

Luego crea el filtro necesario:

/etc/fail2ban/filter.d/nginx-auth.conf

[Definition]
failregex = no user/password was provided for basic authentication.*client: <HOST>
              user .* was not found in.*client: <HOST>
              user .* password mismatch.*client: <HOST>
ignoreregex = </host></host></host> 

/etc/fail2ban/jail.conf

[nginx-auth]
enabled = true
filter = nginx-auth
action = iptables[name=NoAuthFailures, port=80, protocol=tcp]
logpath = /var/log/nginx*/*error*.log
bantime = 3600 # 1 hour
maxretry = 3

Probando las reglas de Fail2Ban:

fail2ban-regex /var/log/nginx/localhost.error_log /etc/fail2ban/filter.d/nginx-auth.conf

Failregex
|- Regular expressions:
|  [1] no user/password was provided for basic authentication.*client: <HOST>
|  [2] user .* was not found in.*client: <HOST>
|  [3] user .* password mismatch.*client: <HOST>
|
`- Number of matches:
   [1] 1 match(es)
   [2] 2 match(es)
   [3] 0 match(es)

Ignoreregex
|- Regular expressions:
|
`- Number of matches:

Summary
=======

Addresses found:
[1]
    127.0.0.1 (Sat Aug 25 10:07:01 2012)
[2]
    127.0.0.1 (Sat Aug 25 10:07:04 2012)
    127.0.0.1 (Sat Aug 25 10:07:07 2012)
[3]

PD: Dado que Fail2ban recupera los archivos de registro para prohibirlos, asegúrese de que logpathcoincidan con su configuración.

Respuesta2

Me sorprende que nadie más haya dado esta solución/solución alternativa.

Nginx basic-auth y htpasswdadmite cifrado de contraseña bcrypt con una variable de costo opcional. Bcrypt está diseñado para ser lento, lo que proporciona un límite estricto a la velocidad con la que se pueden intentar diferentes contraseñas.

Al crear su nombre de usuario/contraseña de autenticación básica

htpasswd -B -C 12 path/to/users.db <username>

Con un costo de 12, es probable que su servidor no pueda probar contraseñas más que unas pocas veces por segundo; aumente eso a 14 y probablemente verá alrededor de 1 por intento de contraseña.

Con eso configurado, cualquier contraseña razonable será inmune a ataques de fuerza bruta incluso si el atacante intentó contraseñas continuamente durante años.

Por ejemplo, a 10 intentos de contraseña por segundo, un ataque de fuerza bruta a una contraseña alfanumérica de 8 caracteres tardaría 692.351 años: 62**8 / (10*3600*24*365).

Esto es mucho más fácil de configurar y más infalible que configurar una limitación de solicitudes "inteligente".

Respuesta3

No creo que nginx tenga ninguna instalación interna para hacer esto. Elpágina de documentaciónno sugiere que sea posible.

Puede utilizar Fail2Ban para bloquear direcciones IP que hayan repetido intentos fallidos de inicio de sesión.

La wiki de Fail2Ban tiene algunospatrones específicos de nginx.

Fail2Ban debería estar disponible como paquete en la mayoría de las grandes distribuciones.

Respuesta4

Esto se puede lograr con una combinación de autenticación básica NGINX y limitación de velocidad.

http {
    map $http_cookie $rate_limit_key {
        default $binary_remote_addr;
        "~__Secure-rl-bypass=SomeRandomBytes" "";
    }
    limit_req_status 429;
    limit_req_zone $rate_limit_key zone=auth:10m rate=1r/m;

    server {
            auth_basic "Private Content";
            auth_basic_user_file your-auth-file.txt;

            limit_req zone=auth burst=20 delay=10;

            add_header Set-Cookie "__Secure-rl-bypass=SomeRandomBytes;Max-Age=${toString (3600*24*180)};Domain=$host;Path=/;Secure;HttpOnly";
    }
}

Este fragmento se extrajo de mi configuración de trabajo, pero el fragmento en sí no se probó.

El concepto básico es que usted crea una cookie que permite eludir el límite de velocidad y luego configura la cookie una vez que alguien se autentica exitosamente. De esta manera, alguien tiene una velocidad limitada hasta que inicia sesión, momento en el que puede realizar tantas solicitudes como desee.

La principal desventaja de este enfoque es que la cookie es estática; una vez que alguien inicia sesión en cualquier cuenta, puede usar el token para forzar brutalmente otras cuentas. Esto no es un problema importante si se confía en que sus usuarios no forzarán la contraseña de otros usuarios. Sin embargo, no creo que puedas hacerlo mejor que esto en la configuración de NGINX. Lo ideal sería que la cookie hash("$remote_user-SomeRandomBytes")vinculara el token al usuario que inició sesión correctamente.

información relacionada