$remote_addr
代表客户端ip。注意,这里的客户端指的是直接请求nginx的客户端,非间接请求的客户端。假设用户请求过程如下:
用户客户端--发送请求->nginx1 --转发请求-->nginx2->后端服务器
那么,默认情况下,针对nginx1而言,$remote_addr
为用户客户端ip,对nginx2而言,$remote_addr
则为nginx1的ip。此时如果希望nginx2也可以获取用户客户端ip,那要怎么处理呢?答案如下:
在nginx1配置文件中使用proxy_set_header
为转发请求设置请求头
proxy_set_header x-real-ip $remote_addr; // x-real-ip 为请求头名称,可自定义
然后,在nginx2 配置文件中通过$http_x_real_ip
来获取x-real-ip
请求头的值来获取真实客户端ip.
此时,如果要求“后端服务器”也要获取用户客户端ip,咋处理呢?做法和上述类似,在nginx2配置文件中,使用proxy_set_header
做同样的配置,即:
proxy_set_header x-real-ip $remote_addr;
然后,“后端服务器”获取请求头“x-real-ip”的值即为用户客户端ip。
很多http代理会在http协议头中添加x-forwarded-for
头,用来追踪请求的来源。x-forwarded-for
的格式如下:
x-forwarded-for
包含多个ip地址,每个值通过逗号+空格分开,最左边(client1)是最原始客户端的ip地址,中间如果有多层代理,每一层代理会将连接它的客户端ip追加在x-forwarded-for
右边。
$proxy_add_x_forwarded_for
代表附加$remote_addr
变量的客户端请求头x-forwarded-for
,其值如果包含多个地址,用逗号+空格分隔,标准格式如下:
x-forwarded-for: clientip, proxyip1, proxyip2 # 最左边的clientip即为客户端真实ip
如果x-forwarded-for
字段没出现在客户端请求头,$proxy_add_x_forwarded_for
等同于$remote_addr
变量。
这里,假设用户请求过程和上文所述一样,如下:
用户客户端--发送请求->nginx1 --转发请求-->nginx2->后端服务器
假设,仅在nginx1配置文件中进行了以下配置
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
那么,nginx2配置的x-forwarded-for
请求头的值即为clientip
,当然,这个结论的前提是,客户端ip没有配置x-forwarded-for请求头,因为如上所述,客户端没有出现这个请求头时,$proxy_add_x_forwarded_for 的值即为$remote_addr 变量的值,否则,则是客户端为x-forwarded-for请求头的实际值。
接着,假设nginx2配置文件也进行以下配置
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
那么,“后端服务器”获取的x-forwarded-for
请求头的值将为clientip, nginx1ip
。也就是说以上命令的执行是个叠加的过程(类似python的列表的append
方法的处理过程),可以简单理解为如果存在上级代理,执行以上命令时,会把上级代理ip追加到x-forwarded-for请求头总,否则把客户端ip $remote_addr、或者客户端x-forwarded-for请求头的值(如果有的话)追加到x-forwarded-for请求头中。
参考连接:
https://nginx.org/en/docs/http/ngx_http_core_module.html#var_remote_addr
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_add_x_forwarded_for
到此这篇关于nginx $remote_addr和$proxy_add_x_forwarded_for变量的实现的文章就介绍到这了,更多相关nginx $remote_addr和$proxy_add_x_forwarded_for 内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论