PHP?獲取客戶端真實IP地址
PHP獲取客戶端真實IP地址,需要根據(jù)具體的服務器環(huán)境來確定使用哪種方法。目前搜索到的方法,大多是直接貼代碼,沒有針對不同情況作出說明,有可能導致系統(tǒng)被假IP騙過(IP欺騙)。
很多文章都提到“無法保證獲取到的訪客IP地址100%準確”,是否意味著PHP獲取訪客IP一定有漏洞可鉆呢?
只要根據(jù)實際部署情況選擇相對應的代碼獲取訪客IP地址,是可以確保程序不被假IP欺騙的。
PHP的運行方式
PHP支持非常多的運行方式,例如php-cgi、php-fpm、swoole、php-cli、php-mod等。其中,php-fpm是php的fast-cgi的進程管理器。php-mod通常配合Apache使用,而php-fpm通常配合Nginx使用。從PHP5.4開始,PHP甚至可以以內(nèi)置PHP服務(Buid-in web server)方式運行。逐漸的,PHP形成了很多經(jīng)典搭配,例如LAMP、LNMP、LNMPA、IIS+PHP。
無論采用哪種PHP運行方式,分清是誰傳遞IP給PHP程序即可。這里對幾種常見環(huán)境進行分析。
無代理層(PHP內(nèi)置服務器/swoole)
由于客戶端IP數(shù)據(jù)是從TCP/IP協(xié)議層傳遞過來的,因此在沒有中間代理(客戶端和服務器直連)的情況下,可以直接通過標準方法REMOTE_ADDR
獲得與PHP直接通訊的IP地址。
例如$_SERVER['REMOTE_ADDR']
或getenv("REMOTE_ADDR")
。
而在swoole
中,可以通過$request->server['remote_addr']
獲得客戶端IP地址。
在這種情況下,REMOTE_ADDR
不可以顯式的偽造,獲取到的是實際與服務器連接的IP地址,是可靠的。
Nginx代理(Nginx + php-fpm / Nginx + swoole)
常見的LNMP方案,屬于Nginx反向代理。Nginx與php的通訊,無論unix socket
方式還是tcp socket
方式,都跟Nginx的Header配置有關系。
proxy_http_version 1.1; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
可以在第一層nginx代理設置 proxy_set_header X-Forwarded-For $remote_addr
,
其他層nginx代理設置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
這樣就可以通過X-Forwarded-For
獲取客戶端真實IP地址。
如果設置了X-Real-IP $remote_addr
,則通過X-Real-IP
獲取客戶端IP地址。
PHP代碼:
// php-fpm等 $_SERVER['HTTP_X_FORWARDED_FOR']); // swoole $this->http_input->header('x-real-ip');
總結來說,當有Nginx
代理的情況下,需要根據(jù)具體配置來選擇獲取的Header,從而正確獲取客戶端IP地址,此時PHP中的的REMOTE_ADDR
可能是最后一級代理的IP地址。
Apache代理(Apache + php_mod / Apache + php-fpm)
通常在Apache + PHP方案中,獲取IP地址取決于Apache配置信息。
絕大部分情況可以使用$_SERVER["REMOTE_ADDR"]
獲取到真實客戶端IP地址。
如果Apache上級存在Nginx,那么可以在Apache中使用mod_rpaf
模塊將客戶端IP地址傳遞到X-Forwarded-For
頭中。
PAFheader X-Forwarded-For
負載均衡/云虛擬機/Serverless
在負載均衡條件下,需要查閱對應負載均衡程序的文檔,來決定使用哪種方法獲取真實客戶端IP地址。
在大部分虛擬主機、負載均衡及無服務器中,可以通過HTTP_CLIENT_IP
、HTTP_X_FORWARDED_FOR
或X-REAL-IP
其一得知客戶端IP地址。但是不建議對多種來源進行空值判斷,這樣容易被偽造者利用,從而實現(xiàn)IP欺騙。
目前并未有標準規(guī)定將客戶端IP地址放入名為CLIENT_IP
的環(huán)境變量,但是有不少老虛擬主機供應商這樣做。新的提供商都不再使用該環(huán)境變量。網(wǎng)上大量的PHP文章中都是優(yōu)先獲取HTTP_CLIENT_IP
的值,因此導致網(wǎng)上存在大量的服務器可以被偽造IP欺騙。
可能有該漏洞的代碼:
<?php if(!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { $ip = $_SERVER['REMOTE_ADDR']; }
IIS + PHP
這種情況下直接使用$_SERVER['REMOTE_ADDR']
方法即可。
總結
無論是哪種情況,如果用戶使用匿名代理訪問服務器,只能獲取到代理服務器的IP地址,其IP地址仍然具有參考意義。
獲取客戶端真實IP地址,此事需要查閱相關資料根據(jù)具體情況選用某一個方法,而不是復制粘貼。
部分方法獲取到的值可能是一個數(shù)組。
不建議對獲取到的IP地址進行正則過濾,有可能你獲取到的是一個IPv6地址。
以上就是PHP 獲取客戶端真實IP地址的詳細內(nèi)容,更多關于PHP 獲取客戶端真實IP地址的資料請關注腳本之家其它相關文章!
相關文章
laravel使用Faker數(shù)據(jù)填充的實現(xiàn)方法
這篇文章主要給大家介紹了關于laravel使用Faker數(shù)據(jù)填充的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用laravel具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-04-04Laravel框架中VerifyCsrfToken報錯問題的解決
這篇文章主要給大家介紹了關于Laravel框架中VerifyCsrfToken報錯問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習,需要的朋友們下面跟著小編來一起學習學習吧。2017-08-08thinkphp數(shù)據(jù)查詢和遍歷數(shù)組實例
這篇文章主要介紹了thinkphp數(shù)據(jù)查詢和遍歷數(shù)組的方法,包括數(shù)據(jù)庫的DSN方法配置、CURD操作方法以及模板的遍歷數(shù)組等技巧,具有一定的借鑒價值,需要的朋友可以參考下2014-11-11