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