Home » 未分类 » 获取客户端真实IP

获取客户端真实IP

一般的,获取客户端真实 IP 会取全局变量 $_SERVER 中的 REMOTE_ADDR。在请求没经过转发的情况下是对的,经过转发后这个值就是转发服务器的 IP 了。我们要在转发软件中将真实的客户端 IP 进行传递,后端才有可能获取得到。

以 nginx 为例,一般会在转发时通过 proxy_set_header 指令添加一个名为 X-Forwarded-For 的请求头,其值是内置变量 $proxy_add_x_forwarded_for。此变量会不断的将 $remote_addr  的值追加到 X-Forwarded-For 中,多个以逗号分割。若请求中没有 X-Forwarded-For 请求头,它的值等于 $remote_addr。在三台服务器上测试,请求客户端-218.17.233.156先后通过机器1-106.14.33.138、机器 2-45.32.255.235使用 proxy_pass 指令的转发,最后到达机器3-134.175.116.139。三台机器的 nginx 都添加以下配置:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

三台机器 access_log 查看 $remote_addr 与 $http_x_forwarded_for 的值:

可以看到,到达机器3时,$remote_addr  是它前一台转发机器即机器2的 IP,$http_x_forwarded_for 是客户端 IP 与机器1的IP。这时取 $_SERVER[‘HTTP_X_FORWARDED_FOR’] 中第 1 个 IP 就是客户端 IP 了。

但是,这个 X-Forwarded-For 毕竟只是一个请求头,如果客户端的请求本身就包含这样一个请求头,你就不知道真实的客户端IP是第几个了。如我们的请求添加名为 X-Forwarded-For 值为 aaa, bbb 的请求头,最终的 $http_x_forwarded_for 值将会是:

我们需要稍微修改下,第一台转发机器配置的 proxy_set_header X-Forwarded-For 不要取 $proxy_add_x_forwarded_for ,直接忽略取 $remote_addr ,后边的机器都不需要变,就可以了。

其实我们并不关心中间转发层机器的 IP,只需要客户端的 IP,更简单直接的方法是第一台机器把 $remote_addr 传递,后边的取过来接力就可以了。一般使用名为 X-Real-IP 的请求头。

//第一台机器添加
proxy_set_header X-Real-IP $remote_addr;

//后边的机器添加
proxy_set_header X-Real-IP $http_x_real_ip;

这样在后端,直接取 $_SERVER[‘HTTP_X_REAL_IP’] 就是客户端 IP。

参考:https://juejin.im/entry/5bbb6e90f265da0a89304a43

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.