Nginx的rewrite模塊疑問排查

標題索引


  • 追溯原因

  • 實驗分析

  • 原理總結


追蹤原因

    最近心態"一步一印,有印爲證",在Nginx的rewrite模塊在工作過程中,客戶端發起包到服務器解包整體過程瀏覽器做了什麼?服務器做了什麼?到底是服務器端接收請求匹配跳轉條件後先執行跳轉並將執行結果反饋給客戶端呢?還是服務器端接收到請求後先反饋給客戶端跳轉後的路徑,然後客戶端再次重新發起請求,服務器端再次接收請求並執行請求,最後將執行結果反饋給客戶端?爲此決定抓包分析一探究竟。

過程分析

    爲驗證此做四個實驗,第一個實驗利用rewrite指令進行永久性重定向,抓包分析過程及內容,第二個實驗利用rewrite指令臨時重定向redirect,抓包分析過程及內容,第三個實驗利用rewrite指令後續跟last選項,抓包分析過程及內容,第四個實驗利用rewrite指令做http跳轉https,,然後分析過程及內容,最後總結rewrite工作原理及過程。

    實驗環境:一臺虛擬服務器、一臺普通PC機,虛擬服務器做Nginx服務器,PC機做測試,具體拓撲如下:

e8faf043036a7449f174c20decccfa3b.png

圖1-1 測試環境拓撲圖   

 


   實驗一:服務器rewrite參數配置爲永久性重定向,具體配置如下

[ root@nginxagent conf.d ]#pwd
/etc/nginx/conf.d
[ root@nginxagent conf.d ]mkdir /app/website01/jn
[ root@nginxagent conf.d ]mkdir /app/website01/jncsy
[ root@nginxagent conf.d ]echo jn >/app/website01/jn
[ root@nginxagent conf.d ]echo jncshy >/app/website01/jncsy
[ root@nginxagent conf.d ]#vim virtual.conf
 #server test
 server {
     listen 80;
     index index.html;
     server_name 
      root /app/website01/;
     location /zz {
         rewrite ^/jn/(.*)$ /jncsy/$1 permanent;
     }
 }

     Client客戶端通過瀏覽器訪問www.a.com,IP地址即172.18.27.22,同時在客戶端利用Wireshark抓包分析如圖:

ee795fcea2281ca441edd86c03d58492.png

圖1-2 永久性重定抓包分析圖

    由上圖可知,在客戶端第一次發起請求http://www.a.com/jn/到達服務器後,服務器對迴應301永久性重定向返回新的地址鏈接,第二次重新發起新的地址請求後,重新獲取數據。


    實驗二:服務器rewrite參數配置爲last時,具體如下

[ root@nginxagent conf.d ]#vim virtual.conf
 #server test
 server {
     listen 80;
     index index.html;
     server_name www.a.com;
      root /app/website01/;
     location /zz {
         rewrite ^/jn/(.*)$ /jncsy/$1 last;
     }
 }

    Client客戶端通過瀏覽器訪問www.a.com,IP地址即172.18.27.22,同時在客戶端利用Wireshark抓包分析如圖:

1-3 last重定向工作抓包分析圖

    當服務器第一次發起請求時,通過http://www.a.com/jn/,請求到達服務器後,服務器內部根據跳轉規則直接進行跳轉,並將跳轉後的最終結果數據反饋給客戶端,客戶端無需進行第二次請求。


    實驗三:服務器rewrite參數配置爲redirect時,具體如下

[ root@nginxagent conf.d ]#vim virtual.conf
 #server test
 server {
     listen 80;
     index index.html;
     server_name www.a.com;
      root /app/website01/;
     location /zz {
         rewrite ^/jn/(.*)$ /jncsy/$1 redirect;
     }
 }

    Client客戶端通過瀏覽器訪問www.a.com,IP地址即172.18.27.22,同時在客戶端利用Wireshark抓包分析如圖:

9c49561e4eb77f20c199edf02d118967.jpg

圖1-4 臨時重定向工作抓包分析圖

    由上圖可知,在客戶端第一次發起請求http://www.a.com/jn/到達服務器後,服務器對迴應302臨時重定向返回新的地址鏈接,第二次重新發起新的地址請求後,重新獲取數據。


    實驗四:當服務器配置https,由http跳轉至https時,且重定向爲redirect,實驗如下:

[ root@nginxagent ~ ]#mkdir /etc/nginx/ssl
#----------------------------------生成自簽名祕鑰和證書------------
[ root@nginxagent ~ ]#cd /etc/pki/tls/certs
[ root@nginxser01 certs ]#make nginx.crt
umask 77 ; \
/usr/bin/openssl genrsa -aes128 2048 > nginx.key
Generating RSA private key, 2048 bit long modulus
.........+++
.........................................+++
e is 65537 (0x10001)
Enter pass phrase: #創建私鑰,並輸入密碼#
Verifying - Enter pass phrase: #確認密碼#
umask 77 ; \
/usr/bin/openssl req -utf8 -new -key nginx.key -x509 -days 365 -out nginx.crt -set_serial 0
Enter pass phrase for nginx.key: #利用私鑰生成證書,輸入私鑰密碼#
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SHANXI
Locality Name (eg, city) [Default City]:XI'AN  
Organization Name (eg, company) [Default Company Ltd]:JNCSY
Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's hostname) []:www.a.com
Email Address []:
#-------------------------驗證生成的證書和祕鑰------------------------------
[ root@nginxser01 certs ]#ll ngi*
-rw------- 1 root root 1289 Oct 28 06:47 nginx.crt
-rw------- 1 root root 1766 Oct 28 06:43 nginx.key
#-------------------------避免每次調用私鑰進行輸入密碼驗證進行解密-----------
[ root@nginxser01 certs ]#openssl rsa -in nginx.key -out nginx.key
Enter pass phrase for nginx.key:
writing RSA key
[ root@nginxser01 certs ]#cp ngi* /etc/nginx/ssl
[ root@nginxagent conf.d ]#vim virtual.conf
 #server test
 server {
     listen 80;
     index index.html;
     server_name www.a.com;
     root /app/website01/;
     location / {
          rewrite ^/(.*)$  https://172.18.27.22/$1 redirect;
          }
 server {
     listen 443 ssl;
     server_name www.a.com;
     index index.html;
     root /app/website01/;
     ssl on;
     ssl_certificate /etc/nginx/ssl/nginx.crt;
     ssl_certificate_key /etc/nginx/ssl/nginx.key;
     ssl_session_cache builtin:1000 shared:SSL:20m;
     ssl_session_timeout 10m;
     }

    Client客戶端通過瀏覽器訪問www.a.com,IP地址即172.18.27.22,同時在客戶端利用Wireshark抓包分析如圖:

af470a63bf07291117261d63864a8ff5.jpg

圖1-5 http跳轉https工作抓包分析圖

    由上圖可知,在客戶端第一次發起請求http://www.a.com/jn/到達服務器後,服務器對迴應302臨時重定向返回新的地址https://www.a.com/jn/,第二次重新發起新的地址請求後,重新獲取數據。


總結對比

    由此實驗總結得知:在臨時重定向和永久重定向中,服務器端返回給客戶端新的鏈接,客戶端根據服務器端返回的新連接重新發起請求。而rewrite模塊的last參數則較爲特殊,服務器收到請求後在內部跳轉並將跳轉執行後的結果直接一次性返回客戶端。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章