如,是我測試的一段代碼訪問一個IP查詢服務的服務,可以看出,可以任何偽造ip地址!
當前正在做的一個PHP項目,需要驗證使用者的IP地址是否在授權範圍中,請問有什麼方法可以避免使用者偽造IP?
或者,是否能提供一個其他思路?
補充:實際情境為rest調用,調用和被調用端都為伺服器~
回複內容:
如,是我測試的一段代碼訪問一個IP查詢服務的服務,可以看出,可以任何偽造ip地址!
當前正在做的一個PHP項目,需要驗證使用者的IP地址是否在授權範圍中,請問有什麼方法可以避免使用者偽造IP?
或者,是否能提供一個其他思路?
補充:實際情境為rest調用,調用和被調用端都為伺服器~
提供幾個思路:
- 如果是區域網路環境,那麼建議你從系統上,甚至路由器上去限制IP
- 如果是公開的,偽造IP將無法收到你的Response,也就是說這個Response會發到那個被偽造的IP去。所以,除非是對你做泛洪攻擊,偽造IP沒有意義。
再說你評論的那個方案,其實是一種驗證的手段,我倒是覺得,這種手段和對稱式加密沒什麼兩樣,當然對稱式加密成本要比你說的握手方式成本低很多。
總之,限制IP是為了做訪問限制,而為了資料安全,還是要做加密和身分識別驗證,對稱式加密是個好辦法(對稱式加密中加入時間等元素,安全性一般比較高)。
REMOTE_ADDR 沒那麼容易偽造.
請參見
Can $_SERVER['REMOTE_ADDR'] be trusted?
http://stackoverflow.com/questions/58...
"HTTP_" 開頭的$_SERVER很容易偽造.
服務段判斷還是挺容易的. 其實下面這個代碼也是判斷是否使用proxy.
結論:服務段最好只取$_SERVER['REMOTE_ADDR']
------------------------小插曲---------------------
最近幫人研究一下discuz的xplus投票系統.
function _get_client_ip() {$clientip = '';if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {$clientip = getenv('HTTP_CLIENT_IP');} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {$clientip = getenv('HTTP_X_FORWARDED_FOR');} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {$clientip = getenv('REMOTE_ADDR');} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {$clientip = $_SERVER['REMOTE_ADDR'];}preg_match("/[\d\.]{7,15}/", $clientip, $clientipmatches);$clientip = $clientipmatches[0] ? $clientipmatches[0] : 'unknown';return $clientip;}
呵呵...
"X-FORWARDED-FOR" 是Proxy 伺服器通過 HTTP Headers 提供的用戶端IP。Proxy 伺服器可以偽造任何IP。
要防止偽造,不要讀這個IP即可(同時告訴使用者不要用HTTP 代理)。
如果是PHP,$_SERVER['REMOTE_ADDR'] 就是跟你伺服器直接連接的IP,用這個就可以了。
我也試過這個,不止是X-FORWARDED-FOR,也可以偽造CLIENT_IP的要求標頭,看你的指令碼如何取要求標頭的key, 好像就REMOTE_ADDR沒辦法偽造,可以取這個吧,PHP下是$_SERVER['REMOTE_ADDR'],不知道會不會存在空值的情況。
想完全避免近乎不可能,透明和匿名http代理還能檢測http頭,但是socks代理呢,或者自己實現的連接埠轉寄呢?
現在能想到的就是維護一個巨大的庫,把所有能搜集到的可能是代理的ip加進去,使用者訪問之前先進庫對比。但是這樣缺點也很大,一是庫太大了訪問速度會變慢,影響效率;二是有些ip可能只是暫時是代理,比如肉雞,可能會恢複正常,比如營運商動態分配的ip,今天我用時做代理,明天分配到你那裡就可能不是代理了,如果沒有一個很好的檢測剔除機制,很可能誤殺;三是庫不可能把所有代理都收進去,只能儘可能搜集一些互連網上公開的代理,私人代理很難收集到,這些庫之外的代理還是沒法避免他們訪問。
不過目前有公司確實在維護這樣的庫,對外以api的方式提供服務。