实例:
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 - 博客园