`

客户端的IP地址伪造、CDN、反向代理

阅读更多

    

外界流传的JAVA/PHP服务器端获取客户端IP都是这么取的:
伪代码:
1)ip = request.getHeader("X-FORWARDED-FOR")
    可伪造,参考附录A
2)如果该值为空或数组长度为0或等于"unknown",那么:
ip = request.getHeader("Proxy-Client-IP")
3)如果该值为空或数组长度为0或等于"unknown",那么:
ip = request.getHeader("WL-Proxy-Client-IP")
4)如果该值为空或数组长度为0或等于"unknown",那么:
ip = request.getHeader("HTTP_CLIENT_IP")
    可伪造
5)如果该值为空或数组长度为0或等于"unknown",那么:
ip = request.getRemoteAddr()
    可对于匿名代理服务器,可隐匿原始ip,参考附录B
 
之所以搞这么麻烦,是因为存在很多种网络结构,如 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;

              }
注意看红色字体,这些配置与下面的闯关拿IP有关。
 
———————————————————————————————
——第一关|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”,这样取第一个值即可
      • 这也就是大家所常见的场景!
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_client-cdn-nginx-resin.png
综上所述,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。
 
郑昀 :△
+++附录A XFF 与 Nginx 配置的测试用例+++
测试环境: nginx+resin
内网IP:172.16.100.10
客户端IP:123.123.123.123

测试页面: test.jsp
<%
out.println("x-forwarded-for: " + request.getHeader("x-forwarded-for"));
out.println("remote hosts: " + request.getRemoteAddr());
%>

nginx 配置一
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
wget测试
wget -O aa --header="X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"
页面返回结果:
x-forwarded-for: 192.168.0.1, 123.123.123.123
remote hosts: 172.16.100.10
 
curl测试
curl -H "X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"
x-forwarded-for: 192.168.0.1, 123.123.123.123
remote hosts: 172.16.100.10

nginx 配置二
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

wget测试:
wget -O aa --header="X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"
页面返回结果:
x-forwarded-for: 123.123.123.123
remote hosts: 172.16.100.10

curl测试
curl -H "X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"
x-forwarded-for: 123.123.123.123
remote hosts: 172.16.100.10

测试结果:
1、配置  
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
增加了一个真实ip X-Forwarded-For,并且顺序是增加到了“后面”。

2、配置  
proxy_set_header X-Forwarded-For $remote_addr;
清空了客户端伪造传入的X-Forwarded-For
保证了使用 request.getHeader("x-forwarded-for") 获取的ip为真实ip,
或者用“,”分隔,截取 X-Forwarded-For 最后的值。
 
+++附录B 搜狗浏览器高速模式的测试用例+++
访问路径:
搜狗浏览器“高速”模式(即使用代理)-->LVS-->Apache
获得的值为:
x-forwarded-for:180.70.92.43   (即真实ip)
Proxy-Client-IP:null
WL-Proxy-Client-IP:null 
getRemoteAddr:123.126.50.185  (即搜狗代理ip)
 
 
×××参考资源:×××
1,http://bbs.linuxtone.org/thread-9050-1-1.html
2,http://hi.baidu.com/thinkinginlamp/item/e2cf05263eb4d18e6e2cc3e6
3,http://bbs.chinaunix.net/thread-3659453-1-1.html
转自:http://zhengyun-ustc.iteye.com/blog/1895878
分享到:
评论

相关推荐

    cdn软件高级版(nginx反向代理方式实现)

    反向代理是指客户端请求到达Nginx服务器时,Nginx并不直接返回内容,而是根据配置将请求转发到实际的后端服务器,获取内容后再返回给客户端。这样做的好处包括负载均衡、安全防护以及提高响应速度等。 **二、Nginx...

    PHP 获取客户端IP

    客户端IP地址可以帮助我们识别用户的位置,记录访问日志,或者在需要时实施IP限制策略。以下是一些关于如何在PHP中获取客户端IP的方法,以及相关的知识点。 首先,PHP提供了`$_SERVER`全局变量数组,它包含了服务器...

    获取客户端IP

    在实际应用中,获取客户端IP可能会受到各种因素的影响,比如NAT、代理服务器、CDN服务等,因此,正确地获取并处理IP地址是一个需要细心考虑的问题。了解这些细节对于优化服务、提高用户体验以及确保网络安全都至关...

    Web APP 如何实现类似Nginx反向代理转发功能-zhangyannan1

    在实际应用中,我们可以根据需要调整反向代理转发规则,例如根据用户的IP地址、浏览器类型等信息来进行转发。同时,我们也可以使用其他技术,例如负载均衡器、CDN 等来实现反向代理转发功能。 使用 Web APP 实现...

    精确的在线人数统计,记录客户端的ip等等........

    - **CDN与反向代理**:若使用CDN或反向代理,需确保计数逻辑在最接近源服务器的地方执行,以避免重复计算。 2. IP地址记录: 记录客户端IP地址可以提供以下信息: - **用户识别**:虽然IP地址不等同于唯一用户,...

    kangle反向代理linux安装包

    反向代理(Reverse Proxy)是网络服务的一种架构模式,其工作原理是,客户端的请求首先会到达反向代理服务器,然后由反向代理服务器决定将请求转发到哪个内部服务器(如Web服务器、应用服务器等)。这样做的好处包括...

    CDN获取真实IP

    在使用CDN的情况下,服务器接收到的客户端IP地址实际上是CDN节点的IP地址。可以通过特定的Nginx配置来获取客户端的真实IP地址: ```nginx http { proxy_set_header X-Real-IP $remote_addr; proxy_set_header ...

    CDN下真实ip查询器

    然而,由于数据传输的路径经过多个CDN节点,这使得在CDN环境下获取用户的真实IP地址变得复杂。 "CDN下真实ip查询器"是一个专门针对这种情况设计的工具,它的主要功能是穿透CDN服务,准确地识别出用户的原始IP地址。...

    7ghostPHP反向代理脚本

    7ghostPHP反向代理脚本通过将HTTP请求重定向到其他服务器,实现了这一目的,尤其适用于负载均衡和内容分发网络(CDN)场景。 首先,`.htaccess`文件是Apache Web服务器配置的一部分,用于实现对目录级别的配置,...

    Python-通过扫描全网绕过CDN获取网站IP地址.zip

    2. **IP反向查找**:获取CDN分配给特定域名的IP后,可以尝试进行反向DNS查找,找出该IP对应的主机名,然后对主机名再次进行正向解析,可能会揭示原始IP。 3. **网络扫描**:利用Python中的网络扫描库(如Scapy、...

    idea,java获取ip地址

    然而,如果应用运行在反向代理服务器(如Nginx)后,这个方法可能会返回代理服务器的IP。因此,我们需要检查`X-Forwarded-For`头,它包含了经过代理服务器的原始客户端IP。 ```java String ipAddress = request....

    asp.net获取客户端mac地址

    - 一些ISP(Internet Service Provider)或CDN(Content Delivery Network)服务可能会提供客户端的MAC地址,但这些信息通常是私有的,只有在服务提供商允许的情况下才能获取。 6. **网络设备日志**: - 在企业...

    反向代理缓存视频.zip

    这个“反向代理缓存视频.zip”压缩包文件包含了多个关于这一主题的相关资料,包括“1-buffer-cache.rar”、“2浏览器dns.rar”、“3浏览器缓存”、“4-cdn.rar”、“5-oldboy-1.rar”、“6-ngink反向代理.rar”以及...

    Squid代理项目-正向和反向详细笔记文档实战案例

    在这种情况下,客户端需要知道代理服务器的 IP 地址和端口,并在浏览器或其他应用程序中配置。正向代理常用于共享 Internet 连接、缓存内容以提高速度和减少带宽使用,以及隐藏客户端的真实身份。透明代理也是正向...

    Python-通过扫描全网绕过CDN获取网站IP地址

    "Python-通过扫描全网绕过CDN获取网站IP地址"这个主题涉及到CDN(内容分发网络)的工作原理,以及如何利用Python进行网络扫描来获取真实的服务器IP。CDN是一种分布式网络服务,它能够通过将内容缓存到全球各地的边缘...

    JS获取客户端IP地址、MAC和主机名的7个方法汇总

    在JavaScript中,获取客户端的IP地址、MAC地址和主机名通常是由于特定的需求,例如实现个性化服务、定位或安全验证。由于JavaScript的安全限制,它本身并不直接支持这些操作,但可以通过一些间接的方式实现。以下是7...

    第六节 收集真实IP地址信息-01

    如果目标服务器返回的IP地址不是真实的IP地址,而是一个CDN的IP地址,那么可以判断目标服务器使用了CDN。 三、绕过CDN 如果目标服务器使用了CDN,那么需要绕过CDN来获取真实IP地址。有多种方法可以绕过CDN,例如:...

    业界最有价值Nginx反向代理实战博文荟萃

    Nginx是一款高性能的反向代理服务器,它在处理高并发请求方面表现卓越,具备高效的负载均衡能力。Nginx支持在多种操作系统上运行,包括FreeBSD、Linux、Windows以及Mac OS X,这使得它能够在不同的环境下部署,进而...

    Go-dummyorigin-一个模拟源服务器来测试CDN或代理的行为

    在IT行业中,CDN(Content Delivery Network)和代理服务器在优化网站性能、提高用户体验以及保障网络安全方面扮演着重要角色。为了确保这些系统能够正确无误地工作,开发者需要进行详尽的测试。`Go-dummyorigin`项目...

Global site tag (gtag.js) - Google Analytics