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

对获取IP过程的详解

时间:2016-06-26 12:43:19      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:

获取ip之所以搞这么麻烦,是因为存在很多种网络结构,如 Nginx+Resin、Apache+WebLogic、Squid+Nginx。

首先,明确一下,Nginx 配置一般如下所示:
location / {
proxy_pass http://yourdomain.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

——第一关|X-Forwarded-For :背景——
这是一个 Squid 开发的字段,并非 RFC 标准。
简称 XFF 头 ,只有在通过了 HTTP 代理或者负载均衡服务器时才会添加该项。在 Squid 开发文档中可以找到该项的详细介绍。
XFF 格式如下:
X-Forwarded-For: client1, proxy1, proxy2
可以看出,XFF 头信息可以有多个,中间用逗号分隔,第一项为真实的客户端ip,剩下的就是曾经经过的代理或负载均衡服务器的ip地址。

——第一关|X-Forwarded-For :场景=客户端--CDN--Nginx——
当用户请求经过 CDN 后到达 Nginx 负载均衡服务器时,其 XFF 头信息应该为 “客户端IP,CDN的IP”。
一般情况下CDN服务商出于自身安全考虑会将屏蔽CDN的ip,只保留客户端ip。
那么请求头到达 Nginx 时:
    在默认情况下,Nginx 并不会对 XFF 头做任何处理
    此时 Nginx 后面的 Resin/Apache/Tomcat 通过 request.getHeader("X-FORWARDED-FOR") 获得的ip仍然是原始ip 。
  当 Nginx 设置 X-Forwarded-For 等于 $proxy_add_x_forwarded_for 时:
     如果从CDN过来的请求没有设置 XFF 头(通常这种事情不会发生),XFF 头为 CDN 的ip
       此时相对于 Nginx 来说,客户端就是 CDN
     如果 CDN 设置了 XFF 头,我们这里又设置了一次,且值为$proxy_add_x_forwarded_for 的话:
      XFF 头为“客户端IP,Nginx负载均衡服务器IP” ,这样取第一个值即可
      这也就是大家所常见的场景!
  技术分享
综上所述,XFF 头在上图的场景,Resin 通过 request.getHeader("X-FORWARDED-FOR") 获得的ip字符串,做一个split,第一个元素就是原始ip。
那么,XFF 头可以伪造吗?

——第一关|X-Forwarded-For :伪造——
可以伪造。
XFF 头仅仅是 HTTP Headers 中的一分子,自然是可以随意增删改的。如附录A所示。
很多投票系统都有此漏洞,它们简单地取 XFF 头中定义的ip地址设置为来源地址,因此第三方可以伪造任何ip投票。

———————————————————————————————
——第二和第三关|Proxy-Client-IP/WL- Proxy-Client-IP :背景——
Proxy-Client-IP 字段和 WL-Proxy-Client-IP 字段只在 Apache(Weblogic Plug-In Enable)+WebLogic 搭配下出现,其中“WL” 就是 WebLogic 的缩写。
即访问路径是:
Client -> Apache WebServer + Weblogic http plugin -> Weblogic Instances
所以这两关对于我们来说仅仅是兼容而已,怕你突然把 Nginx+Resin 换成 Apache+WebLogic 。
也可以直接忽略这两个字段。

———————————————————————————————
——第四关|HTTP-Client-IP :背景——
HTTP_CLIENT_IP 是代理服务器发送的HTTP头。
很多时候 Nginx 配置中也并没有下面这项:
proxy_set_header HTTP_CLIENT_IP $remote_addr;
所以本关也可以忽略。

———————————————————————————————
——第五关| request.getRemoteAddr() :背景——
从 request.getRemoteAddr() 函数的定义看:
Returns the Internet Protocol (IP) address of the client or last proxy that sent the request.
实际上,REMOTE_ADDR 是客户端跟服务器“握手”时的IP,但如果使用了“匿名代理”,REMOTE_ADDR 将显示代理服务器的ip,或者最后一个代理服务器的ip。请参考附录B。

综上,
java/php 里拿到的ip地址可能是伪造的或代理服务器的ip。

 

具体参考:http://www.udpwork.com/item/8135.html

 

对获取IP过程的详解

标签:

原文地址:http://www.cnblogs.com/liuconglin/p/5617593.html

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