核心是“内核级实时检测+用户态灵活处置”双层协同:recent模块毫秒级频次识别与临时封禁,脚本负责日志分析、长期黑名单、自动解封与告警;recent应对突发短时洪峰,脚本处理持续性特征化攻击。

用 iptables -m recent 配合脚本防御 Web CC 攻击,核心是“内核级实时检测 + 用户态灵活处置”双层协同:recent 模块在内核完成毫秒级频次识别和临时封禁,脚本则负责日志分析、长期黑名单管理、自动解封与告警。两者不互斥,而是互补——recent 应对突发短时洪峰(如1秒10次请求),脚本处理持续性、特征化攻击(如高频UA、特定路径扫描)。
一、内核层:用 recent 实现秒级熔断
这是第一道防线,不依赖任何外部程序,所有判断在 netfilter 内核模块中完成:
- 规则必须插入 INPUT 链顶部(用 iptables -I),顺序不可错:先 DROP 已封IP,再判定+记录,最后 ACCEPT 合法连接
- 典型配置(HTTP 80端口,1秒内≥10次新连接即熔断):
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --name http_cc --rcheck --seconds 1 --hitcount 10 -j DROP
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --name http_cc --set
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT - 注意:务必搭配 --state NEW,避免把 ACK、重传等包误计入;--set 要放在判定规则之后,否则所有新连接都会被无差别记录,导致漏判
二、用户层:Shell脚本做深度识别与长效管控
recent 只能记源IP和时间戳,无法识别 User-Agent、URL、状态码等应用层特征。这时需脚本定期解析 access.log,提取异常行为:
- 常见识别维度:
• 单IP 1分钟内请求数 > 200(排除静态资源:.js/.css/.png)
• 高频 404 或 499(扫描型请求)
• UA 包含 sqlmap、nmap、masscan 等工具名
• 请求路径含 /phpmyadmin/、/wp-admin/、/shell.php 等敏感关键词 - 脚本示例逻辑(每分钟执行):
→ 用 awk + sort + uniq -c 统计 IP 访问频次
→ grep -vE '\.(jpg|gif|css|js|ico)' 过滤静态文件
→ 对超阈值 IP 执行:
iptables -I INPUT -s $ip -p tcp --dport 80 -j DROP
echo "$ip $(date +%s)" >> /etc/iptables/blacklist.log - 配套自动解封机制:脚本同时检查 blacklist.log 中时间戳,若距今超 3600 秒(1小时),则调用 iptables -D INPUT -s $ip ... 删除规则并清理日志行
三、增强稳定性与可观测性的关键操作
光有规则不够,得让整个机制可靠、可查、可调:
-
调大 recent 模块容量:默认只存 100 个 IP,高并发场景易溢出。编辑 /etc/modprobe.d/ipt_recent.conf:
options ipt_recent ip_list_tot=2000 ip_pkt_list_tot=100
然后 modprobe -r ipt_recent && modprobe ipt_recent 重载 -
验证是否生效:
→ ls /proc/net/xt_recent/ 应看到 http_cc 文件
→ cat /proc/net/xt_recent/http_cc 显示类似 src=203.201.32.12 ttl: 4(ttl 表示剩余秒数) -
加 LOG 规则辅助调试(临时启用,避免长期开启影响性能):
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --name http_cc --rcheck --seconds 1 --hitcount 10 -j LOG --log-prefix "CC_BLOCK: "
四、与 connlimit 协同构建多层防护
recent 控制“单位时间新建连接频次”,connlimit 控制“同一时刻并发连接数”,二者叠加可覆盖更多攻击面:
- 添加并发限制规则(防慢速CC、连接耗尽):
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 --connlimit-mask 32 -j DROP
表示单个 IP 最多维持 50 个活跃连接,超过即丢弃新 SYN - 注意:connlimit 规则应放在 recent 规则之后(即更靠后位置),因为它作用于 ESTABLISHED 状态连接,而 recent 主要盯 NEW 状态。两套规则共存不冲突,但顺序错位会导致 connlimit 失效
- 实际生产建议组合:
• recent 做“快封”(秒级响应)
• connlimit 做“稳压”(防连接池打满)
• 脚本做“精筛”(基于日志的语义识别)


















