iptables recent模块通过内核哈希表实时记录源IP,60秒内同一IP新建5次SSH连接即封禁300秒;需确保xt_recent模块已加载,并严格按顺序插入DROP黑名单检查、阈值触发、ACCEPT放行三条规则。

用 iptables recent 模块实现高频 SSH 连接动态封禁,本质是让内核在内存里维护一张轻量级 IP 记录表,不查日志、不启进程,60 秒内同一 IP 新建 5 次 SSH 连接就自动拉黑 300 秒。关键不在规则多,而在顺序准、参数对、模块活。
确保 xt_recent 内核模块已加载
模块没起来,所有 recent 规则都不生效:
- 运行 lsmod | grep xt_recent,有输出说明已加载
- 若无输出,执行 modprobe xt_recent 手动加载
- 验证是否启用:ls /proc/net/xt_recent/ 应能看到目录;再执行 cat /proc/net/xt_recent/ssh_attack(规则建好后)应有 IP 条目
按严格顺序插入三条 INPUT 链规则
顺序错一条,就会漏判或误放。推荐用 -I INPUT 插入链首(不是 -A 追加):
-
第一行(优先拦截黑名单):
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --rcheck --seconds 300 --hitcount 1 -j DROP
→ 已在 300 秒封禁期内?直接丢包,不往下走 -
第二行(触发封禁):
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --set -m recent --name ssh_attack --rcheck --seconds 60 --hitcount 5 -j DROP
→ 先记下这次连接(--set),再检查过去 60 秒是否已达 5 次;满足即丢弃本次并进入黑名单 -
第三行(放行合法连接):
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --set -j ACCEPT
→ 未达阈值的连接,记录后放行;注意这条必须在前两条之后,否则会绕过检测
--rcheck 和 --update 别混用,这里选 --rcheck 更合适
--rcheck 从第一次命中开始倒计时,适合短时密集攻击(如暴力破解);--update 从最后一次命中算起,容易漏判快速试探行为:
- 比如某 IP 在 00:00、00:02、00:04、00:06、00:08 各连一次,用 --rcheck --seconds 60 --hitcount 5,到 00:05 就触发了
- 同场景用 --update,则要等到 00:08 + 60 秒 = 00:13 才“真正开始计时”,防护窗口明显滞后
- 一条规则里同时写 --set 和 --rcheck 是可行的,但不能和 --update 搭配使用
验证是否真起作用
别只看 iptables -L 没报错,要实测闭环:
- 快速执行 5 次错误 SSH 连接(例如 ssh -o ConnectTimeout=3 user@your-server,输错密码后 Ctrl+C 中断),控制在 60 秒内
- 立刻试第 6 次:应卡住或提示 Connection refused
- 查匹配数:iptables -L INPUT -n -v | grep DROP,对应规则 packet 计数应增加
- 等满 300 秒后再试,应恢复可连;同时 cat /proc/net/xt_recent/ssh_attack 中 ttl 值应随时间递减至 0 后消失

















