fail2ban 默认不封IP的主因是jail未启用且logpath路径错误;需显式设enabled = true、匹配系统日志路径(如Ubuntu用/var/log/auth.log)、正确配置banaction(firewalld或iptables)并重启服务。

fail2ban 能防 SSH 暴力破解,但默认不生效 —— 它不会自动启动任何 jail,也不读取你没配对的日志路径或动作后端。
fail2ban 启动后为什么完全不封 IP?
最常见原因是 [sshd] 或 [ssh-iptables] 这类 jail 没启用。fail2ban 默认所有 jail 都是 enabled = false,哪怕你装好了、改了配置、重启了服务,只要没显式设为 true,它就纯旁观。
另一个高频问题是日志路径错配:logpath 必须指向真实失败登录记录的位置:
- Debian/Ubuntu 系:必须是
/var/log/auth.log - RHEL/CentOS 7+ 系:必须是
/var/log/secure - 写成
/var/log/messages或漏掉.log后缀,fail2ban 就压根看不到Failed password行
验证方式很简单:sudo fail2ban-client status sshd 如果报 Server replied: Not found,八成是 jail 名字没对上或根本没启用;如果显示 0 banned 且 Journal match 是空的,大概率是 logpath 指错了。
firewalld 和 iptables 动作不能混用
系统用的是 firewalld(CentOS 7+/RHEL 8+ 默认),但你在 jail.local 里写了 action = iptables[...],那封 IP 就只是纸上谈兵 —— fail2ban 会调用 iptables 命令,而 firewalld 正在接管规则表,结果就是命令执行成功、实际无任何封禁效果。
正确做法是匹配系统实际防火墙后端:
- 用
firewalld:设banaction = firewallcmd-ipset,并确保firewalld已运行(systemctl is-active firewalld返回active) - 用
iptables(已停用 firewalld):先systemctl stop firewalld && systemctl disable firewalld,再设banaction = iptables - 不确定时,查
sudo firewall-cmd --state和sudo iptables -L | grep f2b两者是否共存
注意:action_mwl 是快捷宏,展开后仍依赖底层 banaction,别只改 action 却忽略 banaction。
maxretry / findtime / bantime 参数怎么设才合理?
这三者不是孤立的,得看你的使用习惯和攻击强度:
-
maxretry = 5+findtime = 600(10 分钟):适合日常管理,能扛住短时扫段,又不至于误伤输错密码的自己 -
maxretry = 2+findtime = 300(5 分钟):适合高敏环境,但要求你输密码非常稳,否则容易被自己 ban -
bantime = 86400(24 小时)是常见选择;设-1表示永久封,但得配合定期清理,否则ipset或iptables规则会越积越多
关键点:fail2ban 判断依据是日志里的 Failed password 或 Invalid user 行,不是连接请求本身。所以即使攻击者用慢速扫描(比如每分钟 1 次),只要在 findtime 内凑够 maxretry 次失败,照样触发封禁。
ignoreip 白名单写错会导致自己登不上
ignoreip 不支持通配符,只认 CIDR(如 192.168.1.0/24)、单 IP(如 203.0.113.42)或主机名(需 DNS 可解析)。写成 203.0.113.* 或漏掉掩码,fail2ban 会静默忽略整行,白名单失效。
更隐蔽的坑是动态 IP 场景:如果你家用宽带是动态公网 IP,今天是 203.0.113.42,明天变成 203.0.113.43,那新 IP 就不在白名单里 —— 建议加一段内网段(192.168.0.0/16)或公司出口 IP 段,比只写一个 IP 更可靠。
最后提醒一句:改完 jail.local 一定要 sudo systemctl restart fail2ban,而且务必新开一个终端,用普通用户连一次确认没把自己锁在外面 —— 这步跳过,可能就得物理接触服务器了。


















