如何在 Nginx 配置中限制单个 IP 的请求频率防止滥用

文章导读
据统计 60% 的服务瘫痪源于未管控的突发流量而非真实用户压力,通过 Nginx 的 limit_req_zone 配置可实现每秒 200 请求/IP 的基础限流,配合 burst=50 允许瞬时 250 请求。
📋 目录
  1. 原因分析
  2. 解决方案
  3. 注意事项
  4. 参考来源
A A

如何在 Nginx 配置中限制单个 IP 的请求频率防止滥用

核心结论:据统计 60% 的服务瘫痪源于未管控的突发流量而非真实用户压力,通过 Nginx 的 limit_req_zone 配置可实现每秒 200 请求/IP 的基础限流,配合 burst=50 允许瞬时 250 请求。

原因分析

当单 IP 请求速率异常飙升时,服务器可能面临恶意爬虫高频抓取数据、暴力破解攻击尝试登录、DDoS 洪水攻击以及服务器资源被大量消耗等问题。Nginx 提供两个核心模块用于流量控制:ngx_http_limit_req_module 基于请求速率的限流 (Rate Limiting),采用漏桶算法 (Leaky Bucket);ngx_http_limit_conn_module 基于并发连接的限流 (Connection Limiting)。漏桶算法的核心思想是请求如"水"流入桶中,桶底以恒定速率"漏水"(服务处理能力),溢出请求直接被丢弃。

解决方案

1. 基础 IP 限流规则配置

在 Nginx 配置文件的 http 段中添加以下配置:

http {
    limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=200r/s;
    server {
        location /api/ {
            limit_req zone=ip_limit burst=50 nodelay;
            proxy_pass http://backend;
            limit_req_status 429;
        }
    }
}

关键参数解析:rate=200r/s 表示每秒允许 200 个请求;burst=50 允许单 IP 瞬时 250 请求 (200+50);内存计算显示 10MB 空间在 64 位系统可存储约 81,920 个 IP 状态 (128 字节/IP)。使用$binary_remote_addr 而非$remote_addr 可节省 50% 内存,因为$binary_remote_addr 变量长度固定为 4 字节,而$remote_addr 变量长度为 7 字节到 15 字节。

2. 并发连接数限制

针对瞬间高并发场景,使用 limit_conn_module 限制连接数:

如何在 Nginx 配置中限制单个 IP 的请求频率防止滥用
http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
        location / {
            limit_conn addr 10;
        }
    }
}

注意:Nginx 1.18 以后用 limit_conn_zone 替换了 limit_conn 指令,且只能放在 http{}代码段。1M 共享空间可以保存 3.2 万个 32 位的状态或 1.6 万个 64 位的状态。超出限制时服务器将返回 503(服务临时不可用) 错误。

3. 动态封禁恶意 IP(OpenResty 方案)

对于需要实时拦截高频攻击源的场景,可使用 Lua 脚本实现动态封禁:

http {
    lua_shared_dict block_ip 1m;
    server {
        location / {
            access_by_lua_block {
                local blacklist = ngx.shared.block_ip
                if blacklist:get(ngx.var.remote_addr) then
                    return ngx.exit(403)
                end
            }
        }
        location /admin/block {
            content_by_lua_block {
                ngx.shared.block_ip:set(ngx.var.arg_ip, true)
            }
        }
    }
}

此方案支持封禁时长动态调整,需配合鉴权机制使用。

注意事项

1. 状态码选择:默认超限返回 503,可通过 limit_req_status 429 改为更语义化的"Too Many Requests"状态码,部分配置支持 limit_req_status 444 直接关闭连接。

如何在 Nginx 配置中限制单个 IP 的请求频率防止滥用

2. 内存耗尽风险:如果共享内存空间被耗尽,服务器将会对后续所有的请求返回 503 (Service Temporarily Unavailable) 错误,建议根据预期 IP 数量调整 zone 大小。

3. 局域网场景:同一个局域网访问网站可能是同一个外网 IP,系统设计时需要考虑到这点,无论是放入白名单还是设置合理阈值都需预留缓冲空间。

4. burst 与 nodelay 配合:如果设置了 nodelay,当访问超过频次且缓冲区满的情况下会直接返回错误;如果不设置该选项,严格使用平均速率限制请求数,超额请求会等待排队。

5. 配置验证:修改配置后务必执行 nginx -t && systemctl reload nginx 验证配置并热重载,避免配置错误导致服务中断。

如何在 Nginx 配置中限制单个 IP 的请求频率防止滥用

参考来源

来源:腾讯云开发者社区 - Nginx 限制访问频率、下载速率和并发连接数教程 (2023 年 4 月 26 日)

来源:CSDN 技术博客 - Linux 技术:怎么对同一 IP 频繁访问进行限流配置 (2026 年 4 月 23 日)

来源:知乎技术专栏 - 学习笔记:配置 Nginx 实现站点限流与防止 DDOS 攻击 (2026 年 1 月 31 日)

来源:Nginx 官方文档 - ngx_http_limit_req_module 模块说明 (2022 年 5 月 12 日)