我正在研究使用 nginx 的速率限制HttpLimitReq模块。但是,请求都来自同一个 IP(负载均衡器),并且标头中包含真实的 IP 地址。
有没有办法让 nginx 根据X-Forwarded-For
标头中的 ip 而不是源的 ip 进行速率限制?
答案1
是的,典型的速率限制配置定义字符串如下所示:
limit_req_zone $binary_remote_addr zone=zone:16m rate=1r/s;
其中$binary_remote_addr
是限制器的唯一键。您应该尝试将其更改为$http_x_forwarded_for
获取标头值的变量X-Forwarded-For
。尽管这会增加内存消耗,因为$binary_remote_addr
使用压缩二进制格式存储 IP 地址,而$http_x_forwarded_for
不是。
limit_req_zone $http_x_forwarded_for zone=zone:16m rate=1r/s;
答案2
该limit_req_zone
指令定义用作请求分组键的变量。
通常$binary_remote_addr
使用 而不是 ,$remote_addr
因为它更小,节省空间。
也许你想使用ngx_http_realip_module。
这会将远程地址变量重写为自定义标头中提供的地址,同时也会使日志记录和其他变量的使用更加容易。
答案3
仅作为使用标头设置 real_ip 的示例和演示。
我们精确地获取 IP 地址
然后客户端 IP 将被该值覆盖
然后我们可以继续使用
$binary_remote_addr
- 并非总是
x-forwarded-for
被使用。
- 并非总是
该方法也可以帮助记录日志(默认格式将起作用,因为
$remote_addr
现在它被设置为覆盖的值)要使用的 Nginx 模块:ngx_http_realip_module 使用 Cloudflare 设置的示例(多个服务器源或 IP 范围)
# Ipv4
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
# Ipv6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
- 您可以将其保存在文件中。例如:
cloudflare_ip.conf
并将其添加到conf.d
您可以看到
set_real_ip_from
- 只有来自这些 IP 的请求才会被覆盖
real_ip_header
包含通过 Cloudflare 连接的客户端 IP 的标头是
CF-Connecting-IP
Cloudflare指导
对于速率限制
limit_req_zone $binary_remote_addr zone=limit_ip_10rs:10m rate=10r/s;
- 我们继续使用
$binary_remote_addr