fail2ban生产环境中应避免永久封禁,bantime需按服务类型分级设定(ssh 1h~4h、web登录15m~30m、api/后台30m~2h、扫描探测10m~20m),并启用自适应递增封禁与精准白名单及正则过滤以降低误封。

Fail2Ban 在生产环境中不能无限制封禁 IP,否则可能误伤合法用户、引发服务中断或被攻击者利用“封禁耗尽”策略反制。最大封禁时间(bantime)必须结合业务容忍度、攻击特征和运维响应能力来设定,而非简单设为永久(-1)。
明确 bantime 的实际含义与风险
bantime 是单次触发后该 IP 被防火墙规则禁止访问的持续时长。它不是“累计封禁时间”,也不是“黑名单保留时间”——到期即自动解封,不依赖手动清理。
- 设为
-1(永久封禁)在生产环境极不推荐:一旦因日志误匹配、内网 NAT 共享出口 IP、或 CDN 回源异常导致误封,将造成不可逆的服务阻断 - 过短(如 60 秒)起不到防护作用,攻击者可快速重试绕过
- 过长(如 7 天以上)会堆积大量 iptables 规则,影响防火墙性能,且违背“最小必要封禁”原则
按服务类型分级设置封禁时长
不同服务面对的攻击模式和误封代价不同,应差异化配置 bantime,避免全局一刀切:
-
SSH 服务([sshd]):建议
bantime = 1h~4h。暴力破解通常集中爆发,短期封禁足够打断扫描节奏;超时后若再犯,会重新计数,形成“打-封-再打-再封”的可控压制 -
Web 登录接口(如 WordPress wp-login.php):建议
bantime = 15m~30m。用户输错密码较常见,需兼顾体验与防护;可配合findtime = 5m+maxretry = 3提高灵敏度 -
API 或后台管理路径(/admin, /api/auth):建议
bantime = 30m~2h。这类接口敏感度高,但正常调用频率低,稍长封禁更稳妥 -
扫描探测类(如 nginx-http-bad-request、nginx-botsearch):建议
bantime = 10m~20m。扫描器 IP 常为临时代理,短时封禁成本低、效果好
启用自适应封禁(递增式 bantime)
对反复触发的恶意 IP,可使用 bantime.increment 和 bantime.factor 实现“越犯越久”的惩罚机制,避免固定时长被摸清规律:
- 在
[sshd]或对应 jail 段中添加:bantime.increment = truebantime.factor = 2 - 首次触发封禁 1 小时,第二次触发封禁 2 小时,第三次 4 小时……上限由
bantime.maxtime控制(如设为24h) - 需确保
dbfile = /var/lib/fail2ban/fail2ban.sqlite3已启用(默认开启),用于记录历史处罚次数
配合 ignoreip 和 failregex 精准降低误封
最大封禁时间再合理,也救不了错误匹配。必须从源头减少误触发:
- 白名单务必包含所有运维出口、监控系统、CDN 回源段(如 Cloudflare 的 IP 段),写入
ignoreip,避免封禁自身流量 - 自定义
failregex时,优先用带上下文的正则,例如匹配 SSH 失败只抓"Failed password.*from <host>"</host>,而非泛匹配"Failed";Web 类规则建议加上状态码限定(如" 401 " 或 " 403 ") - 对高频合法请求(如健康检查、爬虫白名单 UA),可在 filter 中用
ignoreregex过滤掉,不计入失败计数











