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"
然后创建必要的过滤器:
/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>
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
server {
listen 80;
server_name XXX;
location / {
auth_basic "Authentication required.";
auth_basic_user_file /path/to/htpasswd; # You should change this
error_page 401 /AuthFailureLimit/index.html;
root /usr/share/nginx/html/normal; # Demo
}
location /AuthFailureLimit {
internal; # To prevent visible redirects
auth_basic off; # Just in case the "auth_basic" was used in the "server" section
limit_req zone=login burst=20 nodelay;
limit_req_log_level warn; # Show blocks on the console
limit_req_status 429; # Make more sense than "503 Service Unavailable"
# ONLY use root or alias in this location, other statements (like return) will be executed before the rate limit triggers!
alias /usr/share/nginx/html/ratelimit; # Demo
}
}
据我所知,Auth Basic模块不支持此功能,但您可以使用Fail2ban来实现。
使用不存在的用户进行测试,您将在错误日志中看到如下内容:
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"
然后创建必要的过滤器:
/etc/fail2ban/filter.d/nginx-auth.conf
/etc/fail2ban/jail.conf
测试 Fail2Ban 规则:
fail2ban-regex /var/log/nginx/localhost.error_log /etc/fail2ban/filter.d/nginx-auth.conf
PS:由于 Fail2ban 会获取要禁止的日志文件,请确保
logpath
与您的配置相匹配。我很惊讶没有其他人给出这个解决方案/解决方法。
Nginx basic-auth 并
htpasswd
支持带有可选成本变量的 bcrypt 密码加密。Bcrypt 的设计速度很慢,因此对尝试不同密码的速度提供了硬性限制。创建基本身份验证用户名/密码时使用
成本为 12,您的服务器可能无法每秒尝试超过几次密码,将其增加到 14,您可能会看到每次密码尝试大约 1 秒。
通过该配置,即使攻击者连续多年尝试密码,任何合理的密码都将免受暴力攻击。
例如,以每秒 10 次密码尝试对 8 个字符的字母数字密码进行暴力攻击需要 692,351 年:
62**8 / (10*3600*24*365)
.这比设置“智能”请求限制更容易配置,也更简单。
我不相信 nginx 有任何内部设施可以做到这一点。文档页面并不表明这是可能的。
您可以使用 Fail2Ban 来阻止重复登录尝试失败的 IP 地址。
Fail2Ban wiki 有一些特定于 nginx 的模式。
Fail2Ban 应该作为一个包在大多数大型发行版上可用。
Nginx-HTTP-Auth-Digest模块可以用重试和超时等许多附加功能代替基本的 auth 模块。此处提供了其他文档
唯一的缺点是这可能需要重建 nginx
这可以通过结合 NGINX 基本身份验证和速率限制来完成。
这个片段是从我的工作配置中提取的,但片段本身没有经过测试。
基本概念是您创建一个允许绕过速率限制的 cookie,然后在有人成功通过身份验证后设置 cookie。通过这种方式,某人在登录之前会受到速率限制,此时他们可以根据需要执行任意数量的请求。
这种方法的主要缺点是 cookie 是静态的,一旦有人登录了任何帐户,他们就可以使用令牌来暴力破解其他帐户。如果您相信您的用户不会暴力破解其他用户的密码,那么这不是一个大问题。但是我不认为你可以在 NGINX 的配置中做得更好。理想情况下,cookie 应将
hash("$remote_user-SomeRandomBytes")
令牌绑定到成功登录的用户。只是为了解决我自己对这个问题的解决方案:它基于另一个(流行的)答案,类似于你的问题。这是配置:
它允许您直接使用 NGINX 的速率限制功能,而不需要客户端存储 cookie。请注意配置本身的注释,因为(由于不同的 NGINX 阶段)某些语句可能会扰乱速率限制。