获取nginx代理后的ip

阅读 2.2k

在部署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。

参考资料

MDN, X-Forwarded-For

HTTP 请求头中的 X-Forwarded-For

最后编辑于: 2022-06-28

评论(0条)

(必填)
复制成功