nginx之線上CDN的rewrite規則修改

線上的CDN廠商的nginx的rewrite規則配置驗證
環境介紹:
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

nginx服務是編譯安裝:

yum install -y gcc gcc-c++ make \
openssl-devel pcre-devel gd-devel libxslt-devel \
iproute net-tools telnet wget curl && \
yum clean all && \
rm -rf /var/cache/yum/*
wget http://nginx.org/download/nginx-1.12.2.tar.gz && \
tar zxf nginx-1.12.2.tar.gz && \
cd nginx-1.12.2 && \
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-stream \
--with-stream_ssl_module && \
make -j 4 && make install && \
mkdir -p /usr/local/nginx/conf/vhost && \
rm -rf /usr/local/nginx/html/* && \
echo "ok" >> /usr/local/nginx/html/status.html

[root@localhost ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.12.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-stream --with-stream_ssl_module
[root@localhost ~]# 

驗證測試:
爲使nginx vhost虛擬主機配置文件更簡潔,所以採用include方式,把nginx的rewrite規則寫到一個單獨的配置文件中

[root@test01 vhost]# grep include /usr/local/nginx/conf/vhost/img.test.conf 
   include /data/www/images/.htaccess; 

下面的rewrite規則是雲端CDN的提供的配置規則,但是其中3條規則存在問題

[root@test01 03]# cat /data/www/images/.htaccess
rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+).gjf$ /uploads/picture/2016/$1/$2/$3.gif last;
rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+)(png|jpeg|jpg|gif)$ /uploads/picture/2016/$1/$2/$3.$4 last;
rewrite "^/.{6}[0-9]+/([0-9]{2})([0-9]{2})/(.*)$" /uploads/picture/2016/$1/$2/$3 ;
rewrite "^/.{6}[0-9]{4}/(.*)$" /uploads/picture/2016/$1 last;
rewrite "^/.{6}[0-9]{4}[0-9]{8}/(.*)$" /uploads/picture/$1 last; (此規則雲端CDN配置有問題,位置應該放到第一的位置就可以了)
rewrite ^/[0-9]+\.([0-9]+)\.([0-9]+)\.([0-9]+)\.(.*)$ /uploads/picture/$1/$2/$3/$4 last; (此規則雲端CDN配置有問題,點號不需要轉譯的)
rewrite ^/[0-9]+/([0-9][0-9])([0-9][0-9])/(.*)$ /uploads/picture/2016/$1/$2/$3 last;(此規則放到最後不合理,應該放到第三條規則的前面)

本人親自測試最合理的配置文件的規則如下:

[root@test01 ~]# cat /data/www/images/.htaccess 
#rewrite ^/[a-zA-Z0-9]+/(.*)$ /uploads/picture/$1 last;
rewrite "^/.{6}[0-9]{4}[0-9]{8}/(.*)$" /uploads/picture/$1 last;
rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+).gjf$ /uploads/picture/2016/$1/$2/$3.gif last;
rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+)(png|jpeg|jpg|gif)$ /uploads/picture/2016/$1/$2/$3.$4 last;

rewrite ^/[0-9]+/([0-9][0-9])([0-9][0-9])/(.*)$ /uploads/picture/2016/$1/$2/$3 last;
rewrite "^/.{6}[0-9]+/([0-9]{2})([0-9]{2})/(.*)$" /uploads/picture/2016/$1/$2/$3 ;
rewrite "^/.{6}[0-9]{4}/(.*)$" /uploads/picture/2016/$1 last;
rewrite ^/[a-zA-Z0-9]+.([0-9]+).([0-9]+).([0-9]+).(.*)$ /uploads/picture/$1/$2/$3/$4 last;

*基於CDN提供的原nginx rewrite規則順序逐一進行實例演示:**

規則1

rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+).gjf$ /uploads/picture/2016/$1/$2/$3.gif last;

說明:

/[a-zA-Z0-9]+/:匹配到任意的字符串;
$1指的是第一個圓括號([0-9][0-9]) 中的2位數;
$2指的是第二個圓括號([0-9][0-9]) 中的2位數;
$3指的是第三個圓括號([0-9]+)中的任意數字;([0-9]+).gjf:匹配到以gjf結尾的文件跳轉到請求服務器上的([0-9]+).gif文件【注意:服務器上的([0-9]+).gif這個圖片文件是必須存在的】

正常的瀏覽器訪問:

http://img.test.com/uploads/picture/2016/08/03/1501742944.gif
http://img.test.com/uploads/picture/2016/08/03/1501742944.gif?base6412345
http://img.test.com/uploads/picture/2016/08/03/1501742944.gif???dwer

通過匹配到rewrite規則 瀏覽器訪問:

http://img.test.com/awe21/0803/1501742944.gjf
http://img.test.com/22KDJH21/0803/1501742944.gjf??base64

服務器上文件的位置:

[root@test01 03]# ll /data/www/images/uploads/picture/2016/08/03/1501742944.gif
-rw-r--r--. 1 root root 184440 Aug  3  2017 /data/www/images/uploads/picture/2016/08/03/1501742944.gif

規則2:

rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+)(png|jpeg|jpg|gif)$ /uploads/picture/2016/$1/$2/$3.$4 last;

說明:

/[a-zA-Z0-9]+/:匹配到任意的字符串;
$1指的是第一個圓括號([0-9][0-9]) 中的2位數;
$2指的是第二個圓括號([0-9][0-9]) 中的2位數;
$3指的是第三個圓括號([0-9]+)中的任意數字【注意:這些數字必須是服務器上存在的並且以png|jpeg|jpg|gif結尾文件的前面的數字】;
$4指的是第四個括號(png|jpeg|jpg|gif)中的服務器上必須存在的以png|jpeg|jpg|gif結尾的文件

實例演示:

http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg
http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg??base64
http://img.test.com/aA01/0728/1469696883jpeg??base64
http://img.test.com/1/0728/1469696883jpeg
http://img.test.com/34chk/0728/1469696883jpeg
http://img.test.com/chkDHK/0728/1469696883jpeg
http://img.test.com/chkDHK123654/0728/1469696883jpeg?2345

規則3:

rewrite "^/.{6}[0-9]+/([0-9]{2})([0-9]{2})/(.*)$" /uploads/picture/2016/$1/$2/$3 ;

說明:

^/.{6}[0-9]+/:匹配到任意6個字符串加任意數字;
$1指的是第一個圓括號([0-9]{2}) 中的2位數;
$2指的是第二個圓括號([0-9]{2}) 中的2位數;
$3指的是第三個圓括號(.*)中的任意字符串。當然$1,$2,$3這些字符串必須是服務器上實實在在存在的字符串,只有這樣在瀏覽器請求時,才能獲取到服務器上的圖片

實例演示:
http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg
http://img.test.com/cHrtwK123/0728/1469696883.jpeg
http://img.test.com/cHrtwK1234/0728/1469696883.jpeg
http://img.test.com/cHrtwK4/0728/1469696883.jpeg??base64

規則4:

rewrite "^/.{6}[0-9]{4}/(.*)$" /uploads/picture/2016/$1 last;

說明:

^/.{6}[0-9]{4}:匹配到任意6個字符串加任意4個數字

實例演示:


http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg
http://img.test.com/cHrtwK4123/07/28/1469696883.jpeg
http://img.test.com/cH23wK4155/07/28/1469696883.jpeg

以下這樣的是不符合規則的,所以找不到文件

http://img.test.com/cH23wK41/07/28/1469696883.jpeg

規則5:

rewrite "^/.{6}[0-9]{4}[0-9]{8}/(.*)$" /uploads/picture/$1 last;

說明:

^/.{6}[0-9]{4}[0-9]{8} :匹配到任意6個字符串加任意4個數字再加8個任意的數字

實例演示:

http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg

經測試,此rewrite規則放到此位置,是匹配不到圖片的,所以位置得變動下,把此規則放到規則的首位就可以了

http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg
http://img.test.com/weijdg444433336666/2016/07/28/1469696883.jpeg

規則6:

rewrite ^/[a-zA-Z0-9]+.([0-9]+).([0-9]+).([0-9]+).(.*)$ /uploads/picture/$1/$2/$3/$4 last;

注意:此處的點號是不需要轉譯的,轉譯會導致rewrite規則不可用,就如下面的這條rewrite規則是不正確的

rewrite ^/[0-9]+\.([0-9]+)\.([0-9]+)\.([0-9]+)\.(.*)$ /uploads/picture/$1/$2/$3/$4 last;

實例演示:

下面的請求是可以打開的
http://img.test.com/SHDw.2017.11.26.1520924032.png
http://img.test.com/1wer1.2016.07.28.1469696883.jpeg
http://img.test.com/SHDw.2018.08.18.1489719802.png?base64

http://img.test.com/1wer1.2016.07.28/1520924032.png
http://img.test.com/SHDw.2018.08.18/1489719802.png?base64
http://img.test.com/SHDw.2017.11.26/1520924032.png

規則7:

rewrite ^/[0-9]+/([0-9][0-9])([0-9][0-9])/(.*)$ /uploads/picture/2016/$1/$2/$3 last;

實例演示:
下面的請求是打不開的
http://img.test.com/1345/0728/1469696883.jpeg
http://img.test.com/1232345/0803/1661442694.jpg
http://img.test.com/66/0803/1661442694.jpg

*於是把第七條規則放到第四條規則:rewrite "^/.{6}[0-9]+/([0-9]{2})([0-9]{2})/(.)$" /uploads/picture/2016/$1/$2/$3 ; 前面進行
測試**
下面的請求都是可以打開的

http://img.test.com/1345/0728/1469696883.jpeg
http://img.test.com/1232345/0803/1661442694.jpg
http://img.test.com/66/0803/1661442694.jpg

規則八:
讓我們繼續看下本人親自測試的文件:

[root@test01 ~]# cat /data/www/images/.htaccess 
#rewrite ^/[a-zA-Z0-9]+/(.*)$ /uploads/picture/$1 last;
rewrite "^/.{6}[0-9]{4}[0-9]{8}/(.*)$" /uploads/picture/$1 last;
rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+).gjf$ /uploads/picture/2016/$1/$2/$3.gif last;
rewrite ^/[a-zA-Z0-9]+/([0-9][0-9])([0-9][0-9])/([0-9]+)(png|jpeg|jpg|gif)$ /uploads/picture/2016/$1/$2/$3.$4 last;

rewrite ^/[0-9]+/([0-9][0-9])([0-9][0-9])/(.*)$ /uploads/picture/2016/$1/$2/$3 last;
rewrite "^/.{6}[0-9]+/([0-9]{2})([0-9]{2})/(.*)$" /uploads/picture/2016/$1/$2/$3 ;
rewrite "^/.{6}[0-9]{4}/(.*)$" /uploads/picture/2016/$1 last;
rewrite ^/[a-zA-Z0-9]+.([0-9]+).([0-9]+).([0-9]+).(.*)$ /uploads/picture/$1/$2/$3/$4 last;

如果把#rewrite ^/[a-zA-Z0-9]+/(.*)$ /uploads/picture/$1 last; 註釋掉的規則放到第一條規則後面的任意位置進行測試

不顯示文件:
http://img.test.com/qwerty1/2016/07/28/1469696883.jpeg
http://img.test.com/qwerty123/2016/07/28/1469696883.jpeg
http://img.test.com/qy123/2016/07/28/1469696883.jpeg
可以顯示文件:
http://img.test.com/qwerty444455556666/2016/07/28/1469696883.jpeg

*於是乾脆去掉註釋放到第一條規則rewrite "^/.{6}[0-9]{4}[0-9]{8}/(.)$" /uploads/picture/$1 last;的前面進行測試:**

以下鏈接都可以正常的顯示圖片了:

http://img.test.com/qwerty1/2016/07/28/1469696883.jpeg
http://img.test.com/qwerty123/2016/07/28/1469696883.jpeg
http://img.test.com/qy123/2016/07/28/1469696883.jpeg
http://img.test.com/qwerty444455556666/2016/07/28/1469696883.jpeg

但是接着有發現:

http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg
http://img.test.com/uploads/picture/2018/08/18/1489719802.png
http://img.test.com/uploads/picture/2017/11/26/1520924032.png

相對路徑的訪問請求此時卻打不開了,報錯404,於是嘗試把此規則放到其他規則的後i面進行測試,發現相對路徑的訪問請求都是不好使的。
於是註銷掉此規則,下面的相對路勁的訪問鏈接是又可以打開了

http://img.test.com/uploads/picture/2016/07/28/1469696883.jpeg
http://img.test.com/uploads/picture/2018/08/18/1489719802.png
http://img.test.com/uploads/picture/2017/11/26/1520924032.png

總結:
Apache和nginx的rewrite規則的匹配是有順序的,而且是從上往下依次匹配的。如果上面優先被匹配到就不再匹配下面的規則。

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