静态资源被恶意刷量,本质上是通过海量请求消耗服务器带宽和连接数,最终导致正常用户无法访问。攻击者通常会瞄准CSS、JS、图片、字体文件这类体积较大且不会频繁变动的资源,因为单次请求成本低,但对服务器造成的流量压力却很直接。处理这类问题不能只靠加机器硬抗,而是要从请求识别、访问控制、资源优化和架构隔离四个维度同时下手,才能把防护成本控制在可接受范围内。

用Cookie或Token验证把机器请求挡在门外

最直接有效的方法是在静态资源请求前植入一层验证逻辑。具体做法是,当用户首次访问页面时,服务器在返回HTML的同时下发一个加密的Cookie或Token,浏览器后续请求静态资源时必须携带这个凭证。Nginx或CDN边缘节点先校验凭证合法性,校验不通过直接返回403,根本不把请求透传到源站。这种方式对搜索引擎爬虫也友好,因为主流爬虫支持Cookie和JavaScript挑战。实现时要注意Token的过期时间不宜太长,通常5到10分钟就够了,同时配合滑动刷新机制,避免用户长时间浏览时凭证失效。另外Token生成算法要用HMAC-SHA256这类带密钥的哈希,不要用简单的Base64编码,防止攻击者伪造。

浏览器指纹和TLS指纹做前置过滤

除了Cookie验证,还可以在TLS握手阶段就做指纹识别。JA3和JA4指纹能标识客户端的TLS握手特征,恶意脚本通常使用特定编程语言的HTTP库,其TLS指纹与真实浏览器有明显差异。在Nginx上通过nginx-module-vts或自定义Lua脚本提取TLS指纹,与已知的恶意指纹库比对,命中则直接拒绝连接。浏览器指纹方面,可以在HTML中嵌入一段JavaScript,收集屏幕分辨率、Canvas指纹、WebGL渲染特征等,生成一个设备标识,后续静态资源请求在URL中携带这个标识的哈希值。攻击者如果只用简单脚本发包,很难模拟完整的浏览器环境,自然就被过滤掉了。这套机制对CC攻击尤其有效,因为CC攻击追求的是请求量,攻击者往往不会花资源去完整渲染页面和执行JS。

URL签名与时间戳防篡改

静态资源的URL可以加上签名参数,让每个链接都带上有效期和完整性校验。例如原始URL是/assets/app.js,生成对外暴露的链接时变成/assets/app.js?t=1700000000&s=abc123,其中t是过期时间戳,s是对资源路径加时间戳加密钥的HMAC签名。Nginx用Lua模块或者直接通过OpenResty来校验签名,签名无效或时间戳过期就拒绝请求。这个方案的好处是,即使攻击者拿到了某个资源链接,也只能在限定时间内使用,过期后链接自动失效。同时签名机制让攻击者无法批量构造有效的资源URL,大大提高了攻击门槛。需要注意的是,页面缓存时间要短于签名有效期,否则用户可能拿到过期的签名链接。

Nginx限流模块的精细化配置

Nginx自带的limit_req和limit_conn模块是基础防线,但很多人配置得过于粗糙,导致误伤正常用户。正确的做法是做两层限流:第一层按IP限制请求速率,对静态资源目录设置每秒允许10到20个请求,突发容量给到50左右;第二层按域名和资源类型做整体流量控制,用limit_rate_after和limit_rate限制单个连接的传输速率。更精细的做法是用Lua脚本实现令牌桶算法,按请求资源的体积大小消耗不同数量的令牌,这样下载大文件的请求消耗更多令牌,防止攻击者用大文件请求占满带宽。同时要配合白名单机制,把主流搜索引擎爬虫的IP段和User-Agent加入白名单,避免误伤。

CDN边缘节点做流量清洗

把静态资源托管到CDN上,利用CDN厂商的DDoS防护能力是性价比最高的方案。CDN节点遍布全球,单点被打爆的概率极低,而且主流CDN都自带CC攻击检测和流量清洗功能。配置时要把源站IP隐藏好,只允许CDN回源IP访问源站的80和443端口,其他IP一律拒绝。CDN上开启智能限速,设置单IP带宽上限和请求速率阈值。另外CDN的缓存策略要配置得足够激进,静态资源的Cache-Control头设置max-age至少一周以上,配合版本号或内容哈希做缓存更新,这样绝大部分请求在边缘节点就被命中,根本不会回源。即使攻击者刷量,也是在消耗CDN的带宽,对源站几乎没有影响。

对象存储加CDN双层架构

比单纯用CDN更进一步的做法是,把静态资源上传到对象存储,然后通过CDN回源到对象存储。对象存储本身就有极高的带宽承载能力,而且按量计费,不需要为闲置带宽买单。在这种架构下,即使CDN被刷,回源请求落到对象存储上,对象存储也能轻松应对。同时对象存储支持设置防盗链Referer白名单,只允许自己的域名和CDN域名引用资源。还可以开启User-Agent黑名单,把已知的攻击工具特征过滤掉。成本控制方面,对象存储通常提供按量计费和包年包月两种模式,根据业务量选择即可。

前端代码层面做请求合并与懒加载

减少静态资源的请求数量本身就是一种防护手段。用Webpack或Vite打包时,把多个小文件合并成一个bundle,减少HTTP请求次数。图片资源用CSS Sprites或SVG Sprite技术合并成一张图,通过background-position定位显示。非首屏资源全部做懒加载,用户滚动到可视区域再发起请求。这样正常用户的请求量本身就少,攻击者想刷量就得模拟滚动行为,进一步增加了攻击成本。同时前端可以加入请求重试机制,当请求失败时用指数退避算法重试,避免因为网络波动导致请求风暴。

日志监控与自动化封禁

防护措施部署完不代表高枕无忧,需要实时监控异常流量。在Nginx访问日志中统计每个IP的请求次数、请求资源总大小、User-Agent分布等指标。用Elasticsearch加Kibana或者Grafana Loki搭建日志分析平台,设置告警规则,当某个IP在1分钟内请求超过500次或者流量超过100MB时触发告警。自动化封禁可以用fail2ban分析Nginx日志,匹配到异常IP后自动调用iptables或云防火墙API封禁。更高级的做法是用机器学习模型分析请求序列的熵值和模式,识别出低频慢速攻击。这套监控和封禁链路要保证延迟在秒级,否则攻击者可能已经造成损害后才被封禁。

Web服务器层面的连接优化

Nginx和Apache本身有一些参数可以优化来抵御慢速攻击和连接耗尽。keepalive_timeout设置短一些,比如10到15秒,避免攻击者保持大量空闲连接。client_body_timeout和client_header_timeout设置5秒左右,防止慢速发送请求头占用连接。worker_connections根据服务器内存调整到合理值,配合worker_rlimit_nofile提高文件描述符上限。开启Nginx的sendfile和tcp_nopush,提高文件传输效率,让正常请求更快完成,释放连接资源。这些参数调整虽然不能直接防CC,但能提高服务器在遭受攻击时的抗压能力,为其他防护手段争取反应时间。

使用WAF规则识别恶意请求特征

Web应用防火墙可以配置针对性的规则来拦截CC攻击。例如检测请求头中是否缺少常见的浏览器特征头,像Accept、Accept-Language、Accept-Encoding等,攻击脚本往往会省略这些头部。还可以检测User-Agent是否为空或者包含已知的恶意工具名称。Referer检查也很重要,如果静态资源请求的Referer不是自己的域名,大概率是盗链或者直接发起的攻击请求。WAF上配置速率限制规则,按IP加URL的组合维度做限流,比单纯按IP限流更精准。现在很多云WAF还支持验证码挑战,当检测到异常流量时自动弹出滑块验证,进一步区分人机。

灰度发布与熔断机制

当攻击流量超过防护阈值时,需要有兜底策略。可以在Nginx上配置熔断逻辑,当某个资源目录的请求量超过预设上限时,自动返回304 Not Modified或者一个极小的占位文件,减少带宽消耗。同时触发告警通知运维人员介入处理。对于非核心的静态资源,比如装饰性图片、动画效果脚本,可以在攻击期间临时关闭,保证核心功能的资源正常加载。这套熔断机制要用Lua脚本实现动态切换,配合配置中心实时下发开关,不需要重启Nginx就能生效。

合理利用浏览器缓存减少请求量

在响应头中正确设置Cache-Control、ETag和Last-Modified,让浏览器尽可能从本地缓存加载资源。对于带版本号的静态资源,可以设置一年的max-age,因为文件内容变化时URL会跟着变。对于不带版本号的HTML页面,设置较短的缓存时间或者使用协商缓存。Service Worker可以做更激进的缓存策略,把静态资源预缓存到浏览器本地,后续请求直接从缓存中取,根本不发网络请求。这样正常用户的回访几乎不产生请求,攻击者刷量时面对的也是大量有缓存能力的客户端,实际发起的请求量会打折扣。

源站IP隐藏与任播技术

如果攻击者绕过了CDN直接攻击源站IP,前面的防护会大打折扣。源站IP必须严格保密,只通过CDN对外提供服务。DNS记录只解析到CDN的CNAME地址,源站防火墙只允许CDN的回源IP段访问。如果业务需要对外暴露API,用独立的子域名和服务器,与静态资源源站物理隔离。对于大型业务,可以考虑使用任播技术,将同一个IP地址广播到多个物理位置的服务器上,攻击流量会被分散到最近的节点,单点压力大幅降低。任播配合BGP路由协议,当某个节点被攻击时,流量会自动转移到其他节点,实现天然的流量分散。

成本控制与攻击溯源

防护的同时要关注成本,避免防护措施本身产生高额账单。CDN和对象存储设置带宽上限和费用告警,防止被刷后收到天价账单。对于持续的大流量攻击,考虑接入高防IP服务,按清洗流量计费。攻击溯源方面,从Nginx日志中提取攻击IP,查询IP归属地和AS号,向攻击来源的云服务商或IDC提交滥用报告。如果攻击规模较大,保留证据向公安机关网安部门报案。溯源信息还能帮助调整防护策略,比如发现攻击IP集中在某个地区或某个运营商,可以针对性地加强该区域的防护规则。