Fail2Ban不能单独防御CC攻击,它仅通过日志分析封禁IP,不参与实时限流;真正拦截高频请求的是Nginx的limit_req机制,二者需配合:Nginx作第一道实时流量闸门,Fail2Ban则作为事后精准清剿的巡逻者。

Fail2Ban 不能单独防 CC 攻击,它不拦请求,只看日志、数次数、封 IP。真正挡流量的是 Nginx 自身的限流机制;Fail2Ban 的作用是“抓漏网之鱼”——把绕过限流、反复试探、触发异常的恶意 IP 精准揪出来并拉黑。两者必须配合,才构成完整防线。
先用 Nginx 做实时限流(守门)
Nginx 是第一道屏障,必须在请求到达后端前就压住流量:
- 在 http{} 块中定义限流区:
limit_req_zone $binary_remote_addr zone=cc:10m rate=15r/s;(每秒最多 15 次,推荐博客类用 10r/s,API 类可用 20–30r/s) - 在 location / 或具体接口路径(如 location /api/)中启用:
limit_req zone=cc burst=30 nodelay;(允许突发 30 次,超了立刻返回 503) - 务必用
$binary_remote_addr而非$remote_addr,更省内存且兼容 IPv6;若走 CDN,需提前配置real_ip_module还原真实 IP
再让 Fail2Ban 监控 access.log 封高频触发者(巡逻)
当攻击者被限流打回大量 503,或故意低频扫接口时,Fail2Ban 从 access.log 中识别行为并封禁:
- 新建过滤器
/etc/fail2ban/filter.d/nginx-cc.conf,匹配 503 请求:failregex = ^<HOST> -.*"(GET|POST).*"503 .*$ - 在
/etc/fail2ban/jail.local或独立 jail 文件中添加规则:
[nginx-cc]<br> enabled = true<br> filter = nginx-cc<br> logpath = /var/log/nginx/access.log<br> maxretry = 8<br> findtime = 60<br> bantime = 3600<br> action = iptables-multiport[name=NGINX_CC, port="http,https"]
(1 分钟内出现 8 次 503 即封 1 小时) - 避免误伤:可加
ignoreregex = health|monitor|/static/排除健康检查和静态资源路径
进阶:用 error.log 补盲,抓更隐蔽的攻击
access.log 里全是 200 不代表安全;error.log 才暴露真实意图,比如慢速连接、非法协议、后端探活失败:
- 确保 Nginx error.log 输出真实 IP:启用
log_subrequest on;,并在 location 中加入带 IP 的自定义错误输出,例如应用层写[BLOCK_ME] Client: 1.2.3.4 - 新建过滤器
/etc/fail2ban/filter.d/nginx-error-block.conf,匹配关键信号:
failregex = ^\s*\[error\].*client <host>.*upstream timed out.*$<br> ^\s*\[error\].*\[BLOCK_ME\] Client: <host>$ - 对应 jail 配置更激进:
maxretry = 3、findtime = 60、bantime = 1800(3 次即封 30 分钟)
验证与上线前必做三件事
配置完别急着 reload,否则可能白忙活:
- 用
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-cc.conf测试正则是否真能捕获目标日志行 - 执行
fail2ban-client status nginx-cc查看当前 jail 是否加载成功、匹配数是否增长 - 手动模拟攻击(如用 curl 快速刷 10 次触发 503),再查
iptables -L -n | grep NGINX_CC确认 DROP 规则已生效


















