iptables recent模块通过内存IP列表实现轻量级动态黑名单,支持自动超时释放,适用于防暴力破解等场景,核心参数包括name、set、rcheck、seconds和hitcount。

iptables 的 recent 模块可用于记录匹配数据包的源 IP,并在后续规则中基于该记录做条件判断。它不持久化、不依赖外部程序,适合轻量级动态黑名单(如防暴力破解、限速拦截),且支持自动“超时释放”——只要 IP 在设定时间内不再触发规则,其记录就会被自动清除,无需手动清理或定时脚本。
理解 recent 模块的核心机制
recent 模块本质是维护一个内存中的 IP 列表(默认最多 100 个条目),每个条目附带最后匹配时间戳。关键参数包括:
-
name:指定列表名(如
ssh_attack),同一链中不同规则可共用或隔离使用 - set:将当前包源 IP 加入列表(并刷新时间戳)
- update:仅当该 IP 已存在时才刷新时间戳;常用于“续期”行为
- rcheck:检查 IP 是否在列表中,且未超时(推荐用于拦截判断)
-
seconds:配合
rcheck或update使用,定义有效窗口(如seconds=300表示 5 分钟) -
hitcount:限制命中次数(如
hitcount=3配合seconds=60实现“1 分钟内 3 次即拉黑”)
典型场景:SSH 暴力破解自动封禁与释放
以下规则链放在 INPUT 链中,按顺序加载(顺序敏感):
# 1. 先记录新连接的 SSH 尝试(非 established) -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attacks --set <h1>2. 若同一 IP 在 60 秒内出现第 4 次 NEW 连接,丢弃</h1><p>-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attacks --rcheck --seconds 60 --hitcount 4 -j DROP</p><h1>3. (可选)已封禁的 IP,若 3600 秒内无新尝试,自动从列表移除(由内核自动完成,无需额外操作)</h1><h1>→ 实际上无需显式清理:只要不持续触发 --set 或 --update,超时后条目自然失效
说明:第 2 条规则使用 --rcheck 而非 --update,避免误“续期”;--hitcount 4 表示第 4 次才触发 DROP,前 3 次仍放行(便于合法用户容错)。一旦触发 DROP,该 IP 后续所有 NEW 包都会被拦,直到其最后一次匹配时间超过 60 秒,条目自动消失,下次 NEW 连接重新计数。
进阶控制:区分封禁时长与检测窗口
若需“检测 60 秒内 3 次 → 封禁 10 分钟”,不能只靠单个 recent 列表。可组合两个列表实现:
- 用
ssh_scan列表记录高频尝试(短窗口,如 60 秒 / 3 次) - 命中后写入
ssh_banned列表,并设长超时(如seconds=600) - 后续所有 SSH NEW 包先查
ssh_banned,命中即 DROP
示例片段:
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_scan --set -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_scan --rcheck --seconds 60 --hitcount 3 -m recent --name ssh_banned --set --seconds 600 -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_banned --rcheck --seconds 600 -j DROP
这样,封禁时长(600 秒)独立于检测窗口(60 秒),逻辑更清晰,也避免因检测窗口过长导致误伤。
注意事项与调试技巧
recent 列表存储在内存,重启 iptables 或系统会清空;如需持久化黑名单,需额外配合脚本保存/恢复(/proc/net/nf_conntrack 不适用,recent 无对应 proc 接口)。调试时可用:
-
cat /proc/net/nf_recent/ssh_attacks查看当前列表内容(含时间戳) -
iptables -L INPUT -n -v观察规则匹配计数,确认是否生效 - 慎用
--update:它会在每次匹配时刷新时间戳,可能掩盖真实攻击节奏 - 列表容量默认 100,高并发场景可调大(需编译内核模块时指定,或通过 sysctl:
net.netfilter.nf_conntrack_max不影响 recent)
不复杂但容易忽略:recent 的“自动释放”完全依赖内核定时检查,只要 IP 停止触发 --set 或 --update,超时后自然失效,无需 cron 清理。

















