遇到恶意流量时,最稳妥的做法是先通过日志确认攻击特征,再针对单个高频 IP 进行封禁,避免直接封禁整个网段导致误伤正常用户。
先说结论:日志分析是定位问题的手段,封禁是后续动作,建议设定具体阈值(如每分钟超过 100 次)后再考虑自动化,防止误封正常流量。
- 先判断:确认是扫描、爬虫还是正常高峰,避免把 CDN 节点当成攻击者。
- 优先做:先用 Nginx 自带 deny 指令封禁单个 IP,观察业务影响。
- 再验证:确认封禁生效后,再考虑是否引入 fail2ban 等自动化工具。
命令速用版
以下命令用于快速提取访问频率最高的 IP 地址,假设日志格式为默认的 combined 格式:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10
如果需要查看特定时间段(例如最近 1000 行):
tail -n 1000 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10
按网段聚合分析:若需识别恶意 IP 段,可提取前三段进行统计:
awk '{print $1}' /var/log/nginx/access.log | cut -d. -f1-3 | sort | uniq -c | sort -nr | head -n 10
Nginx 日志分析原理
Nginx 访问日志记录了每个请求的来源 IP、时间、请求路径和状态码。恶意行为通常表现为某个 IP 在短时间内发起大量请求,或者频繁访问不存在的路径(导致 404 激增)。通过统计 IP 出现频率,可以找出异常流量来源。但需要注意,日志中的 IP 不一定是用户真实 IP,如果服务器前有 CDN 或负载均衡器,记录的可能是一层代理的地址。
分步处理
1. 备份配置文件
修改配置前务必备份,防止配置错误导致服务无法启动:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
2. 提取可疑 IP
使用上述命令找出频率最高的 IP。如果某个 IP 的请求量远超其他 IP,且伴随大量 403、404 或 500 状态码,可列为可疑对象。
3. 创建封禁配置文件
不要在主配置文件中直接写大量 deny 规则,建议单独建立一个文件,例如 /etc/nginx/conf.d/deny_ips.conf:
deny 192.168.1.100;
deny 10.0.0.5;
4. 在主配置中引入
在 nginx.conf 的 http 或 server 块中添加 include 指令。注意:server 块中的规则优先级高于 http 块,且规则按顺序匹配,一旦匹配成功即停止。
http {
include /etc/nginx/conf.d/deny_ips.conf;
server {
# 或者放在 server 块内针对特定域名生效
include /etc/nginx/conf.d/deny_ips.conf;
}
}
5. 检查配置并重载
修改配置前务必检查语法,避免写错导致 Nginx 无法启动:
nginx -t
nginx -s reload
获取真实 IP 配置方案
如果站点接了 CDN,日志里的 IP 可能是 CDN 节点的 IP。直接封禁会导致该节点下所有用户无法访问。此时需要配置 Nginx 获取真实 IP(需编译时包含 ngx_http_realip_module):
http {
set_real_ip_from 10.0.0.0/8; # CDN 厂商提供的 IP 段
real_ip_header X-Forwarded-For;
real_ip_recursive on;
}
Fail2ban 基础配置示例
若需自动化封禁,可安装 fail2ban 并配置 /etc/fail2ban/jail.local:
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
怎么验证是否生效
1. 本地测试
如果条件允许,用被封禁的 IP 环境发起请求,预期返回 403 Forbidden 状态码。
2. 日志观察
继续观察 access.log,确认被封禁 IP 的请求是否减少,或者状态码是否变为 403。注意,如果攻击者更换 IP 段,封禁单个 IP 可能效果有限。
3. 业务确认
确认正常用户访问不受影响,特别是当你在云服务器上操作时,确保没有误封自己的管理 IP 或办公网出口 IP。
常见坑
- CDN 导致的误判:如果站点接了 CDN,日志里的 IP 可能是 CDN 节点的 IP。直接封禁会导致该节点下所有用户无法访问。此时需要配置 Nginx 获取真实 IP(如通过 X-Forwarded-For 头)。
- 封禁网段过大:使用 CIDR 格式(如 192.168.1.0/24)封禁时,务必确认该网段内没有正常用户,否则会造成大面积不可用。
- 配置优先级:Nginx 的 allow/deny 规则按顺序匹配,一旦匹配成功即停止。确保 allow 规则放在 deny 之前,或者逻辑清晰,避免把自己关在门外。
- 自动化风险:使用 fail2ban 等工具自动封禁时,要设置合理的阈值和封禁时长,避免因短暂流量波动导致永久封禁。
参考来源
- Nginx 官方文档:ngx_http_access_module 模块说明,https://nginx.org/en/docs/http/ngx_http_access_module.html
- Fail2ban 项目仓库:自动化封禁工具参考,https://github.com/fail2ban/fail2ban