nginx使用limit_req模块
nginx使用limit_req模块时,如果使用CDN的话,能按真实的用户IP来限流吗?如果使用的是CDN的IP,从而把CDN直接限流了,影响正常访问:

http_limit_req 模块文档:
https://nginx.org/en/docs/http/ngx_http_limit_req_module.html

limit_req 模块配置实例:

http {

        limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

server {
...
    limit_conn perserver 300;
    limit_conn perip 25;
    limit_rate 512k;

...
}

}

在使用 Nginx 的 limit_req 模块时,如果你使用了 CDN,默认情况下限流是基于 CDN 的 IP 地址的,而不是真实用户的 IP 地址。这是因为 CDN 会将请求转发到你的 Nginx 服务器时,源 IP 地址通常是 CDN 的 IP。

要按真实用户 IP 限流,你需要配置 Nginx 以正确识别用户的真实 IP 地址。通常,这可以通过设置 real_ip 模块来实现。你需要确保 Nginx 从 CDN 请求头(如 X-Forwarded-For 或 X-Real-IP)中提取真实用户 IP 地址,并将其用于限流。

http_realip 模块文档:
https://nginx.org/en/docs/http/ngx_http_realip_module.html
确保nginx有这个模块,查看命令(包含有 --with-http_realip_module 字样):

nginx -V

nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.1.1g  21 Apr 2020
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=srclib/ngx_devel_kit --add-module=srclib/lua_nginx_module --add-module=srclib/ngx_cache_purge --add-module=srclib/nginx-sticky-module --with-openssl=srclib/openssl --with-pcre=srclib/pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-http_dav_module --add-module=srclib/nginx-dav-ext-module

示例配置

set_real_ip_from  192.168.1.0/24;
set_real_ip_from  192.168.2.1;
set_real_ip_from  2001:0db8::/32;
real_ip_header    X-Forwarded-For;
real_ip_recursive on;

匹配项说明:

  • set_real_ip_from 指定了哪些 IP 地址可以作为信任的代理来源,通常可以设置为 CDN 提供的 IP 范围。 0.0.0.0/0; # 允许所有 IP 的 CDN 代理
  • real_ip_header 设置了使用哪个请求头来获取真实 IP 地址。
  • real_ip_recursive 使 Nginx 从请求头链中递归提取真实 IP 地址。

嵌入变量
$realip_remote_addr
保留原始客户端地址 (1.9.7)
$realip_remote_port
保留原始客户端端口 (1.11.0)

常见配置实例:

http {
    # 信任的代理 IP 范围
    set_real_ip_from 192.168.0.0/24;  # 负载均衡器或 CDN 的 IP 范围
    set_real_ip_from 10.0.0.0/8;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    server {
        location / {
            # 其他配置
        }
    }
}

当使用 real_ip 模块时,$remote_addr 变量将反映真实的客户端 IP 地址,而不是中间代理或负载均衡器的 IP 地址。这是因为 real_ip 模块会根据你配置的规则修改 $remote_addr 变量的值。

**如何工作**
没有代理的情况: $remote_addr 直接表示客户端的 IP 地址,无需 real_ip 模块的干预。

有代理或 CDN 的情况: 当你配置了 real_ip 模块并正确设置了信任的代理 IP 地址和请求头(如 X-Forwarded-For),Nginx 会从这些请求头中提取真实的客户端 IP 地址,并将其赋值给 $remote_addr。这使得 $remote_addr 始终反映真实的客户端 IP,而不是代理或负载均衡器的 IP。
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;

另一种得到真实IP的方法

  map $http_x_forwarded_for  $clientRealIp {
                ""      $remote_addr;
                ~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
        }

$clientRealIp就得到了真实IP

标签: none

添加新评论