java防止http header伪造ip地址


一 了解一些东西
   1 X-Forwarded-For 
     XFF 头,只有在通过了 HTTP 代理或者负载均衡服务器时才会添加该项 。

    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 头可以伪造吗?XFF 头仅仅是 HTTP Headers 中的一分子,自然是可以随意增删改的
  • 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 
  • 综上,
    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张

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM