流量异常的真实场景:源站为何突然崩溃
某天下午,运维告警系统突然弹出源站CPU使用率100%的红色警告,同时服务器响应延迟超过30秒。登录CDN控制台后,发现某个静态资源路径的请求量在十分钟内从每分钟200次飙升至20万次,所有请求都来自几十个随机IP,User-Agent伪装成正常浏览器——这是典型的DDoS刷流量攻击。如果源站直接暴露在公网,或者CDN节点没有配置限速,这些请求会穿透缓存直达源站,瞬间耗尽带宽与计算资源。
很多新手运维会直接选择升级源站带宽或增加服务器数量,但这种方式治标不治本——攻击者可以花更低的成本继续放大流量。正确的思路是:在CDN层实施限速与请求速率限制(Rate Limiting),将异常流量拦截在边缘节点。
CDN限速与Rate Limiting:两条防线,一个目标
两种机制虽然经常被混用,但侧重点不同:
- CDN限速(带宽/流量限制):针对单个IP或单个回源域名的总带宽或总流量进行上限控制。超过阈值后,CDN会返回503或断开连接。适合应对大流量型DDoS,例如每秒几百Mbps的UDP/HTTP洪水。
- 请求速率限制(Rate Limiting):基于时间窗口(如每秒、每分钟)对请求次数进行计数,超过允许次数后直接拒绝请求或返回429 Too Many Requests。适合应对高频请求刷接口行为,比如遍历ID、爆破登录、频繁刷新页面。
实际攻击中,两者经常同时使用:先用CDN限速防止源站带宽被打满,再用Rate Limiting精准拦截单个IP的恶意高频请求。
为什么不能只依赖CDN限速
CDN限速通常按IP或账户总流量设置,例如“单IP每秒最大100KB”。但如果攻击者使用大量IP分别发送小流量请求(如每秒2KB),每个IP都没有触达限速阈值,但总体请求量依然能让源站疲于响应。此时Rate Limiting按照请求次数而非流量大小进行限制,可以更灵敏地发现异常——例如“单IP每分钟最多100次请求”。
CDN限速配置:从宽带限制到突发保护
不同CDN厂商的配置入口不同,但底层逻辑相似。这里以通用配置步骤为例:
第一步:识别攻击特征
登录CDN日志分析平台,筛选出请求量异常的路径、状态码分布以及客户端IP来源。重点排查以下模式:
- 单一URL请求量突增(如/sitemap.xml或/api/query)
- 大量请求携带相同Referer或User-Agent(但攻击者可能随机变化)
- 请求间隔均匀且持续,没有真实用户的行为曲线
第二步:设置带宽上限
在CDN“限速”或“带宽控制”选项中,配置每IP或每连接的最大下载速度。例如:
- 单连接限速:设为512KB/s,防止单个连接占满带宽
- 单IP总带宽限速:设为2Mb/s,避免同一IP开大量并发连接
- 缓存命中率优化:对静态资源强制缓存,减少回源请求(攻击者可能故意绕过缓存,所以限速是兜底)
注意:带宽上限不宜设置过低,否则会影响正常大文件下载或视频播放类的业务。观察历史峰值后,建议设置为正常峰值的1.5~2倍。
第三步:启用突发流量熔断
部分CDN支持“突发流量熔断”功能:当源站与CDN节点的回源带宽在短时间内超过预设值(如100Mb/s持续10秒),自动对所有该域名的请求返回503直到熔断解除。这种方法属于“防火墙快关”,能立刻保住源站,但也会误伤所有用户。因此只应在极端情况下手动触发,或结合Rate Limiting的白名单机制。
请求速率限制(Rate Limiting):精细化防御
Rate Limiting的威力在于“按请求计数”而不是“按流量计数”。配置时需要关注三个参数:
- 时间窗口:通常为1秒、10秒、1分钟、1小时。越短的时间窗口越能快速拦截高频攻击,但也要考虑正常用户的突发操作(如页面加载时的5个并发请求)。
- 请求阈值:在该时间窗口内允许的最大请求数。例如每分钟100次对普通浏览够了,但API接口可能需要更高(如每分钟300次)。
- 触发后的动作:常见选项有返回429、返回503、封禁IP一段时间(如10分钟)或仅记录日志。
配置Rate Limiting的典型场景
- API接口保护:对/api/*路径设置每秒20次限制,因为正常客户端调用频率较低,而攻击脚本常以毫秒间隔连续请求。
- 登录/注册接口:对POST /login路径设置每IP每分钟5次,有效防止暴力破解(同时搭配CAPTCHA)。
- 静态资源防刷:虽然静态资源可以通过缓存缓解,但有些攻击者会人为添加随机参数(如?t=12345)强制回源。此时可在CDN层面忽略查询参数或对资源路径本身进行Rate Limiting。
实战示例:在Nginx/CDN的配置对应
如果你使用自建CDN或反向代理(如Nginx),可以用limit_req模块实现:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=30r/m;
server {
location /api/ {
limit_req zone=mylimit burst=5 nodelay;
proxy_pass http://backend;
}
}
说明:rate=30r/m表示每分钟最多30次;burst=5允许短时突发5个请求;nodelay表示超出限制的请求立即拒绝。在CDN控制台中,你选择路径、时间窗口和阈值即可,原理与此类似。
配置陷阱:不当限速反而影响正常用户
很多运维在刷流量事件发生后匆忙设置限制,结果教训惨痛:
- 误将CDN边缘节点IP当做攻击IP:如果开启“单IP限速”但未排除CDN节点的出口IP(例如使用CDN后源站看到的IP都是CDN节点IP),会导致所有正常用户共享同一个节点IP的限速额度,造成大面积访问失败。因此必须在CDN层设置限速,而不是源站;或者在源站使用CDN传递的真实客户端IP(如X-Forwarded-For)进行限速。
- 突发流量熔断过于敏感:正常情况下,零点后的爬虫、凌晨的数据同步也可能产生短时高带宽。熔断阈值建议基于近一周的统计峰值设置,并留有冗余。
- Rate Limiting时间窗口过小:例如设置每秒1次请求,会导致正常网页浏览(包含CSS、JS等雪崩请求)被拦截。正确做法是为每个资源配置独立规则,或使用请求数较少的统计周期(如每分钟)。
验证与回滚:确保线上安全
任何限速配置上线前必须经过三项验证:
- 使用测试IP模拟攻击:从不同地域的机器发送高频请求,确认CDN返回429或503,并且源站日志中的请求量骤降。
- 正常用户访问测试:用真机浏览器打开网站,检查页面加载是否完整,是否有资源被拦截。特别留意首次访问时的CSS合并请求(有时一个页面会同时发送10+请求)。
- 监控告警与回滚脚本:如果配置后正常用户的错误率(5xx/429)超过5%,应自动回滚到上一版本。大部分CDN支持“版本管理”功能,在修改限速规则后保留历史配置,以便一键切换。
回滚方案:
- 立即关闭新增的限速规则(或改为只记录不拦截)
- 如果源站仍有压力,临时启用全站静态化或启用Web应用程序防火墙(WAF)的拦截模式
- 待业务正常后,再小流量灰度测试新的限速参数
总结:分层防御才是长治久安
单一的CDN限速或Rate Limiting都无法完美应对所有刷流量场景。正确的架构是:
- 第一层:CDN缓存,尽可能降低回源比例;
- 第二层:CDN限速,对抗带宽型攻击;
- 第三层:Rate Limiting,精准打击高频请求;
- 第四层:WAF与IP黑名单,针对已知恶意指纹的封锁;
- 第五层:源站自身的限流与熔断,作为最后保底。
配置时牢记“宁可漏放进十个请求,也别误杀一个真实用户”,因此所有限速建议从宽松到严格阶梯式调整,结合实际监控数据持续优化。唯有如此,才能让源站在刷流量的风暴中安然无恙。
延伸阅读
