网站突然访问变慢或无法打开,查看服务器时发现CPU和带宽占满,但访问量并没有异常增长,这种情况很可能是遭遇了CC攻击。CC攻击与传统的DDoS不同,它不依赖海量流量,而是通过大量看似正常的请求持续消耗服务器资源,使正常用户无法访问。针对此类攻击,单纯封IP往往效果有限,更可靠的做法是在Nginx层做精细化限流,同时配合WAF规则对恶意请求特征进行拦截,形成组合防御。

一、认识CC攻击:特征与危害
CC攻击全称Challenge Collapsar,早期主要用来挑战抗DDoS设备,现在通常指针对Web应用层的资源耗尽型攻击。攻击者会控制大量代理或肉鸡,向目标网站发起大量看似正常的HTTP请求。这些请求可能集中在某个搜索接口、动态页面、数据库查询页面或登录接口,因为这些路径消耗的服务器资源远高于静态资源。攻击者甚至会模拟正常用户行为,随机切换User-Agent、使用代理IP,让简单的IP封禁难以奏效。
CC攻击的危害非常直接。当大量请求同时到达时,Web服务器进程或连接数被占满,数据库连接池迅速耗尽,CPU和内存持续高位运行,最终表现为正常用户无法打开页面或响应极慢。对于中小型云服务器来说,由于硬件资源有限,一次并不算大的CC攻击就可能导致服务瘫痪。要有效防护,需要从请求频率、并发连接和请求特征多个维度同时下手,这正是Nginx限流与WAF规则组合的意义所在。
二、Nginx限流的基础配置
Nginx自带的limit_req模块可以限制请求的处理速率,limit_conn模块可以限制并发连接数。实际部署时,通常使用客户端IP作为限制维度,也可以使用服务器名或指定的变量。配置写在http块中,通过limit_req_zone和limit_conn_zone定义共享内存区域,然后在server或location中引用。
http {
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
limit_req_zone $server_name zone=perserver:10m rate=100r/s;
limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
}
上面的配置创建了两个限流区域:perip按客户端IP限制每秒10个请求,perserver按服务器名限制每秒100个请求。limit_conn_zone则用于限制单个IP的并发连接数。在需要保护的location中,可以使用limit_req和limit_conn指令启用限制。例如:
location /search/ {
limit_req zone=perip burst=20 nodelay;
limit_conn perip_conn 10;
}
burst参数表示允许的突发请求数量。如果没有设置nodelay,超过速率但未超过burst的请求会排队等待处理;设置了nodelay后,这些突发请求会立即处理,但会消耗突发额度。对于CC攻击,通常建议设置合理的burst并开启nodelay,既能避免正常用户突发流量被全部拒绝,又能防止攻击请求长时间占用连接。
并发连接限制同样重要。有些CC攻击会使用慢速连接,请求速率不高,但会长时间保持连接,导致服务器连接数被占满。limit_conn可以限制单个IP同时打开的连接数量,配合limit_req可以更全面地压制攻击。需要注意的是,如果Nginx前面还有CDN或反向代理,直接使用$binary_remote_addr只能看到代理IP,此时需要结合X-Forwarded-For或real_ip模块获取真实客户端IP。
三、WAF规则如何识别CC攻击
Nginx限流擅长控制请求速率和连接数,但对于低频但高消耗的请求,或者针对特定业务逻辑的攻击,单纯限流可能会误伤正常用户。WAF的作用是更精细地分析请求内容,识别恶意特征。WAF规则可以基于请求头、UA、Cookie、URL参数、请求体等多个维度进行判断,命中规则后可以直接拦截、记录日志或跳转验证。
常见的WAF规则包括:限制同一IP对特定URL的访问频率,例如对某个搜索接口每秒只能请求1次;拦截空UA或明显伪造的UA;对无Referer的POST请求进行验证;对包含SQL注入或XSS特征的参数直接返回403。对于开源环境,可以使用ModSecurity、NAXSI等WAF模块与Nginx集成,也可以使用OpenResty配合Lua脚本编写自定义规则。云服务商提供的WAF通常还支持JS挑战、验证码和智能信誉库,能够识别代理IP和僵尸网络。
WAF和Nginx限流的核心区别在于:Nginx限流基于速率和连接数,规则简单、性能开销低,适合作为第一道防线;WAF基于请求内容和行为特征,判断更准确,但资源消耗相对更高,适合对Nginx限流放行后的请求做进一步过滤。两者结合能够形成纵深防御,减少单纯依赖某一层带来的漏报和误报。
四、组合防御策略与配置示例
实际部署时,建议将Nginx限流作为第一层,WAF规则作为第二层。第一层先把明显超高频的请求直接拒绝,降低后端和WAF的压力;第二层对通过第一层的请求进行特征分析,识别伪装成正常流量的攻击请求。对于命中WAF规则的IP,可以进一步触发动态封禁,例如将IP加入临时黑名单,一段时间内所有请求都直接返回444状态码。
以一次常见的CC攻击为例:攻击者大量请求一个搜索接口,导致数据库压力过大。首先配置Nginx对搜索路径单独设置每秒1个请求的限流,并限制单IP并发连接数为5。然后在WAF中增加规则:当同一IP在30秒内请求该路径超过5次时,自动将该IP加入封禁列表,封禁时长为10分钟。这样即使攻击者更换UA和代理IP,只要触发频率规则,WAF就会主动阻断。
| 防护层 | 主要作用 | 典型配置/规则 | 局限 |
|---|---|---|---|
| Nginx limit_req | 限制请求处理速率 | rate=10r/s,burst=20 nodelay | 无法识别低频高消耗请求 |
| Nginx limit_conn | 限制并发连接数 | perip_conn 10 | 对多IP轮换攻击效果有限 |
| WAF自定义规则 | 基于请求特征和行为识别 | 同IP对某URL频率限制、UA黑名单 | 配置复杂,需持续调优 |
| 动态封禁策略 | 对命中规则的IP临时封禁 | 30秒内超过阈值则封禁10分钟 | 可能误伤共享出口IP |
组合策略的另一个关键是分层阈值设置。Nginx限流可以相对宽松,比如单IP每秒10个请求,避免误杀正常用户;WAF规则可以更严格,因为它是基于行为特征的,比如同一IP访问同一动态URL每秒超过2次就触发验证。这样攻击流量在第一层被拦截一部分,剩余流量在第二层被精确识别,正常用户基本无感。
五、实施步骤与监控优化
部署组合防御前,先要分析访问日志,确认攻击目标URL、请求来源和请求特征。可以使用Nginx的access_log统计请求最多的URI和IP,找到消耗资源最高的动态接口。然后根据业务实际情况设置Nginx限流阈值,建议从宽松开始,逐步收紧。配置完成后,观察正常用户的访问是否受到影响,尤其是登录、支付、搜索等关键流程是否出现误拦截。
WAF规则上线后需要持续监控命中情况。可以通过WAF日志查看规则触发频率和拦截的请求内容,判断是否存在误报。对于已知的搜索引擎爬虫、合作方服务器或办公出口IP,可以配置白名单,避免被规则误伤。同时,结合服务器监控查看CPU、内存、连接数和数据库连接池的变化,确认防护是否真正降低了资源消耗。
如果攻击量突然增大,还可以临时启用应急策略,例如在Nginx中直接对攻击IP段返回444,或在DNS层面切换至高防IP。CDN也能承担一部分CC攻击流量,但前提是源站限制了来自非CDN节点的直接访问。组合防御不是一劳永逸的,需要根据攻击手法变化不断调整限流参数和WAF规则,才能持续保持防护效果。