恶意刷新流量是最常见的CC攻击形式之一。攻击者通过僵尸网络或单台高带宽机器,不断向目标页面发送大量GET或POST请求,导致服务器CPU、内存或数据库连接数瞬间飙升,最终服务瘫痪。与DDoS不同,CC攻击的流量特征往往“看起来像正常请求”,因此传统的高防IP和硬防设备在低速率攻击下经常失效。要有效阻断这类恶意刷新,关键在于WAF(Web应用防火墙)的精细化规则配置,而非单纯增加带宽。
一、认清恶意刷新与正常刷新的分界线
在配置规则之前,需要区分“恶意刷新”与“正常用户的高频操作”。例如,一个电商秒杀活动,同时可能有数千用户每分钟点击5-6次,这属于正常峰值;而攻击者可能利用一台机器每秒发送100次请求,且来源IP固定,User-Agent异常或缺失——这就是典型恶意刷新。分界线通常基于两个维度:请求频率 和 请求一致性。
正常用户行为呈现随机性(不同页面、不同间隔、不同浏览器特征),而恶意刷新通常具备高度重复性:相同的URL、相同的Referer、相同的参数、甚至相同的时间间隔。WAF应当识别出这种“机械重复”模式,而非仅仅限制IP速率。
二、WAF规则设计的核心原则
阻断恶意刷新不意味着封死所有高频率请求。以下三条原则可避免误伤:
- 分层触发:第一层用频率阈值做预警,第二层用挑战验证(如JS校验、CAPTCHA)做二次确认,第三层才直接封禁。
- 基于会话而非单纯IP:NAT下多个正常用户共享一个公网IP,仅限制IP会误伤。应结合Cookie、Token或浏览器指纹建立会话。
- 动态惩罚递增:首次触发警告,第二次挑战,第三次临时封禁,第四次永久加入黑名单,且每次封禁时长指数增长。
三、阻断恶意刷新的五类WAF规则
3.1 精确的速率限制规则
最常见的WAF功能。但简单的“每IP每分钟100次”太粗暴。推荐使用滑动窗口算法,并设置多个维度:
- URI级别:对特定资源(如 /login、/api/query)单独设置更严格的阈值,因为攻击者常盯住动态接口。
- 请求方法:POST请求的阈值通常低于GET,因为POST涉及写操作。
- 参数内容:可通过WAF规则识别可疑参数(如固定时间戳、递增数字),对这类请求额外计数。
举例:在ModSecurity或云WAF中,可以编写规则:如果同一IP在5秒内对 /checkout 的POST请求超过6次,则触发挑战。挑战成功后,刷新计数器;挑战失败则封禁30秒。
3.2 浏览器指纹与JS挑战
恶意刷新工具通常不会执行JavaScript。WAF可以在响应中注入一段JS,要求客户端计算一个简单hash并携带回Cookie。正常浏览器自动执行,攻击脚本往往忽略或无法执行,因此请求会被阻断。这是低误杀、高拦截率的方法。
具体实现:WAF对可疑请求返回一个302重定向到验证页,验证页包含JS生成 token,token有效期为当前会话。已验证通过的IP+User-Agent组合放行一段时间(如30分钟)。
3.3 基于Cookie/Session的访问频率限制
很多WAF支持基于Cookie的速率限制。要求客户端必须携带一个由服务器下发且不可预测的会话ID,否则直接拒绝。恶意刷新工具若未携带该Cookie,则被挡在第一层。若攻击者伪造固定Cookie,WAF可以检测到该Cookie在极短时间内被大量不同IP使用(即共享Cookie异常),从而封禁相应会话。
3.4 动态黑名单与自动响应
对于触发多次挑战失败的IP或IP段,WAF应自动将其加入临时黑名单。黑名单生效期间,所有来自该IP的请求直接返回403。建议配合CDN的IP信誉库,对来自已知代理或云服务商的IP启用更严格限制(因为CC攻击常用AWS、Azure或低端VPS发起)。
还需注意:只封禁特定路径而不是全站。例如攻击者只刷 /user/profile,WAF应只对该路径实施黑名单,避免影响该IP访问其他正常页面。
3.5 请求频率的“行为基线”学习
高级WAF具备机器学习能力,可以学习每个用户(IP+UA+Cookie)的正常请求间隔分布。一旦某个会话的请求频率偏离基线超过3个标准差,自动标记为攻击行为。这种方法能有效防范“慢速CC”(即低于普通阈值但持续长时间的攻击)。手动也可以设置类似规则:如果某个会话在15分钟内请求次数超过历史平均的5倍,则触发验证。
四、真实配置示例:以Nginx+ModSecurity为例
假设我们使用Nginx作为反向代理,并开启ModSecurity(开源WAF)。以下是一个防止恶意刷新的核心配置段(注释版):
# 在modsecurity.conf中
SecRuleEngine On
# 阶段: 请求体读取后
SecAction "id:1000,phase:2,pass,nolog,setvar:tx.rate_limit_threshold=60"
# 规则: 针对动态路径 /api/order
SecRule REQUEST_URI "^/api/order"
"id:1001,phase:2,block,
initcol:ip=%{REMOTE_ADDR},
setvar:'ip.rate_minute=+1',
expirevar:'ip.rate_minute=60',
chain"
SecRule IP:RATE_MINUTE "@gt 20"
"t:none,msg:'Rate limit exceeded for /api/order'"
上述规则对IP在60秒内请求 /api/order 超过20次则阻断。但考虑到NAT,更推荐结合Cookie:
SecRule REQUEST_COOKIES "!bsessionid=([a-z0-9]+)"
"id:1002,phase:1,deny,status:403,msg:'Missing session cookie'"
五、验证与回滚机制
任何WAF规则都不应直接上线生产。建议遵循以下流程:
- 模拟攻击测试:使用wrk、ab或自定义脚本模拟恶意刷新,观察WAF是否命中规则并返回预期状态码。
- 灰度发布:先对10%的流量开启规则,监控误拦截比例(正常用户触发验证或返回403的比率)。若误拦率高于0.1%,立即调整阈值。
- 日志审计:每天检查WAF日志,统计被阻断的请求中是否包含已知爬虫(如Googlebot)。若误拦合法爬虫,应在规则中设置白名单User-Agent。
- 快速回滚:在WAF管理平台预设一键禁用规则的API或CLI命令。一旦发现大面积误伤,立即关闭规则,并通知用户清空浏览器缓存或重新登录。
特别注意:开启JS挑战后,API接口(移动端或前后端分离的应用)无法执行JS。此时需要为API路径单独配置Token验证或通过请求头中的Authorization结合速率限制。
六、常见陷阱与补充策略
陷阱1:过度依赖IP黑名单。攻击者可以使用大量免费代理轮换IP,单纯封IP效果有限。应结合指纹和挑战。
陷阱2:固定阈值导致误杀秒杀用户。对于抢购、抢票场景,需提前与业务沟通,临时提高阈值或关闭挑战,使用签名机制(如时间戳+密钥)替代。
陷阱3:忽略应用层协议特征。恶意刷新可能使用HTTP/2多路复用,相同的TCP连接内发送大量请求。WAF的速率限制应基于Stream而不是仅基于TCP连接。
补充一条策略:在CDN层启用“请求频率平滑”。如果CDN支持,可以配置“每客户端每秒最多5个请求”,CDN将超出部分排队或丢弃,这样源站几乎不受影响。但需确保CDN能识别真实客户端IP(通过X-Forwarded-For)。
七、总结:从配置到运营
有效阻断恶意刷新流量,不是一两条规则就能完成。需要一套多层防御体系:CDN过滤已知IP信誉、WAF规则拦截高频异常、应用层验证机制防止伪造、以及监控告警持续优化阈值。关键是把“阻断”与“放行”的决策权交给自动化规则,同时保留人工介入的接口。定期复盘攻击日志,调整规则粒度,才能让WAF真正成为CC攻击的“防波堤”。
延伸阅读
