iptables的recent模块通过内核内存中的“最近列表”实现高频扫描源的动态防护,支持时间窗口与命中次数条件判断,可构建三层指数惩罚机制:快速识别、逐级延长封禁、阻断响应提升扫描成本。

iptables 的 recent 模块可用于实时追踪连接行为,配合自定义规则链,实现对高频扫描源的动态限速、延迟响应甚至临时封禁。其核心在于利用内核内存中的“最近列表”(recent list)记录 IP 地址的访问时间戳与频次,并支持基于时间窗口和命中次数的条件判断。
理解 recent 模块的关键参数
recent 不是独立模块,而是 xt_recent 内核模块提供的匹配扩展,需配合 -m recent 使用。常用选项包括:
-
--name:指定列表名(如
scanlist),不同规则可共用或隔离列表 - --set:将当前源 IP 加入列表(并更新时间戳)
- --rcheck:检查 IP 是否在列表中,且未超时(默认 60 秒)
- --update:检查 IP 是否在列表中,且距上次命中未超时;命中则刷新时间戳
-
--seconds:限定时间窗口(如
--seconds 30) -
--hitcount:设定最小命中次数(如
--hitcount 5) - --rttl:(进阶)校验 TTL 一致性,防 IP 伪造(需配合 raw 表)
构建指数惩罚的三层响应机制
所谓“指数惩罚”,指同一 IP 在短时间内的多次违规触发逐级加重策略(如:首次快响应 → 二次延迟 → 三次丢包 → 四次 DROP)。不依赖外部脚本,纯 iptables 即可实现:
-
第一层:识别快速扫描行为
例如 30 秒内发起 ≥5 次新连接(如 SYN 到非白名单端口):-A INPUT -p tcp --syn -m multiport ! --dports 22,80,443 -m recent --name scanburst --set-A INPUT -p tcp --syn -m multiport ! --dports 22,80,443 -m recent --name scanburst --rcheck --seconds 30 --hitcount 5 -j DROP -
第二层:延长封禁时间(指数增长)
使用多个独立列表模拟“惩罚等级”:
— 列表level1:30 秒内 3 次 → 记入,后续 5 分钟拒绝
— 列表level2:5 分钟内再触发 level1 → 记入,后续 30 分钟拒绝
— 列表level3:30 分钟内再触发 → 记入,后续 4 小时拒绝
每级通过--seconds和--hitcount组合控制升级条件 -
第三层:阻断响应而非仅丢包(提升扫描成本)
对已标记 IP,用REJECT --reject-with tcp-reset主动发 RST,干扰扫描器状态机;或更隐蔽地使用TCPOPTSTRIP(需启用xt_tcpoptstrip)破坏 TCP 选项,使部分扫描工具误判服务状态
避免误伤与运维要点
recent 列表存储在内存中,重启失效;默认最大条目为 100(可通过 sysctl net.netfilter.nf_conntrack_max 或模块参数调整)。实际部署需注意:
- 优先在
raw表的PREROUTING链处理,避开 conntrack 状态影响,尤其对无状态扫描(如 UDP 端口探测)更有效 - 慎用
--rsource(默认),若服务器在 NAT 后或使用 DSR,应确认源 IP 可靠性;必要时结合ipset做持久化备份 - 为防止列表膨胀,定期清理低频条目:可用
watch -n 60 'echo /proc/net/nf_conntrack | wc -l'监控,或写简单脚本读取/proc/net/nf_recent/*并按时间戳裁剪 - 测试阶段务必添加
-j LOG --log-prefix "SCAN-TRAP: "到关键规则前,验证匹配逻辑,避免全站失联
一个可直接运行的轻量示例
以下规则实现“2 分钟内 4 次新连接 → 休眠 10 分钟”基础惩罚(适用于 SSH 暴力探测):
# 创建专用链 iptables -N SCAN_TRAP <h1>记录新连接(仅 SYN)</h1><p>iptables -A INPUT -p tcp --syn --dport 22 -j SCAN_TRAP</p><h1>若已在 recent 列表且 120 秒内达 4 次,则 DROP</h1><p>iptables -A SCAN_TRAP -m recent --name ssh_scan --rcheck --seconds 120 --hitcount 4 -j DROP</p><h1>否则加入列表(并刷新)</h1><p>iptables -A SCAN_TRAP -m recent --name ssh_scan --set</p><h1>允许正常连接继续</h1><p>iptables -A SCAN_TRAP -j ACCEPT</p>
该结构清晰分离检测与动作,便于后续叠加多级逻辑或替换为 REJECT / REDIRECT 等策略。

















