抵御cc和慢速攻击需超时控制、连接限制与后端调度三层协同:收紧client_header/body/send_timeout等前端超时,upstream层配置proxy_read_timeout、禁用非幂等重试、least_conn调度,叠加limit_req/limit_conn限流及主动健康检查,并通过日志与测试验证效果。

抵御CC和慢速连接攻击,不能只靠upstream集群本身,而要结合超时控制、连接限制与后端调度三层协同。关键不是让Nginx“等得更久”,而是让它更快识别异常连接、更早切断无效请求、更准地分流健康流量。
收紧前端连接超时,卡死慢速头部与空闲间隔
CC类慢速攻击(如Slowloris)依赖极低速率维持大量半开连接,必须在Nginx入口层就掐断其生存空间:
- client_header_timeout 5s:99%真实客户端在毫秒级发完请求头,设5秒可拦截只连不发、分段发送User-Agent的头部拖延行为
-
client_body_timeout 5s:监控上传体数据到达间隔,防慢POST;若需支持大文件上传,放宽至300秒但必须配
client_max_body_size 10m硬限大小 -
send_timeout 5s:控制向客户端写响应的空闲间隔,防慢读攻击;流式接口(SSE)除外,可设为300秒并关缓冲
proxy_buffering off - keepalive_timeout 5s + reset_timedout_connection on:长连接超时后直接发RST包,比FIN更快释放socket资源,避免TIME_WAIT堆积
upstream层同步加固,防止攻击穿透到后端
前端超时只是第一道防线,若攻击绕过或触发重试,会把压力传导至upstream节点,引发雪崩:
-
proxy_read_timeout 15–20s:必须小于
fail_timeout(如设为30s),确保后端响应慢能及时计入失败计数,触发节点摘除 -
禁用非幂等重试:对POST/PUT等操作,设
proxy_next_upstream_tries 1;仅允许error timeout http_502 http_503 http_504触发重试,禁用http_500和全部4xx -
least_conn算法优先:相比轮询,它天然规避已堆积连接的后端,降低单点压垮风险;搭配
keepalive 32复用连接,提升调度效率 - max_fails=2 fail_timeout=10s:缓存或API类后端响应快,两次失败即标记不可用,10秒后自动试探恢复,兼顾敏感性与稳定性
前置限流+连接控制,堵住绕过路径
单靠超时和重试控制不够,攻击者可能通过大量合法IP或低频多连接绕过。必须叠加速率与并发限制:
-
按IP限速:
limit_req_zone $binary_remote_addr zone=cc:10m rate=30r/s;,再在location中limit_req burst=60 nodelay; -
全局连接数限制:
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;+limit_conn conn_per_ip 50;,防单IP建数百连接耗尽worker -
upstream连接池保护:在upstream块中加
max_conns 200;(需Nginx 1.11.5+),限制每个后端最大并发连接数,避免后端被撑爆 -
启用主动健康检查(HTTP模块):
health_check interval=3 fails=2 passes=2 match=status_ok;,配合match status_ok { status 200; body ~ "ok"; },比被动探测更早发现假存活
日志与可观测性,让防护可验证
配置生效后必须能确认是否起作用,否则等于没防:
- 在
log_format中加入$upstream_addr $upstream_status $upstream_response_time $request_time,观察是否出现大量10.x.x.x:8080 - 504 0.000或超长$upstream_response_time - 用
curl -I反复请求,查access_log中$upstream_addr是否确实落在连接数少的节点(验证least_conn) - 模拟慢速连接测试:
timeout 30s curl --limit-rate 1b -v http://your-domain/,确认5秒内返回408或直接断连











