fail2ban 默认通过 iptables 的 input 链实施封禁,因 ssh 等服务监听本机端口,攻击流量首先进入 input 链,匹配源 ip 后立即 drop;规则由 fail2ban 动态调用 iptables 命令增删,插入链顶并带注释标记,依赖 netfilter 执行且需避免 firewalld/nftables 冲突及规则顺序错位。

Fail2Ban 与 iptables 的联动,不是简单“调个命令”就完事的。它是一套日志驱动、规则触发、内核级执行的闭环机制——Fail2Ban 是决策者,iptables 是执行者,而 Linux 内核的 netfilter 框架才是真正的封禁底座。
封禁动作实际落在哪条链上?
Fail2Ban 默认通过 iptables 的 INPUT 链 实施封禁,而不是 FORWARD 或 OUTPUT。这是因为 SSH 等服务监听在本机端口,攻击流量进入服务器后首先进入 INPUT 链,此时匹配源 IP 并 DROP 就能立即阻断连接建立。你可以在终端运行 sudo iptables -L INPUT -n --line-numbers 查看 Fail2Ban 插入的规则,通常形如:
REJECT all -- 192.0.2.45 0.0.0.0/0 reject-with icmp-host-prohibited- 这条规则由 Fail2Ban 自动插入到 INPUT 链顶部附近(确保优先匹配)
- 它不依赖状态(stateless),只要包的源 IP 匹配即拦截,开销极低
iptables 规则怎么被 Fail2Ban 动态管理?
Fail2Ban 不直接写 iptables 规则文件,而是通过 iptables 命令行调用 实时增删规则。它的动作(action)定义在 /etc/fail2ban/action.d/iptables.conf 中,核心逻辑是:
- 封禁时执行:
iptables -I INPUT -s <ip> -j REJECT --reject-with icmp-host-prohibited</ip> - 解封时执行:
iptables -D INPUT -s <ip> -j REJECT --reject-with icmp-host-prohibited</ip> - 所有操作都带
-w参数(等待锁),避免多线程冲突 - 规则带有注释标记(如
[fail2ban-sshd]),便于识别和清理
为什么有时封了却没效果?关键在 netfilter 层级
封禁失效往往不是 Fail2Ban 没运行,而是规则被更高优先级策略覆盖或绕过:
- firewalld 或 ufw 正在运行:它们会接管 iptables 规则表,Fail2Ban 插入的规则可能被重载清空
- 系统启用 nftables 后端但未配置兼容:现代发行版默认用 nftables,若 Fail2Ban 仍硬写 iptables 命令,实际不会生效
- 规则顺序错位:如果自定义的 ACCEPT 规则放在 Fail2Ban REJECT 规则之前,攻击 IP 就会被提前放过
- IP 匹配不精确:比如日志里记录的是 NAT 后的真实客户端 IP,但服务器只看到代理或负载均衡器的 IP
封禁真正生效的位置:netfilter + conntrack 协同
iptables 规则最终由内核 netfilter 框架执行,而连接跟踪(conntrack)模块会影响封禁即时性:
- 对已建立的 TCP 连接(如正在传输中的 SSH 会话),REJECT 规则不会中断它——只拦新连接
- 若攻击者复用长连接暴力尝试,需配合
iptables -I INPUT -m state --state INVALID -j DROP清理异常状态 - Fail2Ban 的 bantime 到期后,不仅删规则,还会触发 conntrack -D 删除对应连接跟踪条目,确保旧会话无法续命











