Nginx 防 CC 攻击实战:limit_req 与 limit_conn 限流配置完整教程(宝塔面板 + 命令行双版本)

导语

CC 攻击(Challenge Collapsar)是站长度过最头疼的应用层攻击之一。它不像传统 DDoS 那样直接打满带宽,而是模拟真实用户,用大量 HTTP 请求集中“刷”某一个动态接口或页面,最终把 CPU、数据库和 PHP-FPM 进程池耗尽,导致网站响应缓慢甚至大面积 502。对于使用 Nginx 作为 Web 服务器的站点,Nginx 自带的 limit_reqlimit_conn 模块就是对抗 CC 攻击的第一道、也是最划算的防线——无需额外付费,纯配置即可生效。本文将从原理到落地,手把手教你用 Nginx 限流把 CC 攻击挡在门外,并给出宝塔面板和纯命令行两种操作方式。

一、CC 攻击为什么难防?先搞懂限流原理

很多新手一上来就装 WAF、上高防,却忽略了 Nginx 本身的限流能力。要写好规则,先要理解两个核心模块的区别:

  • limit_req(请求频率限制):基于“漏桶算法”控制单个客户端在一段时间内的请求数。比如限制每个 IP 每秒最多 10 个请求,超过的部分要么排队(burst)要么直接拒绝(nodelay)。它防的是“短时间高频请求”,也就是典型的 CC 刷接口。
  • limit_conn(并发连接限制):限制单个客户端同时建立的连接数。它防的是“长连接耗尽”——攻击者开大量 keep-alive 连接占满 worker_connections。

一句话总结:limit_req 管“快不快”,limit_conn 管“多不多”。两者配合,才能既防突发洪峰,又防连接耗尽。

注意:Nginx 的限流依赖真实客户端 IP。如果你的站点前面套了 CDN 或负载均衡,必须正确配置 real_ip 才能拿到真实 IP,否则限流会误伤整个 CDN 节点。后面第五部分会专门讲解。

二、limit_req 频率限制配置实战(命令行版)

打开你的 Nginx 主配置(通常在 /etc/nginx/nginx.conf 或宝塔路径 /www/server/nginx/conf/nginx.conf),在 http 区块中加入共享内存 zone 定义:

http {
    # 定义名为 cc_limit 的限流 zone,10MB 内存约可存 16 万个 IP 的状态
    # rate=10r/s 表示每个 IP 每秒最多 10 个请求
    limit_req_zone $binary_remote_addr zone=cc_limit:10m rate=10r/s;
}

然后在需要保护的站点配置(server 或 location 区块)中引用:

server {
    listen 80;
    server_name example.com;

    location / {
        # 启用限流,burst=20 允许突发 20 个请求排队
        # nodelay 表示排队请求立即处理而非匀速,否则正常访问会卡顿
        limit_req zone=cc_limit burst=20 nodelay;

        # 被限流时返回 503,并记录日志便于排查
        limit_req_status 503;

        proxy_pass http://backend;
    }

    # 对登录等敏感接口单独收紧
    location = /wp-login.php {
        limit_req zone=cc_limit burst=5 nodelay;
        limit_req_status 503;
    }
}

配置完成后,先测试语法再平滑重载,避免配置写错导致 Nginx 重启失败:

nginx -t
systemctl reload nginx

经验值参考:普通资讯站建议 rate=5~10r/s、burst=20;电商 / API 站可按业务峰值调整到 20~50r/s。不要一上来就设成 1r/s,否则容易误伤正常用户与搜索引擎爬虫。

三、limit_conn 并发连接限制实战

CC 攻击还常配合大量并发连接拖垮服务器。在 http 区块添加连接数 zone:

http {
    # 限制单 IP 并发连接,10MB 内存
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}

在 server 或 location 引用,限制每个 IP 最多 20 个并发连接;对下载等大流量路径可单独收紧:

server {
    limit_conn conn_limit 20;

    # 下载 / 大文件路径单独收紧到 5 个并发
    location /download/ {
        limit_conn conn_limit 5;
    }
}

四、宝塔面板可视化配置(新手友好)

如果你用的是宝塔面板,不用手敲配置文件也能搞定限流:

  1. 登录宝塔面板 → 软件商店 → 已安装 → Nginx → 设置配置修改
  2. http 区块粘贴上面的 limit_req_zonelimit_conn_zone 定义,保存。
  3. 进入 网站 → 对应站点 → 设置配置文件,在 server 或对应 location 中加入 limit_req / limit_conn 指令。
  4. 点击“保存”后,宝塔会自动检测语法并重载 Nginx。

宝塔 7.x 以上还在「网站 → 流量限制」提供了图形化开关,可直接填写“单 IP 并发、单 IP 请求数 / 秒”,底层就是帮你生成上面的指令,适合不想碰配置的新手。需要注意的是,宝塔的图形入口默认粒度较粗,对登录接口等敏感路径做精细化收紧,仍建议手动改配置文件。

五、关键一步:让限流命中真实 IP(套了 CDN 必看)

很多站长反馈“明明配了限流却没效果”,99% 是因为前端套了 CDN,Nginx 拿到的是 CDN 回源 IP,限流自然全部落在 CDN 节点上。解决办法是启用 real_ip 模块,把 X-Forwarded-For 里的真实 IP 还原出来:

# 在 http 或 server 区块启用
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

更稳妥的做法是只对 CDN 的 IP 段set_real_ip_from(例如百度云加速、速度网络 CDN 的节点段),避免攻击者伪造 XFF 头绕过限流。以速度网络为例,可在官方文档获取回源节点段后逐个声明:

set_real_ip_from 110.242.0.0/16;
set_real_ip_from 36.110.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

六、进阶:CDN + WAF 联动,把攻击挡在源站之外

Nginx 限流是“源站自救”,但当攻击流量特别大时,源站带宽仍会被打满,CPU 照样扛不住。更优解是在源站之前就把恶意流量清洗掉——这正是速度网络(CDN + WAF 一体化防护)的价值所在。

速度网络提供边缘节点的 CC 防护与智能 WAF 规则,攻击流量在离用户最近的边缘节点就被识别并拦截,只有正常请求才回源到你的 Nginx。配合本文的 Nginx 限流做“源站兜底”,形成“边缘清洗 + 源站限流”的双重防护,既能扛住大流量 CC,又能防止单 IP 突发绕过边缘规则。

实战建议:小站长先用本文的 Nginx 限流零成本兜底;业务量上来、频繁被大流量 CC 骚扰时,再叠加速度网络的 CDN / WAF,性价比最高。两者并不冲突,而是层层递进。

七、验证效果与日志排查

发布配置后,用 ab 或 wrk 模拟单 IP 高并发,验证限流是否生效:

# 模拟单 IP 每秒约 100 个请求,持续 30 秒
ab -n 3000 -c 50 http://example.com/

观察 Nginx 错误日志,被限流的请求会记录 limiting requests:

tail -f /var/log/nginx/error.log
# 出现 "limiting requests, excess" 即说明限流已生效

同时监控 503 状态码比例和后端负载(tophtop 看 CPU),确认正常用户未被误伤。若误伤明显,适当调大 rate 与 burst 即可。

总结

Nginx 的 limit_req 与 limit_conn 是对抗 CC 攻击成本最低、见效最快的手段,核心就是“频率 + 并发”双管齐下,并注意拿到真实客户端 IP。对于追求省心、需要抗大流量攻击的站点,建议在此基础上叠加速度网络的 CDN + WAF 联动防护,把防线从源站前移到边缘。安全没有银弹,但把本文的配置落地,你的网站已经能挡掉市面上 80% 的初级 CC 攻击了。

给TA打赏
共{{data.count}}人
人已打赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
在线客服
在线客服
热线电话
QQ客服
电子邮箱
suduwangluo