Fail2ban服务显示active,并不代表指定jail已经读到失败日志,也不代表封禁规则成功写入防火墙。它的完整链路是读取日志、过滤命中、在时间窗口内累计失败、触发动作并由防火墙执行。
排查时应沿链路逐层验证,避免一开始就降低 maxretry 或手工添加永久封禁规则。

先确认jail真正启用
查看服务与已启用jail:
sudo systemctl status fail2ban --no-pager
sudo fail2ban-client status
sudo fail2ban-client status sshd
总状态没有列出 sshd,说明该jail没有成功启用。检查本地覆盖配置:
sudo fail2ban-client -d | less
sudo journalctl -u fail2ban --since "30 minutes ago" --no-pager
优先在 jail.local 或 jail.d/*.local 中写覆盖项,不要直接修改随软件包升级的 jail.conf。服务active但目标jail缺失时,后续过滤和封禁都不会发生。
分清文件日志与systemd后端
文件后端依赖 logpath,例如发行版使用 /var/log/auth.log 或 /var/log/secure。先确认认证失败确实写入该文件:
sudo tail -n 100 /var/log/auth.log
sudo tail -n 100 /var/log/secure
使用 backend = systemd 时,Fail2ban官方明确说明 logpath 无效,日志选择来自filter中的 journalmatch。应直接检查journal:
sudo journalctl -u ssh -u sshd --since "10 minutes ago" --no-pager
后端和实际日志位置不匹配,是服务正常却零命中的常见原因。 不要同时依赖无效的logpath和systemd后端。
用fail2ban-regex验证过滤器
文件日志可直接测试发行版自带的sshd过滤器:
sudo fail2ban-regex /var/log/auth.log sshd
systemd journal后端可按当前版本支持的方式测试journal与过滤器:
sudo fail2ban-regex systemd-journal sshd
输出中的matched应包含刚才产生的失败记录。零命中时,核对日志格式、服务名、过滤器模式和时区。自定义 failregex 前先保存真实日志样本,并确保表达式中的主机部分由Fail2ban提供的安全占位符识别。
不要使用过宽的正则匹配任意IP和任意错误行,否则可能封禁正常用户或代理出口。
核对findtime、maxretry与忽略规则
Fail2ban只有在 findtime 窗口内达到 maxretry 才触发封禁。查看目标jail的生效配置:
sudo fail2ban-client get sshd findtime
sudo fail2ban-client get sshd maxretry
sudo fail2ban-client get sshd bantime
sudo fail2ban-client get sshd ignoreip
测试IP可能被 ignoreip 排除,日志时间与系统时间不一致也会导致记录落在窗口之外。先检查:
timedatectl status
测试前确认自己的管理IP和恢复通道,避免为了验证而把唯一入口封掉。
确认封禁动作写入正确防火墙
jail计数增加但IP仍可访问时,重点检查action与当前防火墙栈。系统可能使用nftables兼容层、原生nftables、iptables或firewalld,容器端口还可能经过独立转发链。
sudo nft list ruleset
sudo iptables -S
sudo journalctl -u fail2ban --since "10 minutes ago" --no-pager
日志若出现actioncheck或命令执行错误,应按发行版实际防火墙选择对应action,而不是同时堆叠多套规则。需要隔离验证安全策略时,可在 萤光云 或 LightNode 建立临时测试机,保留控制台入口再测试封禁。
重载配置并完成闭环测试
修改后先检查配置,再重载:
sudo fail2ban-client -t
sudo fail2ban-client reload
sudo fail2ban-client status sshd
从非管理出口进行受控的失败登录测试,观察日志命中、失败计数、封禁列表和防火墙规则是否依次变化。测试结束后按当前版本支持的方式解封测试IP。
验收必须同时满足过滤器命中、jail计数增加、封禁动作成功以及目标端口确实拒绝该来源。
FAQ
服务启动正常为什么jail没有出现?
jail可能未设置 enabled = true,也可能因日志路径不存在、过滤器错误或配置语法问题而没有启动。查看Fail2ban日志最直接。
backend写auto可以吗?
auto会尝试合适的文件后端,并在满足条件时切换systemd。生产环境应核对最终选中的后端,避免日志迁移后静默失效。
封禁列表里有IP但SSH仍能连接?
可能是action写入了未实际经过的防火墙链、端口转发绕过该链,或测试流量来自另一个出口IP。
温馨提示
Fail2ban是基于日志的补充防护,不能替代密钥登录、关闭不必要端口、云防火墙和系统更新。 每次修改过滤器与action后都应做闭环测试,并持续监控jail是否仍有日志命中。


