获取nginx代理后的ip
在部署Web应用时,通常会在前端架设一个nginx作为代理服务器
,让它来处理静态资源(比如图片,样式表等),动态服务则转发给后端的web应用来处理,这就是所谓的动静分离
,结构图如下:
这种结构引出了一个问题:通过代理转发后,后端服务器获得的ip是代理服务器的ip,而不是原始请求客户端的ip。在后端应用的日志系统中,如果需要记录原始客户端的ip地址,怎么办呢?通过资料查阅,发现解决方案和X-Forwarded-For
有着密切的关联。
X-Forwarded-For
http协议的底层是tcp/ip
协议,对于通信双方来说,一端肯定知道另一端的ip地址,这个ip无法被伪造。但如果在通信过程中,途径代理或者负载均衡服务器,如下图所示:
如果client和server直接通过http通信,那么server端是知道client的ip地址的。但现在client和proxy通信,然后,proxy再和server通信,那么,server就只知道proxy的ip,而无法知道client的ip。
如果server要知道client的ip,就只能通过proxy来告诉server,因为proxy知道client的ip。所以,需要约定一个方式来让proxy转发和它通信的另一端的ip,于是 X-Forwarded-For 出现了,它就是来解决这个问题的。
其语法结构如下:
X-Forwarded-For: <client>, <proxy1>, <proxy2>
比如:
X-Forwarded-For: 203.0.113.195, 70.41.3.18, 150.172.238.178
203.0.113.195
为原始客户端ip,70.41.3.18
为第一个代理服务器ip,150.172.238.178
为第二个代理的ip。所以,最左边的那个ip就是原始客户端ip。
$proxy_add_x_forwarded_for
通过查阅nginx的文档发现,在nginx中可以配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
请注意$proxy_add_x_forwarded_for
这个变量,它是nginx中定义的,它的取值规则如下:
- 如果客户端请求头中没有 X-Forwarded-For 字段,那么值为
$remote_addr
变量的值 - 如果客户端请求头中有 X-Forwarded-For 字段,那么会在这个字段后面追加
$remote_addr
变量的值,通过逗号隔开。
有意思的是,经过nginx搞这么一出,现在,X-Forwarded-For字段中最右边的值,才是原始客户端ip。