win10客戶端請求web服務,win10的ip:192.168.223.1
nginx作為反向代理伺服器:192.168.223.136
nginx作為後端web伺服器:192.168.223.137
前提條件:配置nginx轉發到後端伺服器
server {
listen 8080;
server_name 192.168.223.136;
location / {
root "/www/html";
index index.html;
#auth_basic "required auth";
#auth_basic_user_file "/usr/local/nginx/users/.htpasswd";
error_page 404 /404.html;
}
location /images/ {
root "/www";
rewrite ^/images/bbs/(.*\.jpeg)$ /images/$1 break;
rewrite ^/images/www/(.*)$ http://192.168.223.136/$1 redirect;
}
location /basic_status {
stub_status;
}
location ^~/proxy_path/ {
root "/www/html";
index index.html;
proxy_pass http://192.168.223.137/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
location ^~/proxy_path/ {
root "/www/html";
index index.html;
proxy_pass http://192.168.223.137/;
將左側匹配到的/proxy_path/開頭的url全部轉發到後端伺服器192.168.223.137
現在一一測試各個proxy_set_header設定的變數的內容
1、proxy_set_header Host $host;
將136代理伺服器,137後端伺服器的log_format修改為如下:
然後開啟137後端nginx,檢視日誌:
192.168.223.136 "192.168.223.1" - - [17/Jul/2017:17:06:44 +0800] "GET /index.html HTTP/1.0" "192.168.223.136" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" "192.168.223.1"
即驗證了proxy_set_header Host $host; $host就是nginx代理伺服器,也就是win10客戶端請求的host
2、proxy_set_header Host $proxy_host;
將設定修改為上述proxy_host然後重啟ngxin代理伺服器136
[root@wadeson nginx]# sbin/nginx -s reload
重新請求代理頁面:http://192.168.223.136:8080/proxy_path/index.html,然後日誌如下:
首先檢視136代理伺服器的日誌:
192.168.223.1 - - [18/Jul/2017:10:30:12 +0800] "GET /proxy_path/index.html HTTP/1.1" 192.168.223.136:8080 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
因為win10是136的客戶端,請求的host為192.168.223.136:8080,而nginx代理伺服器作為137後端伺服器的客戶端,將請求的報文首部重新封裝,將proxy_host封裝為請求的host
那麼137上面日誌請求的host就是其自身,proxy_host就是代理伺服器請求的host也就是後端伺服器137
192.168.223.136 "192.168.223.1" - - [18/Jul/2017:10:30:12 +0800] "GET /index.html HTTP/1.0" "192.168.223.137" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "192.168.223.1"
3、proxy_set_header Host $host:$proxy_port;
瞭解了上面的知識,那麼此處對應的host就知道代表的啥了,$host代表轉發伺服器,$proxy_port代表136轉發伺服器請求後端伺服器的埠,也就是80
於是觀察136、137的日誌進行驗證:
192.168.223.1 - - [18/Jul/2017:10:38:38 +0800] "GET /proxy_path/index.html HTTP/1.1" 192.168.223.136:8080 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
192.168.223.136 "192.168.223.1" - - [18/Jul/2017:10:38:38 +0800] "GET /index.html HTTP/1.0" "192.168.223.136:80" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "192.168.223.1"
4、proxy_set_header X-Real-IP $remote_addr;
將$remote_addr的值放進變數X-Real-IP中,此變數名可變,$remote_addr的值為客戶端的ip
nginx轉發136伺服器日誌格式為:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $http_host '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
nginx後端137伺服器的日誌格式:
log_format main '$remote_addr "$http_x_real_ip" - $remote_user [$time_local] "$request" "$http_host" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
兩者區別在於"$http_x_real_ip",新增了這個變數的值
重新請求需要訪問的地址http://192.168.223.136:8080/proxy_path/index.html
136的日誌:
192.168.223.1 - - [18/Jul/2017:10:45:07 +0800] "GET /proxy_path/index.html HTTP/1.1" 192.168.223.136:8080 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
137的日誌:
192.168.223.136 "192.168.223.1" - - [18/Jul/2017:10:45:07 +0800] "GET /index.html HTTP/1.0" "192.168.223.136:80" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "192.168.223.1"
紅色標記的就是"$http_x_real_ip"的值,即可以看見使用者真實的ip,也就是客戶端的真實ip
5、proxy_set_header X-Forwarded-For $remote_addr;
理解了上面的含義那麼這個封裝報文的意思也就請求了
首先還是比對136和137的日誌格式:
136代理伺服器的日誌格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $http_host '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
137後端伺服器的日誌格式:
log_format main '$remote_addr "$http_x_real_ip" - $remote_user [$time_local] "$request" "$http_host" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
重新請求需要訪問的地址http://192.168.223.136:8080/proxy_path/index.html
136的日誌顯示:
192.168.223.1 - - [18/Jul/2017:10:51:25 +0800] "GET /proxy_path/index.html HTTP/1.1" 192.168.223.136:8080 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-",最後一個欄位"$http_x_forwarded_for"對應的為空值
137的日誌顯示:
192.168.223.136 "192.168.223.1" - - [18/Jul/2017:10:51:25 +0800] "GET /index.html HTTP/1.0" "192.168.223.136:80" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "192.168.223.1"
可以看出137後端伺服器成功的顯示了真實客戶端的ip
6、proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
5、6兩者的區別:
在只有一個代理伺服器的轉發的情況下,兩者的效果貌似差不多,都可以真實的顯示出客戶端原始ip
但是區別在於: