Nginx
被 HEAD 請求淹沒
我們的伺服器被 HEAD 請求淹沒了。
這導致 tcp 連接激增,導致伺服器無法連接到其 mysql 數據庫。
我們廣泛使用了 nginx 速率限制,它與 fail2ban 完美結合,適用於任何 GET 和 POST 請求。但是,似乎沒有收到 HEAD 請求。
我們使用的 fail2ban filter.d 操作
nginx-limit-req
似乎是一個股票配置,用於檢測何時達到 nginx 區域限制。由於我們的 webapp 不需要 HEAD 請求,我們有兩個選擇(除了手動禁止單個 IP 地址)
- 有沒有辦法禁用 HEAD 請求?這似乎是氣餒,但它可能仍然嗎?
- 是否可以讓 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; } ... }
監獄.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,違規者ip被封禁後正常化:
要在 Nginx 配置中禁用 HEAD 請求,只需將以下內容添加到您的伺服器塊中:
if ($request_method = HEAD) { return 444; }
444 HTTP 狀態碼是 Nginx 特有的,會丟棄所有 HEAD 請求,因此客戶端發起 HEAD 請求的連接失敗。這些嘗試的連接仍會記錄在 Nginx 日誌中,因此您可以在防火牆配置中禁止相關 IP。