Nginx限流防CC攻击完整指南:limit_req与limit_conn精细化配置


一、CC 攻击的原理:为什么它比 DDoS 更阴险

CC(Challenge Collapsar)攻击并非用海量带宽压垮服务器,而是模拟真实用户、持续向你的动态接口发起大量"看似正常"的请求——刷登录、刷验证码、刷 API、刷后台。它不占用网络带宽,却会疯狂消耗 PHP-FPM 进程、数据库连接和内存,导致正常用户访问变慢甚至 502。由于每个请求都长得像人类,传统的防火墙和 CDN 流量清洗很难识别。Nginx 的请求频率限制(limit_req)和并发连接限制(limit_conn)正是防御这类攻击的第一道稳固防线。

二、limit_req:按请求速率限流

Nginx 用 limit_req_zone 定义"共享内存 + 限流规则",用 limit_req 在具体 location 触发。核心配置示意:

# 定义名为 req_limit 的限流域,key 取客户端 IP,10m 是共享内存大小
http {
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

    server {
        location /api/ {
            limit_req zone=req_limit burst=20 nodelay;
            limit_req_status 429;
            proxy_pass http://backend;
        }
    }
}
  • rate=10r/s:每 IP 每秒最多 10 个请求,超出即处理。
  • burst=20:允许瞬时突发 20 个请求的缓冲,避免误伤正常的短时抖动。
  • nodelay:突发缓冲内的请求不延迟排队立即放行;不加则超出速率的会排队限速(延迟),可形成"削峰"。需要严格平滑时用不带 nodelay 的限速,需要快速响应时用 nodelay。

key 也可以用 $server_name、$uri 或 $http_user_agent,但最常用还是真实 IP。若经过 CDN,需配合 set_real_ip_from + real_ip_header X-Forwarded-For 拿到真实客户端 IP,否则所有请求会被当成 CDN 出口 IP 这一个 key 限死。

三、limit_conn:限制并发连接数

有的攻击是"低频高并发"——连接建立得很多,拖垮进程。用 limit_conn 限制单 IP 并发连接:

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        location /download/ {
            limit_conn conn_limit 50;
            limit_conn_status 429;
            proxy_pass http://backend;
        }
    }
}

它和 limit_req 是互补的两道闸:limit_req 管"每秒来多少",limit_conn 管"同时挂多少连接"。对下载站、图片站这类大文件场景,并发连接限制尤为重要,能有效防刷流量。

四、按 URI、按 UA、按区域精细化限流

攻击往往集中在少数几个热点接口,可以只对敏感路径限流,不动正常流量:

http {
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
    limit_req_zone $http_user_agent zone=ua_limit:10m rate=1r/s;
    map $http_user_agent $is_bad_ua {
        default 0;
        "~*Mozilla" 1;   # 略,真实应根据特征判断
    }
    server {
        # 只对 /api 和 /admin 施加严格限制
        location ~ ^/(login|admin|api/) {
            limit_req zone=api_limit burst=5 nodelay;
        }
    }
}

还可以用 map 根据 UA、Cookie、区域(配合 GeoIP 模块)把流量打标记,对恶意特征单独加快限速,对正常访问放行,实现"精准打击"。恶意 IP 还可以 deny 直接拒绝:

location /admin/ {
    deny 1.2.3.4;      # 直接封禁已知恶意 IP
    allow 192.168.1.0/24;
    deny  all;         # 其余全部拒绝,仅内网可访问
    proxy_pass http://backend;
}

五、配合状态码、日志与告警

被限流会返回 429 Too Many Requests,前端可据此提示"请求过于频繁"。生产中建议:

limit_req_status 429;
limit_req_log_level warn;   # 记录限流事件
error_page   429 /429.html; # 给用户更友好的页面

在日志里检索 "status":429 或 grep nginx error log 中的 "limiting requests" 即可发现被限频才放行与拒绝的比例,帮助判断限流阈值是否过严误伤正常用户,从而动态调整 rate 和 burst。配合监控工具(如 Grafana 采集 error log),攻击开始时能第一时间收到告警。

六、限流之外的纵深防御组合

限流只是缓解手段,真正的 CC 防御要层层叠加:CDN + WAF 规则拦截高频源 IP;关闭不需要的隐蔽接口;给动态接口加验证码/滑块降低机器人成功率;数据库连接池和 PHP-FPM 调优保证即使被刷也不至于雪崩;最后再用 Nginx 的 limit_req / limit_conn 兜底。多租户要特别注意 limit_req_zone 共享内存大小,过小会报 "no free slots",需适当调大。

写在最后

Nginx 限流不是万能的,但它是离应用最近、成本最低、见效最快的一道闸。合理的设计是:白天正常阈值、对敏感接口单独收紧、CDN 层先挡一波、Nginx 层限速限连、日志层盯 429 异常、加上人工黑名单与告警。把这套组合跑起来,即使防不住所有攻击,也能让你的网站在激烈 CC 下保持可访问而不是直接躺平。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

systemd服务管理从入门到实战:unit文件编写、日志排查与资源限制

rsync服务器数据同步备份实战:增量传输、滚动快照与排错指南

评 论
更换验证码