作者arrack (艾瑞克)
看板PHP
標題Re: [請益] Get client ip
時間Fri Jun 19 21:20:27 2009
※ 引述《fillmore (.......................)》之銘言:
: 重點就在於
: getenv("REMOTE_ADDR") = 永遠都是server的ip
: 當其他變數HTTP_X_FORWARDED_FOR......等都不work的時候
: 最後都看REMOTE_ADDR的結果
: 我認知沒錯巴???我看過很多版本的get client ip的版本了
: 最後都看REMOTE_ADDR的結果
: 但是偏偏REMOTE_ADDR的結果永遠都是server的ip
: 所以判斷一定是會有錯誤@@"
先看一下這篇文章
http://bugs.php.net/bug.php?id=44634&edit=1
以及參考資料
http://en.wikipedia.org/wiki/X-Forwarded-For
這裡有更多資料可以參考
http://google.com/#hl=en&q=REMOTE_ADDR+returns+the+same+ip+as+SERVER_ADDR
你主機的情形,
多半是透過了HTTP proxy 或是 load balancer
Client=>Router or proxy=>Server
在Server的認定Remote_addr中,當然就是那台Proxy
而Server的IP就是內部的IP,藏起來讓你無從得知
這部分你可以看一下REMOTE_PORT,在透過netstat看一下你自己本身主機的狀態
就知道中間還有多透過一層
以我們公司來說,Server的IP是192開頭的,Remote_addr是防火牆的IP
結論:其實這部分無擔心,當透過IP轉送或是PROXY的時候
HTTP_X_FORWARDED_FOR,原則上一定會有資料的。
以下funciton 你可以拿去用,我用到現在是都OK
//兩個都要複製,過濾虛擬IP
function getIP() {
if (validip($_SERVER["HTTP_CLIENT_IP"])) {
return $_SERVER["HTTP_CLIENT_IP"];
}
foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) {
if (validip(trim($ip))) {return $ip;}
}
if (validip($_SERVER["HTTP_X_FORWARDED"])) {
return $_SERVER["HTTP_X_FORWARDED"];
}elseif(validip($_SERVER["HTTP_FORWARDED_FOR"])) {
return $_SERVER["HTTP_FORWARDED_FOR"];
} elseif (validip($_SERVER["HTTP_FORWARDED"])) {
return $_SERVER["HTTP_FORWARDED"];
} elseif (validip($_SERVER["HTTP_X_FORWARDED"])) {
return $_SERVER["HTTP_X_FORWARDED"];
} else {
return $_SERVER["REMOTE_ADDR"];
}
}
function validip($ip) {
if (!empty($ip) && ip2long($ip)!=-1) {
$reserved_ips = array (
array('10.0.0.0','10.255.255.255'),
array('127.0.0.0','127.255.255.255'),
array('169.254.0.0','169.254.255.255'),
array('172.16.0.0','172.31.255.255'),
array('192.168.0.0','192.168.255.255'),
);
foreach ($reserved_ips as $r) {
echo $r;
$min = ip2long($r[0]);
$max = ip2long($r[1]);
if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max)) return false;
}
return true;
} else {return false;}
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
※ 編輯: arrack 來自: 219.84.185.110 (06/19 21:31)
※ 編輯: arrack 來自: 219.84.185.110 (06/19 21:35)
推 fillmore :應該還是不行巴當沒有HTTP_X_FORWARDED_FOR 06/20 12:05
→ fillmore :還是跑去選擇看REMOTE_ADDR @@" 06/20 12:06
→ arrack :看來你還是沒有看進去.. 06/20 12:18
→ arrack :上面解釋那麼多,就是在說明,也去看一下WIKI吧 06/20 12:21
推 fillmore :重點是我是實測了還有人會有人判斷錯誤ip 06/20 12:41
→ fillmore :不然我根本不會發問的@@ 06/20 12:42
推 fillmore :你的script就可以看出當HTTP_X_FORWARDED沒生效時 06/20 13:02
→ fillmore :一定會跑去參考REMOTE_ADDR的值 06/20 13:02
→ chrisQQ :不然 HTTP_X_FORWARDED 沒生效的時候要參考哪個值? 06/20 13:56
→ chrisQQ :我覺得問題根本就不在PHP,因為PHP似乎不提供你這種 06/20 13:57
→ chrisQQ :環境的偵測IP支援,所以除了 HTTP_X_FORWARDED 外應 06/20 13:57
→ chrisQQ :該無解吧?有點像再問firefox為什麼不能顯示activeX 06/20 13:59
※ 編輯: arrack 來自: 219.84.185.110 (06/20 14:02)
推 chrisQQ :感覺在這個版常常會鬼打牆… 06/20 14:02
推 chrisQQ :原來有解法~ 我錯了 Q_____Q 06/20 14:49
推 fillmore :解法在哪?請賜教@@ 謝謝 06/20 16:29
推 chrisQQ :這篇的 code 有改過,你可以再試試看 06/20 18:58
推 fillmore :測試過再回報,HTTP_X_FORWARDED_FOR不一定會提供的 06/20 23:53
推 roga :你好煩喔... 06/22 11:35
→ roga :搞不懂你到底想怎樣 06/22 11:35
→ fillmore :你沒看懂我的問題?先找出root cause再說巴 06/23 03:00
→ fillmore :我沒有想怎樣只是想要判斷正確client ip........ 06/23 03:01
→ arrack :他最大的問題就是別人提供給他的資料也不看 06/23 12:59
→ arrack :HTTP_X_FORWARDED_FOR 在某些情況下才會生效 06/23 12:59
推 fillmore :沒錯HTTP_X_FORWARDED_FOR就是還是有情況不生效 06/24 01:16
→ fillmore :所以最後才會去參考REMOTE_ADDR導致錯誤判定 06/24 01:16
推 fillmore :這台主機我已經退掉了 所以沒辦法測試 06/28 21:30