被 HEAD 请求淹没

被 HEAD 请求淹没

我们的服务器被大量 HEAD 请求淹没了。

这导致 tcp 连接数激增,使得服务器无法连接到其 mysql 数据库。

我们大量使用 nginx 速率限制,它与 fail2ban 结合使用,可完美处理任何 GET 和 POST 请求。但是,HEAD 请求似乎未被接收。

我们使用的 fail2ban filter.d 操作nginx-limit-req似乎是一个 stock-config,用于检测何时达到 nginx 区域限制。

由于我们的 Web 应用不需要 HEAD 请求,因此我们有两个选择(除了手动禁止单个 IP 地址)

  1. 有没有办法禁用 HEAD 请求?似乎不建议这么做,但仍然可行吗?
  2. 是否可以让 nginx 区域限制器识别任何 GET/POST/HEAD 请求并进行相应的限制?

nginx.conf:

http {
  ...
  limit_req_zone "$http_x_forwarded_for" zone=web_zone:50m rate=2r/s;
  ...
}

server {
  ...
  fastcgi_buffers 16 16k;
  fastcgi_buffer_size 32k;

  location / {
    limit_req zone=web_zone burst=25;
    try_files $uri $uri/ @pretty-urls;
  }
  ...
}

jail.conf:

[nginx-limit-req]
enabled = true
filter = nginx-limit-req
action = custom-iptables-proxy
port = http,https
logpath = /var/log/nginx/*error*.log
findtime = 10
bantime = 3600
maxretry = 3

nginx-限制-req.conf:

[Definition]
ngx_limit_req_zones = [^"]+
failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
ignoreregex =
datepattern = {^LN-BEG}

来自 accesslog 的示例: 在此处输入图片描述

事件发生期间的 netdata,在违规者 IP 被封禁后恢复正常:

在此处输入图片描述

答案1

要在 Nginx 配置中禁用 HEAD 请求,只需将以下内容添加到您的服务器块中:

if ($request_method = HEAD) {
    return 444;
}

444 HTTP 状态代码是 Nginx 特有的并将丢弃所有 HEAD 请求,因此发起 HEAD 请求的客户端的连接将失败。这些尝试的连接仍会记录在 Nginx 日志中,因此您可以在防火墙配置中禁止相关 IP。

相关内容