Image

知识库 → 防止nginx服务器泛洪(频繁定期抓取页面)

[虚拟服务器]
出版日期: 10.09.2025

任何服务器迟早都会受到洪水攻击(flooding),这会导致服务负载增加和资源使用量升高。互联网上的大量机器人会扫描网站以查找漏洞并收集数据。

这些机器人具有恶意行为,为了不浪费服务器资源在它们身上,应该将其阻止。

在本文中,我们讨论的是对抗洪水攻击的一种特定方法。对抗 DDoS 攻击需要使用其他服务和方法。

此类请求的示例:

100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /aa.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /file.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /file.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp-file.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp-file.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /k.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /k.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /al.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /al.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp- HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /wp- HTTP/1.1" 404 48273 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /admin.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /admin.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /file2.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /file2.php HTTP/1.1" 404 27 "-" "-"

从日志中可以看出,该机器人在一秒钟内向服务器发出了大约9个请求,这相当多,尤其是考虑到可能有多个具有不同IP地址的此类机器人。这可能会对虚拟服务器造成显著的负载。

我们的任务是阻止发出大量常规请求的IP地址,同时排除静态文件——我们只计算动态请求,因为它们才是造成负载的原因。

1. 安装 Fail2ban

apt install fail2ban

2. 配置

nano /etc/fail2ban/jail.local
[DEFAULT]
# 主要设置
ignoreip = 127.0.0.1/8 ::1
bantime = 3600
findtime = 600
maxretry = 200

# 邮件设置
destemail = corp@domain.tld
sender = fail2ban@domain.tld
sendername = Fail2Ban
mta = sendmail

# 默认操作(带邮件通知)
action = %(action_mwl)s

[nginx-flood]
enabled = true
port = http,https
filter = nginx-flood
logpath = /var/log/nginx/*access*.log
maxretry = 200
findtime = 60
bantime = 3600
# action 从 DEFAULT 继承,因此无需重复

2.1 过滤器本身

nano /etc/fail2ban/filter.d/nginx-flood.conf
[Definition]
# 从计数中排除静态文件
failregex = ^<HOST> -.*"(GET|POST|HEAD) (?!.*\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot|svg|pdf|txt|xml)(\?.*)?$).* HTTP/\d\.\d".*
ignoreregex = 
datepattern = ^[^\[]*\[({DATE})\s+({TIME})\s+[^\]]*\]

2.2 修改

别忘了将电子邮件地址更改为您的:

destemail = corp@domain.tld
sender = fail2ban@domain.tld

2.3 触发阈值

如有必要,请根据您的需求调整参数,以避免误报:

maxretry = 200
findtime = 60
bantime = 3600

3. 启动服务

systemctl restart fail2ban
systemctl enable fail2ban

4. 查看和管理

4.1 查看被阻止的IP

对于 iptables

iptables -L -n

对于 fail2ban

fail2ban-client status nginx-flood

4.2 测试

暂时将测试IP添加到封禁列表

fail2ban-client set nginx-flood banip 1.2.3.4

检查是否已阻止以及是否收到了电子邮件

fail2ban-client set nginx-flood unbanip 1.2.3.4




No Comments Yet