在統計訪問日志參數的時候IP是一個重要的參數,所有索取客戶端的IP就至關重要。 在logformat配置中有兩個變量是獲取IP地址的: remoteaddr:客戶端IP xforwardedfor:客戶端的IP
從上面來看兩個都是客戶端IP,那這兩個變量有什么不同?
首先當你訪問某個網站,假設你中間不經過任何代理,那么webserver就會把remoteaddr當成你客戶端的IP,但是你使用代理了或者服務端有代理的情況下webserver獲取的remoteaddr就不準確了,這時候就需要另一個變量xforwardedfor,他把客戶端的IP加到http頭里,這樣就能獲取到客戶端的真是IP了。
下面我們看一下配置信息:
log_format main '$http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" "$upstream_addr" "$request_time"';
我們來介紹一下各個變量的意思:
$remote_addr, $http_x_forwarded_for 記錄客戶端IP地址 $time_local 通用日志格式下的本地時間。 $request 記錄請求的URL和HTTP協議 $status 記錄請求狀態 $bytes_sent 發送給客戶端的總字節數。 $http_referer 記錄從哪個頁面鏈接訪問過來的 $http_user_agent 記錄客戶端瀏覽器相關信息 $upstream_addr 后臺upstream的地址,即真正提供服務的主機地址 $request_time 整個請求的總時間
下面我們在看一下具體的日志:
115.45.71.215 - - [21/Dec/2015:00:01:34 +0800] "GET /bbs/sidebar/Sidebar.php?t=1450627317853&callback=Cal48995 HTTP/1.1" 200 313 "http://www.xxxx.com.cn/bbs/viewthread.php?tid=25687628&page=2" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "127.0.0.1:9000" "0.002" 221.222.123.63 - - [21/Dec/2015:00:01:34 +0800] "GET /bbs/sidebar/Sidebar.php?action=pserid&fid=91&callback=Cal38263 HTTP/1.1" 200 332 "http://www.xxxx.com.cn/bbs/viewthread.php?tid=25655586&page=5" "Mozilla/5.0 (iPad; CPU OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/6.0 MQQBrowser/4.9.3 Mobile/12H143 Safari/7534.48.3" "127.0.0.1:9000" "0.004"
通過上面的兩條日志我們能看到很多信息。
但是你使用CDN之后還是這個樣子嗎?
在上周的時候我的開發小伙伴找我說他看不到用戶的真是的IP,用戶所有的IP都成了一個了,,聽到這個消息我也是驚呆了,去看了一下才確定是xforwardedfor出問題了
原因是我們使用了藍訊的CDN。。。。下面介紹一下原因
在使用了CDN加速后,用戶會先訪問CDN,如果CDN沒有,則回源站(即你的反向代理)取數據(我們的代理是nginx做的后端還有一個netscaler)。CDN在回源站時,會先添加xforwardedfor頭信息,保存用戶的真實IP,而反向代理也會設定這個值,不過它不會覆蓋,而是把CDN服務器的IP(即當前remoteaddr)添加到xforwardedfor的后面,這樣xforwarded_for里就會保存兩個值。Nginx會使用這些值里的第一個,即客戶的真實IP,而PHP則會使用第二個,即CDN的地址,也就是開發小伙伴說的所有的用戶都是一個IP的那個值。
那怎么能讓PHP也使用第一個值? 在fastcgiparams的配置里添加 fastcgiparam HTTPXFORWARDEDFOR $httpxforwardedfor; 它會把nginx使用的值(即第一個IP)傳給PHP,這樣PHP拿到的xforwardedfor里其實就只有一個值了,也就不會用第二個CDN的IP了。
fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200; #fastcgi_param hessian_domain "http://172.16.112.212"; #fastcgi_param des_token "sddsdreuiowerfnddnfadskljdkljfalfdsjfdasl"; #fastcgi_param cook_hashkey "sdhkdssddsjewiojjssd";
好了,現在拍黃片的小伙伴就可以獲取用戶的真是IP了。
原創文章,作者:可樂,如若轉載,請注明出處:http://www.www58058.com/10324