Nginx 反向代理怎么配置防 CC 攻击的限速规则 limit_req?

文章导读
limit_req 是 Nginx 内置模块,适合在网关层对特定 URI 或 IP 做请求频率限制,是防御 CC 攻击的基础手段之一,但配置不当容易误伤正常用户。
📋 目录
  1. A 安全配置示例(含白名单)
  2. B 不同业务场景参数推荐
  3. C 怎么验证是否生效
  4. D 紧急故障回滚方案
  5. E 常见坑与风险
  6. F 参考来源
A A

limit_req 是 Nginx 内置模块,适合在网关层对特定 URI 或 IP 做请求频率限制,是防御 CC 攻击的基础手段之一,但配置不当容易误伤正常用户。

先说结论:limit_req 能有效限制高频请求,但必须区分业务场景设置速率,且务必配置管理白名单。

  • 先判断:确认攻击特征是针对特定接口还是全站,以及正常用户的请求频率。
  • 优先做:在 http 块定义限速区域,配合 geo 模块设置 IP 白名单。
  • 再验证:使用批量请求脚本测试,确认是否触发 503 且未误伤白名单。
  • 留后路:修改配置前备份,确保能快速回滚。

安全配置示例(含白名单)

以下配置片段可直接参考,需放入 nginx.conf 对应位置。注意 rate 参数需根据业务调整,此处示例为 10r/s,避免直接复制 1r/s 导致静态资源加载失败。

http {
    # 定义白名单变量,白名单 IP 的 key 为空,共享全局桶或不限制
    geo $limit_key {
        default $binary_remote_addr;
        192.168.1.0/24 ""; # 替换为你的管理网段
        10.0.0.5 "";       # 替换为你的管理 IP
    }

    # 使用变量作为 key,白名单 IP 因 key 为空不受单个 IP 限制
    limit_req_zone $limit_key zone=one:10m rate=10r/s;
}

server {
    location / {
        # burst 允许突发,nodelay 超出部分直接拒绝
        limit_req zone=one burst=20 nodelay;
        limit_req_status 503;
    }

    # 特定 API 接口可单独设置更严格的限制
    location /api/login {
        limit_req zone=one rate=1r/s burst=5 nodelay;
    }
}

不同业务场景参数推荐

  • 普通网页(HTML/CSS/JS):rate=10r/s ~ 50r/s,burst=20~50。页面加载并发请求多,过严会导致样式丢失。
  • 通用 API 接口:rate=5r/s ~ 10r/s,burst=5~10。防止脚本高频调用。
  • 敏感接口(登录/短信):rate=1r/s ~ 2r/s,burst=3。需严格限制,防止爆破。
  • 静态资源(图片/视频):建议不限速或通过 CDN 防护,Nginx 限速可能影响加载速度。

怎么验证是否生效

单次 curl 请求无法触发限速,需使用脚本模拟高频请求。以下命令发送 20 个请求,观察是否出现 503 状态码:

Nginx 反向代理怎么配置防 CC 攻击的限速规则 limit_req?
for i in {1..20}; do curl -I -o /dev/null -s -w "%{http_code}\n" http://your_domain.com; done

同时查看 Nginx 错误日志,通常位于 /var/log/nginx/error.log,搜索 limiting requests 关键字确认是否触发限速:

grep "limiting requests" /var/log/nginx/error.log

紧急故障回滚方案

配置生效后若发现正常用户无法访问,需立即执行以下操作:

  1. 恢复备份:cp nginx.conf.bak nginx.conf
  2. 或临时注释:在 limit_req 指令前添加 # 注释符号。
  3. 检查语法:nginx -t
  4. 重载配置:nginx -s reload

注意:生产环境修改配置前,务必执行 cp nginx.conf nginx.conf.bak 备份。

常见坑与风险

  • NAT 环境误伤:如果多个用户共用同一个出口 IP(如公司网络、移动网络),限速过严会导致正常用户无法访问。建议结合 Cookie 或 JS 挑战进行二次验证。
  • burst 设置过小:正常页面加载可能包含多个并发请求,burst 太小会导致页面资源加载失败。
  • 忘记定义 zone:limit_req 引用了未定义的 zone 会导致 Nginx 启动失败。
  • 把自己锁在门外:未配置白名单可能导致管理员 IP 被限制,无法登录服务器修复。务必在 geo 模块中添加管理 IP。

参考来源

  • Nginx 官方文档:limit_req_module - https://nginx.org/en/docs/http/ngx_http_limit_req_module.html