iptables recent模块通过内核哈希表实时记录源IP,不依赖日志或脚本,实现60秒5次SSH连接即封300秒的动态防护;需按序配置DROP黑名单检查、阈值触发、SET入表三条规则,并确保模块已加载。

用 iptables 的 recent 模块做动态封禁,核心是靠内核哈希表实时记录源 IP 的连接行为,不依赖日志解析或外部脚本,响应快、开销低。关键在于规则顺序和参数配合——先检查是否已在黑名单,再判断是否触发阈值,最后才放行合法连接。
理解 recent 模块的工作机制
recent 模块在内存中维护一个默认最多 100 条的 IP 哈希表,只记录源 IP(用 --rsource),不存端口或时间戳。它本身不封 IP,必须配合 DROP 或 REJECT 动作使用。常用操作有:
- --set:首次匹配时把源 IP 加入列表
- --rcheck:检查该 IP 是否在列表中,且满足 --seconds 和 --hitcount
- --update:若已在列表中,则刷新最后匹配时间(常与 --rcheck 配合用)
模块需提前加载:modprobe xt_recent;可用 lsmod | grep xt_recent 确认。
为 SSH 设置 60 秒 5 次即封 300 秒的规则
目标是:同一 IP 在 60 秒内发起 ≥5 次新 SSH 连接(--state NEW),后续所有 SSH 请求直接丢弃,持续 300 秒。规则必须按严格顺序插入 INPUT 链:
- 第一步:检查是否已在 300 秒黑名单中 → 是则立即 DROP
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --rcheck --seconds 300 --hitcount 1 -j DROP - 第二步:对新连接,先更新时间戳(若已存在),再判断是否达阈值 → 达标则 DROP 并加入列表
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --update --seconds 60 --hitcount 5 -j DROP - 第三步:未达阈值的新连接,先记入列表(为后续统计打基础)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --set
注意:第三步不能放在最前,否则每个新连接都无条件入表,导致误封;也不能省略,否则 --update 和 --rcheck 失效。
验证与日常维护要点
规则生效后,可通过以下方式确认:
- 查看规则及命中计数:iptables -L INPUT -n -v --line-numbers | grep ssh_attack
- 检查 recent 列表内容(需安装 ipset 或读取 proc):cat /proc/net/xt_recent/ssh_attack
- 手动测试:用另一台机器快速连 SSH 5 次,第 6 次应超时或被拒
封禁是自动过期的,无需手动清理;但若要临时清空列表,可执行:echo +1.2.3.4 > /proc/net/xt_recent/ssh_attack(加白)或直接删除文件(慎用)。
进阶建议:提升稳定性和适应性
生产环境建议补充几点:
- 限制接口:加上 -i eth0(替换为实际外网网卡),避免内网误伤
- 避免干扰已有连接:确保这条规则在 ESTABLISHED,RELATED 规则之后、其他 ACCEPT 规则之前
- 扩展服务:同样逻辑可用于 FTP(--dport 21)、HTTP 登录页(--dport 80/443 + 匹配特定 URI)
- 与 fail2ban 协同:recent 做秒级应急防护,fail2ban 做分钟级日志分析封禁,二者互补


















