码迷,mamicode.com
首页 > 其他好文 > 详细

获取用户的真实ip

时间:2015-06-17 13:06:58      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

常见的坑有两个:

 

一、获取的是内网的ip地址。nginx作为代理层,转发请求到php,java等应用容器上。结果php获取的是nginx代理服务器的ip,表现为一个内网的地址。

二、获取的是攻击者伪造的ip地址。攻击者可以随便伪造一个头部信息,随便填写一个ip放到头部发过来,php获取到HTTP_CLIENT_IP。为避免伪造,不要使用discuz原来的获取ip函数,里面的判断优先级会使得攻击者容易伪造ip。

 

 

php代码:

 

function getIP() {

 

        if (getenv("HTTP_X_FORWARDED_FOR")) {

            //这个提到最前面,作为优先级,nginx代理会获取到用户真实ip,发在这个环境变量上

            $ip = getenv("HTTP_X_FORWARDED_FOR");

        } else if (getenv("REMOTE_ADDR")) {

           //在nginx作为反向代理的架构中,使用REMOTE_ADDR拿到的将会是反向代理的的ip,即拿到是nginx服务器的ip地址。往往表现是一个内网ip。

            $ip = getenv("REMOTE_ADDR");

        } else if ($_SERVER[‘REMOTE_ADDR‘]) {

            $ip = $_SERVER[‘REMOTE_ADDR‘];

        } else if (getenv("HTTP_CLIENT_IP")) {

            //HTTP_CLIENT_IP攻击者可以伪造一个这样的头部信息,导致获取的是攻击者随意设置的ip地址。

            $ip = getenv("HTTP_CLIENT_IP");

        } else {

            $ip = "unknown";

        }

        return $ip;

    }

 

 

 

说明

 

不能通过REMOTE_ADDR来获取用户的真实ip!

 

因为反向代理架构: nginx作为一个前端代理,转发请求到php,java等应用程序上去,nginx和php不在同一台物理服务器上。

 

在nginx作为反向代理的架构中,php的REMOTE_ADDR(其他语言也是类似的名称)拿到的将会是nginx代理的ip地址。拿不到用户的真实ip。

 

REMOTE_ADDR本意就是远程的地址,nginx是代理层,转发请求到php,php获取到的远程地址是nginx的服务器地址,这是符合常理的。

 

但是,可以让nginx帮助我们拿到用户的真实ip,然后转发给我们,只要按照某个约定的名称即可,比如预定HTTP_X_FORWARD_FOR。

 

 

nginx配置类似于这样:

 

fastcgi_param  HTTP_X_FORWARD_FOR  $remote_addr;

 

 $remote_addr是nginx的内置变量,这个变量它得到是用户真实的ip地址(用户使用了代理,则就是代理的ip地址)。

 

 上一句的目的是,将HTTP_X_FORWARD_FOR的值设置为$remote_addr的值。也就是将用户真实的ip放到HTTP_X_FORWARD_FOR中去。

 

于是在php端通过getenv("HTTP_X_FORWARDED_FOR")就可以获取到真实的ip地址。

 

 

注:

1、getenv(‘HTTP_X_FORWARD_FOR‘);等价于$_SERVER[‘HTTP_X_FORWARD_FOR‘]; getenv也是获取环境变量的值的。

2、nginx作为反向代理时,统一使用 HTTP_X_FORWARD_FOR来重置用户的真实ip,遵循统一的风格。以保证所有系统的开发,都可以通过"HTTP_X_FORWARD_FOR"获取到用户真实的ip地址。

获取用户的真实ip

标签:

原文地址:http://www.cnblogs.com/wangtao_20/p/4582701.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!