Fail2Ban内存堆积本质是FailManager累积失败记录未及时清理,关键在findtime设置过长导致记录驻留内存;需收紧findtime与maxretry组合、优化dbmaxmatches和dbpurgeage、提升failregex精确度。

Fail2Ban 封禁队列内存堆积,本质是 FailManager 持续累积失败记录未及时清理,尤其在高并发或 findtime 设置过长时,会导致 RSS 内存线性增长、响应延迟甚至 OOM。关键不在“封了多少 IP”,而在“记了多久的失败行为”。
检查 FailManager 内存留存逻辑
Fail2Ban 的内存管理核心是 FailManager 类,它按 IP 维护失败时间戳列表。默认配置下:
-
findtime = 600(10 分钟):意味着每个 IP 的所有失败记录都保留在内存中至少 10 分钟 - 若每秒有 50 条失败日志(如 SSH 暴破),单 IP 在 10 分钟内就可能积累 3000+ 条记录
- 成百上千个扫描 IP 同时活跃,内存自然快速膨胀
收紧 findtime 与 maxretry 组合策略
这不是简单调小数值,而是要匹配真实攻击节奏:
- 对 SSH 暴力破解:将
findtime从 600 秒降至 180 秒(3 分钟),maxretry保持 5;既覆盖典型爆破窗口,又大幅缩短内存驻留时间 - 对 Nginx 错误类规则(如 upstream timeout):可设
findtime = 60,因这类异常往往瞬时集中爆发,无需保留太久 - 避免
findtime > bantime:否则封禁已生效,失败记录还在内存里“躺尸”
启用数据库缓存限流机制
Fail2Ban 默认用 SQLite 存储持久化匹配记录,但 dbmaxmatches 和 dbpurgeage 直接影响内存压力:
- 在
jail.local中显式设置:dbmaxmatches = 3(只存最近 3 次匹配,而非默认 10) - 缩短清理周期:
dbpurgeage = 6h(6 小时清一次库,防止旧数据拖慢查询) - 若不依赖历史审计,可关闭数据库:
dbfile = /dev/null,完全走内存管理(需确保findtime合理)
过滤器层面减少无效入队
很多内存堆积源于“不该进 FailManager 的日志行也被匹配了”:
- 检查
filter.d/下对应规则(如sshd.conf),确认failregex是否过于宽泛;例如用Failed password for .* from <HOST>会捕获所有失败,而加invalid user前置条件可排除合法用户输错密码的噪音 - 利用
ignoreregex过滤已知良性来源,如监控脚本 IP、内部运维地址 - 禁用低价值 jail(如
apache-badbots),避免为爬虫类流量消耗内存资源
内存堆积不是 Bug,而是配置与流量特征错配的结果。重点盯住 findtime 生命周期、dbmaxmatches 缓存深度、以及 failregex 的精确度,三者协同调整,RSS 就能稳定在 80–150MB 区间。

















