php獲取客戶端ip


獲取ip函數如下:

function getIP() {
	$realip = ''; //設置默認值
	if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
		$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
	} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
		$realip = $_SERVER['HTTP_CLIENT_IP'];
	} else {
		$realip = $_SERVER['REMOTE_ADDR'];
	}
	preg_match('/^((?:\d{1,3}\.){3}\d{1,3})/',$realip,$match);
        if($match && ipType($match[0]) == 'InterNet網地址'){
                return  $match[0];
        }else{
                return  false;
        }
}

//互聯網允許使用IP地址
function ipType($ip) {
	$iplist = explode(".", $ip);
	if ($iplist[0] >= 224 && $iplist[0] <= 239) 
                return '多播'; 
        if ($iplist[0] >= 240 && $iplist[0] <= 255)
		return '保留';
	if (preg_match('/^198\.51\.100/', $ip))
		return 'TEST-NET-2,文檔和示例';
	if (preg_match('/^203\.0\.113/', $ip))
		return 'TEST-NET-3,文檔和示例';
	if (preg_match('/^192\.(18|19)\./', $ip))
		return '網絡基准測試';
	if (preg_match('/^192\.168/', $ip))
		return '專用網絡[內部網]';
	if (preg_match('/^192\.88\.99/', $ip))
		return 'ipv6to4中繼';
	if (preg_match('/^192\.0\.2\./', $ip))
		return 'TEST-NET-1,文檔和示例';
	if (preg_match('/^192\.0\.0\./', $ip))
		return '保留(IANA)';
	if (preg_match('/^192\.0\.0\./', $ip))
		return '保留(IANA)';
	if ($iplist[0] == 172 && $iplist[1] <= 31 && $iplist[1] >= 16)
		return '專用網絡[內部網]';
	if ($iplist[0] == 169 && $iplist[1] == 254)
		return '鏈路本地';
	if ($iplist[0] == 127)
		return '環回地址';
	if ($iplist[0] == 10)
		return '專用網絡[內部網]';
	if ($iplist[0] == 0)
		return '本網絡(僅作為源地址時合法)';
	return 'InterNet網地址';
}

網上常見獲取ip函數如下:

    public function get_real_ip() {
        static $realip;
        if (isset($_SERVER)) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } else if (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $realip = $_SERVER['HTTP_CLIENT_IP'];
            } else {
                $realip = $_SERVER['REMOTE_ADDR'];
            }
        } else {
            if (getenv('HTTP_X_FORWARDED_FOR')) {
                $realip = getenv('HTTP_X_FORWARDED_FOR');
            } else if (getenv('HTTP_CLIENT_IP')) {
                $realip = getenv('HTTP_CLIENT_IP');
            } else {
                $realip = getenv('REMOTE_ADDR');
            }
        }
        return $realip;
    }

’REMOTE_ADDR’ ,’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’之間的區別?
1.’REMOTE_ADDR’ 是遠端IP,默認來自tcp 連接是,客戶端的Ip。可以說,它最准確,確定是,只會得到直接連服務器客戶端IP。如果對方通過代理服務器上網,就發現。獲取到的是代理服務器IP了。
如:a->b(proxy)->c ,如果c 通過’REMOTE_ADDR’ ,只能獲取到b的IP,獲取不到a的IP了。

2.’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 為了能在大型網絡中,獲取到最原始用戶IP,或者代理IP地址。對HTTp協議進行擴展。定義了實體頭。
HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2 所有IP用”,”分割。 HTTP_CLIENT_IP 在高級匿名代理中,這個代表了代理服務器IP。既然是http協議擴展一個實體頭,並且這個值對於傳入端是信任的,信任傳入方按照規則格式輸入的。以下以x_forword_for例子加以說明,正常情況下,這個值變化過程。
image_thumb18

風險點所在:
這些變量,來自http請求的:x-forword-for字段,以及client-ip字段。 正常代理服務器,當然會按rfc規范來傳入這些值。但是,當一個用戶直接構造該x-forword-for值,發送給用戶,這樣就好比就直接有一個可以寫入任意值的字段。並且服務器直接讀取,或者寫入數據庫,或者做顯示。它將帶來危險性,跟一般對入輸入沒有做任何過濾檢測,之間操作數據源結果一樣。

對於上面getip函數:
除了客戶端可以任意偽造IP,並且可以傳入任意格式IP。 這樣結果會帶來2大問題,其一,如果你設置某個頁面,做IP限制。 對方可以容易修改IP不斷請求該頁面。 其二,這類數據你如果直接使用,將帶來SQL注冊,跨站攻擊等漏洞。至於其一,可以在業務上面做限制,最好不采用IP限制。 對於其二,這類可以帶來巨大網絡風險。我們必須加以糾正。


參考:
http://blog.chacuo.net/98.html
http://blog.chacuo.net/103.html


免責聲明!

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



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