nginx 如何做针对 ip 的限流

nginx 如何做针对 ip 的限流
最新回答
一个蛋上三朵花

2020-07-09 22:16:02

在 Nginx 中针对特定 IP 进行限流,可以通过配置 geo、map 和 limit_req_zone 模块实现。以下是具体步骤和配置示例:

1. 定义限流规则

在 http 块中配置以下内容,标记需要限流的 IP(黑名单模式):

geo $limit_ip { default 0; # 默认不受限 1.2.3.4 1; # 需要限流的 IP 5.6.7.8 1; # 可添加更多 IP}map $limit_ip $limit_key { 0 ""; # 不受限的 IP 对应空值 1 $binary_remote_addr; # 受限 IP 映射为二进制地址(节省内存)}limit_req_zone $limit_key zone=ip_limit:10m rate=2r/s;
  • geo:标记目标 IP(值为 1 的 IP 将被限流)。
  • map:将标记的 IP 转换为 $limit_key,未标记的 IP 对应空值(忽略限流)。
  • limit_req_zone:创建共享内存区域 ip_limit,限制每个 IP 的速率为 2 请求/秒
2. 应用限流规则

在需要限流的 location 块中引用配置:

location /api/ { limit_req zone=ip_limit burst=5 nodelay; proxy_pass
http://backend;
}
  • limit_req:启用限流,burst=5 允许短暂突发(超出速率时排队),nodelay 立即处理突发请求(不延迟)。
3. 验证与日志
  • 测试配置:执行 nginx -t 确保语法正确。
  • 重载配置:nginx -s reload 生效。
  • 查看日志:限流记录会出现在 error.log 中,例如:[error] 12345#0: *123 limiting requests, excess: 1.200 by zone "ip_limit", client: 1.2.3.4
4. 进阶配置白名单模式

若需反向操作(仅允许特定 IP 不受限),调整 geo 和 map:

geo $allow_ip { default 1; # 默认受限 192.168.1.0/24 0; # 白名单 IP 不受限}map $allow_ip $limit_key { 0 ""; # 白名单 IP 忽略限流 1 $binary_remote_addr; # 其他 IP 参与限流}动态调整
  • 修改 rate 参数(如 rate=5r/s)后重载配置即可生效,无需重启。
5. 注意事项
  • 内存占用:zone=ip_limit:10m 可存储约 16 万个 IP 的限流状态(根据实际需求调整)。
  • 精确性:$binary_remote_addr 比 $remote_addr 更节省内存。
  • 突发处理:burst 需合理设置,避免合法请求被误拦截。
完整配置示例http { geo $limit_ip { default 0; 1.2.3.4 1; } map $limit_ip $limit_key { 0 ""; 1 $binary_remote_addr; } limit_req_zone $limit_key zone=ip_limit:10m rate=2r/s; server { listen 80; location /api/ { limit_req zone=ip_limit burst=5; proxy_pass
http://backend;
} }}

通过以上配置,Nginx 可高效实现基于 IP 的精准限流,无需修改应用代码,适合防御恶意请求或高并发场景。