nginx 真实IP Remote-Addr X-Forwarded-For X-Real-IP

工作中做负载均衡的时候回经常用到。在这里记录下。

普及下各个机器的名称

发送请求方的机器 名称叫客户端。
请求转发和反向代理的机器叫负载均衡或者LB
最终逻辑处理的机器叫WEB机器。【码农写的逻辑基本上都在WEB机器上】

先说下我们的测试的机器IP分布。

客户端IP 100.100.100.1
负载均衡LB 100.100.100.2
web机器 100.100.100.3

remote_addr

客户端的IP,如果有代理的话表示最后一个代理服务器的IP。Nginx变量。这个变量是建立TCP连接的IP变量。remote_addr所表示的IP是不可更改的。试想下,如果这个变量可随意更改的话,都无法建立正常的TCP连接。
LB上设置

proxy_set_header   REMOTE-ADDR      100.100.100.100;

WEB机器上打印

ngx.log(ngx.ERR,ngx.req.get_headers()['remote_addr'])
ngx.log(ngx.ERR, ngx.var.remote_addr)

[error] 7566#7566: *5914 [lua] test.lua:
proxy_set_header   REMOTE-ADDR      100.100.100.100
[error] 7566#7566: *5914 [lua] test.lua    100.100.100.2

不管怎么设置,最终Nginx变量的值都是建立连接的IP。而且需要注意的是header里面的值和变量里面的值是不相同的

X-Forwarded-For

Nginx变量,如果每个代理服务器都设置了
proxy_set_header X-Forwarded-For KaTeX parse error: Double subscript at position 12: proxy_add_x_̲forwarded_for 是…remote_addr用逗号合起来,如果请求头中没有X-Forwarded-For则KaTeX parse error: Double subscript at position 12: proxy_add_x_̲forwarded_for为remote。
会记录请求的路由顺序。这个变量只是记录请求的服务器路由顺序。因为这个变量不管在客户端还是代理服务商都是可以伪造的。
我们做下测试

ngx.log(ngx.ERR, ngx.var.http_x_forwarded_for)
100.100.100.1 ,100.100.100.2

基本是按照发起方的请求顺序记录的,显示客户端IP,然后代理服务器的IP。如果有多层代理的话,就是这样的

客户端IP,proxy1,proxy2,proxyN

而且是当前机器追加记录上一个机器的IP。proxy1追加就客户端IP,proxy2追加记录proxy1.
如果请求的时候伪造X-Forwarded-For即加header头 -H ‘X-Forwarded-For:1.1.1.1,2.2.2.2’。就会是

伪造IP,客户端IP,proxy1,proxy2,proxyN

所以说取真实IP直接获取X-Forwarded-For的第一个IP是不合理的。

扫描二维码关注公众号,回复: 5226684 查看本文章

如果是服务器上,不传递X-Forwarded-For,即
proxy_set_header X-Forwarded-For 没有这个。那下一级的X-Forwarded-For这个变量就是空的。所以X-Forwarded-For 这个值主要是proxy_set_header 传递。

X-Real-IP

顾名思义真实IP。这个变量主要是用来记录真实IP。这个值也主要是以来proxy_set_header传递。可以先看下使用

100.100.100.2
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

100.100.100.3
ngx.log(ngx.ERR, ngx.var.http_x_forwarded_for)
ngx.log(ngx.ERR, ngx.var.http_x_real_ip)

100.100.100.1,100.100.100.2
100.100.100.1

可以看到,使用得当,x_real_ip是可以很轻松的拿到真实IP。
如果是多级代理的话,一级一级向后传递真实IP。

第一级代理写法
proxy_set_header X-Real-IP $remote_addr;
后面的代理
proxy_set_header X-Real-IP $x_real_ip;

总结

X-Forwarded-For与X-Real-IP 主要依赖proxy_set_header传递,所以想传什么样的值就传什么样的值。Remote-Addr建立连接的IP,有的地方也说是上一跳的IP,这个不依赖header头传递,不可更改。
所以用上面的组合,第一层代理获取到真实IP,remote_addr。使用x_real_ip层层后传,使用x_real_ip在WEB机器上获取到真实IP。
真实IP的获取顺序是 先检查x_real_ip有无值,有就返回。没有再检查Remote-Addr有无值,有就返回。X-Forwarded-For主要记录请求路由顺序,可伪造。

猜你喜欢

转载自blog.csdn.net/feifeixiang2835/article/details/85042081