防止误封合法用户的关键在于提升fail2ban识别精度:收紧正则匹配、分级白名单管理、排除良性日志、分场景设置findtime/maxretry/bantime阈值。

防止误封合法用户,关键不在“加更多规则”,而在于让 Fail2Ban 更精准地识别谁是真攻击者。核心思路是:收紧匹配逻辑、排除干扰日志、分层设置阈值、留出人工干预通道。
锚点强制行首行尾匹配
很多误封源于正则表达式太宽泛,比如只写 Failed password,结果把日志里带这几个字的正常调试信息也抓进去了。必须用 ^ 和 $ 锁定整行结构。
- 错误示例:
failregex = Failed password for .* from <host></host>(可能匹配到中间字段) - 正确写法:
failregex = ^Failed password for \S+ from <host> port \d+ ssh2?$</host> - 额外加固:加上
%(__on_port_opt)s或%(__suff)s这类官方预定义后缀变量,兼容不同系统日志格式
白名单分级管理,不只靠 ignoreip
ignoreip 只能防静态IP,对办公网络出口、云服务商跳板机这类动态出口无效。建议组合使用:
- 基础层:在
[DEFAULT]中设ignoreip = 127.0.0.1/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 - 动态层:启用
action_mw动作,配合邮件通知,收到封禁告警后手动加临时白名单 - 行为层:为内网或可信段单独建 jail,如
[sshd-trusted],设更高maxretry(如 15 次)和更长findtime(如 3600 秒)
过滤器中排除已知良性行为
某些失败登录其实是运维操作或监控探活,不是攻击。可在 filter 规则中显式排除:
- 排除特定用户名:
failregex = ^Failed password for (?!root|admin|backup).*? from <host></host> - 排除特定客户端标识:
^(?!.*Dropbear).*(避开 Dropbear 的非标准日志) - 排除健康检查请求:如果 Nginx 日志中含
status=404但http_user_agent="HealthCheck",就在 nginx-404 filter 中加负向断言
用 findtime + bantime 分段控制敏感度
不分场景统一用“5分钟5次”容易误伤。应按服务风险分级:
- SSH 登录:设
findtime = 600(10分钟),maxretry = 5,bantime = 3600(1小时)——兼顾响应与容错 - Web 登录接口(如 /login):设
findtime = 180(3分钟),maxretry = 3,bantime = 86400(24小时)——更激进,因非人工操作 - 后台管理路径(如 /wp-admin):启用
nginx-noscriptjail,但加ignorecommand = /usr/local/bin/fail2ban-ignore.sh <ip></ip>接口,供人工快速放行











