HTTP中ip地址偽造的問題以及解決辦法


在真實環境下,php獲取客戶端ip地址的方法通常有以下幾種:

                    (1):通過$_SERVER[ "HTTP_CLIENT_IP" ]

                    (2):通過$_SERVER[ "HTTP_X_FORWARDED_FOR" ]

                    (3):通過$_SERVER[ "REMOTE_ADDR" ]

這里需要注意的是:在php中的$_SERVER數組中以HTTP開頭的值,都是由客戶端(client)傳遞到服務端的,也就是說這一部分是可以進行偽造的。而$_SERVER[ "REMOTE_ADDR" ]是由服務器傳遞的,是不能進行偽造的(如果這一部分都可以偽造,那就服務器沒有辦法傳遞數據到正確的客戶端上了)

php通過curl函數進行HTTP_CLIENT_IP以及HTTP_X_FORWARDED_FOR進行偽造:

curl_setopt( $ch , CURLOPT_HTTPHEADER , array('X-FORWARDED-FOR:'.$ip, 'CLIENT-IP:'.$ips ) );

其中的 $_SERVER[ "HTTP_X_FORWARDED_FOR" ] 一開始我壓根不知道這是什么,后來查了一下,總結一下:X-Forwarded-For 是一個 HTTP 擴展頭部。HTTP/1.1(RFC 2616)協議並沒有對它的定義,它最開始是由 Squid 這個緩存代理軟件引入,用來表示 HTTP 請求端真實 IP。它的基本格式如下:X-Forwarded-For: client, proxy1, proxy2 (存在反向代理以及負載均衡時會用到,這個也是可以偽造的)

在不存在反向代理或負載均衡的情況下,服務端通過$_SERVER[ "REMOTE_ADDR" ]就可以獲取真實的客戶端ip地址

在存在反向代理或負載均衡的情況下,服務端通過$_SERVER[ "REMOTE_ADDR" ]獲取到的並不是客戶端的ip地址,而是反向代理服務器或者分發服務器的ip地址(詳情看下圖)

服務端獲取的remote_addr其實是由傳遞數據到php解析器的服務器傳遞的,傳遞時連接服務器的ip地址,上圖http文件服務器所獲取的remote_addr就是nginx服務器的ip地址

如何在存在反向代理以及負載均衡的情況下獲取客戶端的真實的ip地址那?解決辦法如下:

在上圖的nginx服務器(代理服務器中)進行HTTP_X_FORWARD_FOR參數的配置,配置如下:

location ~ "\.+\.php$" {

     fastcgi_pass localhost:9000;

     fastcgi_param  HTTP_X_FORWARD_FOR  $remote_addr;

} -----nginx向php-fpm傳遞的HTTP_X_FORWARD_FOR參數是nginx獲取的真實的客戶端ip,那么在php腳本中直接獲取$_SERVER[ "HTTP_X_FORWARD_FOR" ]就可以獲取真實的客戶端ip地址了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM