nginx獲取客戶端真實ip
https://blog.csdn.net/diyiday/article/details/80827437
https://www.qiansw.com/f5-nginx-proxy-user-ip.html
https://www.cnblogs.com/edward2013/p/5501258.html
https://help.aliyun.com/knowledge_detail/40535.html?spm=5176.2000002.0.0.57554e22UWKxxO
很多時候做用戶分析的時候需要客戶端真實IP地址,尤其是運營或者日志分析,但很多線上環境呢,都是自建IDC或者雲平台。獲取客戶端真實IP,首先要考慮的是網絡環境,例如阿里雲就要在slb開啟X-Forwareded-For,自建IDC的F5這種網絡設備也要開啟AutoMap,並傳遞X-Forwarded-For值,把真實IP透傳下去,Nginx這種web服務器才能獲取到,建議Nginx做7層轉發,這樣子分析Nginx日志比tomcat、Apache、PHP要方便。
F5
一、登陸F5后選擇logical traffic ->profiles->services->http選項
二、在該選項中的service選項卡內點擊create按鈕創建一個http_profile並設置其中的Insert X-Forwarded-For項值為enable
三、在local traffic選項卡中設置點擊virtual server后點擊其中的web虛擬服務器
四、進入該web虛擬server的property選項卡內將type修改成支持7層負載協議即standard並在http profile參數設置選擇你剛剛添加的http_profile
五、最后點擊update按鈕配置生效
方式二:在iRule中開啟X-Forwarded-For
when HTTP_REQUEST {
HTTP::header insert "X-Forwarded-For" [IP::client_addr]
}
阿里雲SLB
四層接入(非網站防護)
按照以下不同的部署配置場景,選擇適合您的源站獲取客戶端IP方式。
- 高防 > 阿里雲ECS
通過TCP端口轉發流量的情況,您無需做任何改動。源站服務器上看到的客戶端IP就是真實的客戶端IP。同時,ECS的安全組配置對象也可以針對真實的客戶端IP進行設置。
說明 如使用UDP端口轉發,源站ECS將無法獲取真實客戶端IP。
- 高防 > SLB > ECS
默認支持獲取客戶端真實IP。
通過TCP端口轉發流量的情況,您無需做任何改動。源站服務器上看到的客戶端IP就是真實的客戶端IP。
七層接入(網站防護)
當一個七層代理服務器(如高防IP)把用戶的訪問請求轉到后端服務器時,源站默認看到的是這個七層代理服務器(如高防IP)的回源IP。而真實的客戶端IP會被七層代理服務器放在HTTP頭部的X-Forwareded-For字段,格式如下:X-Forwarded-For:
用戶真實
IP,
高防代理
IP
。
如果中間經過不止一個代理服務器(如經過了WAF、CDN等等代理服務器),此時HTTP頭部的X-Forwarded-For字段的格式如下:X-Forwarded-For:
用戶真實
IP,
代理服務器
1-IP,
代理服務器
2-IP,
代理服務器
3-IP, …
。
經過多層代理服務器,請求用戶的真實IP處於第一個位置,而后面包含所有經過的中間代理服務器的IP。因此,只要獲取HTTP頭部的X-Forwarded-For字段的內容即可。
Nginx獲取真實IP方法
l 確認 http_realip_module 模塊已安裝。Nginx作為負載均衡獲取真實IP是使用http_realip_module模塊。
說明 通過一鍵安裝包安裝的Nginx默認不安裝此模塊,可以使用 # nginx -V | grep http_realip_module
查看此模塊有無安裝。
如果 http_realip_module 模塊未安裝,需要重新編譯Nginx並加裝此模塊。
--user=admin --group=admin --prefix=/home/admin/webserver --with-http_concat_module --with-http_realip_module --with-http_addition_module --with-http_gzip_static_module --with-http_random_index_module --with-http_stub_status_module --with-http_sub_module --with-http_ssl_module --with-http_flv_module --with-http_sysguard_module --with-http_upstream_check_module --with-http_secure_link_module --with-http_degradation_module --with-http_xslt_module --with-http_v2_module --with-http_image_filter_module --with-http_dyups_module --with-http_dav_module --with-debug --add-module=/home/admin/soft/nginx_install/ngx_devel_kit/ --add-module=/home/admin/soft/nginx_install/lua-nginx-module
作為代理服務器
l 修改Nginx對應server的配置。 在location / {}
中添加以下內容。
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
作為web服務器
location / { set_real_ip_from 10.6.76.27; real_ip_header X-Forwarded-For; real_ip_recursive on; }
如果是阿里雲ecs
set_real_ip_from ip_range1;
set_real_ip_from ip_range2;
...
set_real_ip_from ip_rangex;
real_ip_header X-Forwarded-For;
這里的 ip_range1,2,...
指的是高防IP的回源IP地址,需要添加多條。如果高防IP后還有WAF、CDN,則需要寫WAF、CDN的回源IP地址,即需要寫離源站最近的一層七層代理的回源IP段。
修改日志記錄格式
log_format。log_format一般在nginx.conf中的HTTP配置中:
log_format json '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $request_time $http_x_forwarded_for ' ;
代理服務器日志
1.81.84.185 - - [25/Jul/2019:12:09:33 +0800] "GET /poweredby.png HTTP/1.1" 304 0 "http://test.corp.XXX.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:68.0) Gecko/20100101 Firefox/68.0" 0.001 1.81.84.185
web服務器日志
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
1.81.84.185 - - [25/Jul/2019:12:09:33 +0800] "GET /poweredby.png HTTP/1.1" 304 0 "http://test.corp.zhaonongzi.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:68.0) Gecko/20100101 Firefox/68.0" "1.81.84.185, 1.81.84.185"
可以看出來,通過這樣子設置,remote_addr就是我們的真實IP地址
json方式
log_format json '{"@timestamp":"$time_iso8601",' '"host":"$server_addr",' '"request_method": "$request_method", ' '"clientip":"$remote_addr",' '"size":$body_bytes_sent,' '"responsetime":$request_time,' '"upstreamtime":"$upstream_response_time",' '"upstreamhost":"$upstream_addr",' '"http_host":"$host",' '"url":"$uri",' '"xff":"$http_x_forwarded_for",' '"referer":"$http_referer",' '"agent":"$http_user_agent",' '"status":"$status"}';
{"@timestamp":"2019-07-25T10:31:15+08:00","host":"10.6.76.27","request_method": "GET", "clientip":"1.80.80.50","size":798,"responsetime":0.010,"upstreamtime":"0.010","upstreamhost":"10.6.76.27:5601","http_host":"kibana.corp.zhaonongzi.com","url":"/api/saved_objects/_find","xff":"1.80.80.50","referer":"http://kibana.corp.zhaonongzi.com/app/kibana","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:68.0) Gecko/20100101 Firefox/68.0","status":"200"}
Apache獲取訪客真實IP的解決方案
您可以通過安裝Apache的mod_rpaf第三方模塊,獲取訪問者真實IP地址。
- 執行以下命令,安裝mod_rpaf模塊。
wget http:
//stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gztar zxvf mod_rpaf-
0.6.tar.gzcd mod_rpaf-
0.6;/alidata/server/httpd/bin/apxs -
i-c -n mod_rpaf-
2.0.somod_rpaf-
2.0.c
- 修改Apache配置文件/alidata/server/httpd/conf/httpd.conf,在文件最后添加以下內容:
說明 其中, RPAFproxy_ips ip
地址
不是負載均衡提供的公網IP。具體IP可參考Apache的日志,通常會有兩個IP地址。
LoadModule rpaf_module modules/mod_rpaf-2.0.so RPAFenable On RPAFsethostname On RPAFproxy_ips ip地址 RPAFheader X-Forwarded-For
- 添加完成后,執行以下命令重啟Apache服務,使配置生效。
/alidata/server
/httpd/bin
/apachectl restart
mod_rpaf模塊配置示例
LoadModule rpaf_module modules/mod_rpaf-2.0.so RPAFenable On RPAFsethostname On RPAFproxy_ips 10.242.230.65 10.242.230.131 RPAFheader X-Forwarded-For
httpd.conf添加%{X-Forwarded-For}i(推薦)
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{X-Forwarded-For}i" combined
Tomcat獲取訪客真實IP的解決方案
開啟 Tomcat 的 X-Forwarded-For 功能可獲取客戶端真實IP。
在 tomcat/conf/server.xml 文件中,修改 AccessLogValve 日志記錄功能:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%{X-FORWARDED-FOR}i %l %u %t %r %s %b %D %q %{User-Agent}i %T" resolveHosts="false"/>
在PHP中獲取X-Forwarded-For的值
<?php $headers = apache_request_headers(); $real_client_ip = $headers["X-Forwarded-For"]; echo "Your IP: ",$real_client_ip; ?>