Our server got flooded with HEAD requests.
This resulted in a spike in tcp connections that made the server unable to connect to its mysql databases.
We make extensive use of the nginx ratelimiting, that works in combination with fail2ban flawlessly for any GET and POST requests. However, HEAD requests seem to not be picked up.
The fail2ban filter.d action we use is nginx-limit-req
which seems to be a stock-config to detect when a nginx zone limit is reached.
As our webapp doesnt need HEAD requests, we have two options (aside from banning the individual IP addresses by hand)
- Is there a way to disable HEAD requests? It seems to be discouraged but is it possible nontheless?
- Would it be possible to make the nginx zone limiter recognize any GET/POST/HEAD request and limit it accordingly?
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-limit-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}
netdata during the incident, normalized after the offenders ip was banned: