Nginx多层代理,透传获取客户端IP地址

实例:

proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $http_x_forwarded_for;

第一层:

在 http 模块 加

set_real_ip_from 172.17.10.125; #上一层代理IP地址

real_ip_header X-Forwarded-For;

第二层:

proxy_set_header X-Forwarded-For $http_x_forwarded_for; # 针对非首层代理

hftian同学给出的三个方案:

1、第一层代理将用户的真实 IP 放在 X-Real-IP 中传递下去,后面的每一层都使用 X-Real-IP 继续往下传递。配置为:

proxy_set_header X-Real-IP $remote_addr; # 针对首层代理,拿到真实IP

proxy_set_header X-Real-IP $http_x_real_ip;# 针对非首层代理,一直传下去

2、从首层开始,将用户的真实IP 放在 X-Forwarded-For 中,后面的每一层都使用 X-Forwarded-For继续往下传递。配置为:从首层开始,将用户的真实IP 放在 X-Forwarded-For 中,而不是累加各层服务器的 IP,但这样也不够合理,因为丢掉了整个链路信息。配置为:

proxy_set_header X-Forwarded-For $remote_addr; # 针对首层代理proxy_set_header X-Forwarded-For $http_x_forwarded_for; # 针对非首层代理 3、配合 nginx realip 模块获取用户真实IP;我们将各层代理的IP排除在外,就取到了真实的用户IP。这个可以使用nginx的一个模块realip_module 来实现。原理是从XFF中抛弃指定的代理层 IP,那么最后一个符合规则的就是用户 IP。也可以配合第一起方法一起使用。但无论如何,首层代理的规则最重要,直接影响后面的代理层和web service的接收结果。nginx realip_module 模块需要在编译nginx的时候加上参数--with-http_realip_module。

然后在nginx配置中增加以下配置(可以在http,server或location段中增加)

# set user real ip to remote addrset_real_ip_from 10.200.21.0/24;set_real_ip_from 10.100.23.0/24;real_ip_header X-Forwarded-For;real_ip_recursive on;

set_real_ip_from 后面是可信 IP 规则,可以有多条。如果启用CDN,知道CDN的溯源IP,也要加进来,除排掉可信的,就是用户的真实IP,会写入 remote addr这个变量中。

比如在PHP中可以使用$_SERVER[REMOTE_ADDR] 来获取。而WEB SERVER 不使用任何反向代理时,也是取这个值,这就达到了我们之前所说的原则。

real_ip_recursive 是递归的去除所配置中的可信IP。如果只有一层代理,也可以不写这个参数。

参考资料

hftian - 博客园