任何服务器迟早都会受到洪水攻击(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