Nginx配置指令location匹配符優(yōu)先級和安全問題
最近一直在做location 配置,遇到優(yōu)先級別問題(如果配置不當(dāng)可能存在安全隱患哦),以下是個人學(xué)習(xí)一點體會。
一、 location 的匹配符
1.等于匹配符:=
等于匹配符就是等號,特點可以概括為兩點:
精確匹配
不支持正則表達(dá)式
2.空匹配符
空匹配符的特點是:
匹配以指定模式開始的 URI
不支持正則表達(dá)式
3.正則匹配符:~
正則匹配符是可以使用正則表達(dá)式的匹配符。不過這里要強調(diào)的是,一般來說~是指:
區(qū)分大小寫的正則匹配
而~*表示:
不區(qū)分大小寫的正則匹配
但是對于一些對大小寫不敏感的操作系統(tǒng),這兩者沒有區(qū)別。另外一個就是^~,其表示以指定模式開始的正則匹配。
4.內(nèi)部訪問符:@
一般用于錯誤頁面等,這個暫不討論。
二、匹配符優(yōu)先級
1.=
2.空匹配符,滿足精確匹配時
3.^~
4.~或~*
5.空匹配符,滿足以指定模式開始時的匹配時
這樣說比較抽象,我們來看例子吧。
2.1 等于匹配符與精確匹配時的空匹配符
看下面的例子(用到我們此前一起完成的Hello World模塊):
location /poechant {
hello_world no1;
}
location = /poechant {
hello_world no2;
}
如果我們的請求是http://my.domian/poechant,則我們發(fā)現(xiàn)兩個location都與請求的 URI 匹配,這時根據(jù)我們的優(yōu)先級順序,第一個是精確匹配時的空匹配符,第二個是等于匹配符,所以第二個的優(yōu)先級高,也就是應(yīng)該輸出:
hello_world, no2
同時也說明 Nginx 的 locatoin 不是按照配置文件中的書寫順序來匹配的。
2.2 精確匹配時的空匹配符與正則匹配的^~
下面這個例子中,兩者開始都精確匹配了,連這個正則匹配都是精確匹配。
location ^~ ^/poechant$ {
hello_world no1;
}
location /poechant {
hello_world no2;
}
匹配哪一個?你測試一下,會得到:
hello_world, no2
與我們上面說的優(yōu)先級順序相吻合。
2.3 其他匹配優(yōu)先級比較的實例
略
三、實戰(zhàn)經(jīng)驗總結(jié)
1.location 匹配的優(yōu)先級(來自實踐總結(jié)中)
(location =) > (location 完整路徑 >) >(location ^~ 路徑) >(location ~* 正則) >(location 路徑)
只要匹配到,其它的都會忽略,然后返回到改匹配。
用以下例子來測試:
#1
location / {
return 500;
}
#2
location /a/ {
return 404;
}
#3
location ~* \.jpg$ {
return 403;
}
#4
location ^~ /a/ {
return 402;
}
#5
location /a/1.jpg {
return 401;
}
#6
location = /a/1.jpg {
return 400;
}
說明:測試的時候,先要將#2全部注釋掉,不然會認(rèn)為#2 與#4 完全一樣。會提示:重復(fù)配置,提示如下
D:\nginx-0.8.7>nginx -s reload
[emerg]: duplicate location "/a/" in D:\nginx-0.8.7/conf/nginx.conf:53
瀏覽測試:每次都是訪問:http://localhost:9999/a/1.jpg (在windows 安裝測試,然后端口是9999) 文件a/1.jpg 根本不存在。關(guān)鍵是測試看頁面返回情況。
a.用上面的配置請求后的結(jié)果
--------------------------------------------------------------------------------
nginx/0.8.7
從測試中可以看到,優(yōu)先級最高的是:= 號。 它會最先匹配到。
b.接下來我們 屏蔽掉 #6 如下:
# location = /a/1.jpg {
# return 400;
# }
然后重載配置:D:\nginx-0.8.7> nginx -s reload 并訪問:http://localhost:9999/a/1.jpg ,返回以下結(jié)果:
401 Authorization Required
--------------------------------------------------------------------------------
nginx/0.8.7
結(jié)論:從這個測試發(fā)現(xiàn),沒有“=”情況下,location 后面直接接完整路徑是優(yōu)先匹配。 通過測試發(fā)現(xiàn),如果將:location/a/1.jpg 改成:location /a/1\.jpg
會出現(xiàn)意外情況,直接出現(xiàn)是:return 402. 從這一點,可以推測到nginx 匹配優(yōu)先是:網(wǎng)站路徑,并且不帶正則表達(dá)式的優(yōu)先。
c.同理測試 屏蔽掉 #5 如下:注釋及重新加載同上.
訪問:http://localhost:9999/a/1.jpg 返回如下結(jié)果。
402 Payment Required
--------------------------------------------------------------------------------
nginx/0.8.7
結(jié)論:通過這個測試可以得出:location ^~ 優(yōu)先級 高于 location ~* 優(yōu)先級 ,其中:^~ 主要后面接路徑。
c.同理測試 屏蔽掉 #4 如下:注釋及重新加載同上.
訪問:http://localhost:9999/a/1.jpg 返回如下結(jié)果。
403 Forbidden
--------------------------------------------------------------------------------
nginx/0.8.7
結(jié)論:從以上比較得到,正則優(yōu)先 未帶任何匹配符的路徑匹配
d.同理測試 屏蔽掉 #3 如下:注釋及重新加載同上. 并且去掉#2 的注釋“#”
訪問:http://localhost:9999/a/1.jpg 返回如下結(jié)果。
--------------------------------------------------------------------------------
nginx/0.8.7
結(jié)論:比較有意思是:/a/ 與 / 應(yīng)該是 同種類型的匹配表達(dá)式, 可以從中得到,該匹配順序是,將路徑從右匹配, 可以推測形如逐個字符,那個先匹配到,就是那個優(yōu)先。 因此得到是:/a/ 優(yōu)先于 / .
以上測試,是我測試結(jié)果,優(yōu)先級別以以上規(guī)律。 在實際我們書寫中,經(jīng)常會犯錯誤。 還記得前段時間:80后安全團隊曝nginx漏洞 其實,個人認(rèn)為不能算是nginx 漏洞,只是,我們不了解nginx 配制規(guī)則,而出現(xiàn)一個配置上面致命漏洞而已。 其實,通過上面優(yōu)先級,我們在配置時候可能也一樣經(jīng)常犯一個致命錯誤。
#以下是隨便寫例子,個人可能各不相同
#假設(shè)站點在:/home/www/html/目錄下,所有的php 及上傳文件都在這個目錄下面。
location ~* \.php$ {
proxy_pass http://www.a.com;
}
location /upload/ {
alias /home/www/html/upload/;
}
而且,這個upload 目錄,是靜態(tài)目錄,我們想法是下面所有文件是不能夠執(zhí)行的,包括php文件。
如果有用戶訪問:http://www.a.com/upload/1.css , 會直接顯示該css, 但是,如果有用戶訪問:http://www.a.com/upload/1.php 類似文件,正如上面所說,實際匹配到:~* \.php$ 了。 upload 下面是執(zhí)行了。
從這個里面,我們發(fā)現(xiàn)一個問題,實際沒有達(dá)到我們要求。 靜態(tài)目錄下面的文件一樣執(zhí)行了。 這下比較麻煩了。 一旦出現(xiàn)個什么上存漏洞的,別人上存了一個php,我們還以為,我們配置是ok的。 覺得很安全,缺在不知不覺中被別人打開一扇門。
那么我們怎么樣修改呢?
location ~* \.php$ {
proxy_pass http://www.a.com;
}
location ^~ /upload/ {
alias /home/www/html/upload/;
}
對,就是必須用:"^~" ,這樣是不是就已經(jīng)安全了呢。 如果你再訪問下:http://www.a.com/upload/1.php 你會發(fā)現(xiàn),這段代碼源碼顯示出來了。 這個其實對于我們而言也是不想見到了。 一段顯示源碼,在各個搜索引擎,很容易通過所有特殊關(guān)鍵字,搜索到改文件的。
那么我們該怎么樣配置安全的上存目錄呢? 對,你想到了:限制允許的特殊文件類型。
location ~* \.php$ {
proxy_pass http://www.a.com;
}
location ^~ /upload/ {
if ($request_filename ! ~* \.(jpg|jpeg|gif|png|swf|zip|rar|txt)$) {
return 403;
}
alias /home/www/html/upload/;
}
只要不是滿足上面擴展名文件,就自動提示:403 不能訪問,有可以避免源代碼顯示。
剛才從匹配結(jié)果已經(jīng)知道了,同級不帶任何匹配符的,是以右為準(zhǔn)匹配。 那么,如果都用正則表達(dá)式,以什么方式匹配呢?
測試如下:(新建配置文件,server 包含)
location ~* \.jpg$ {
return 402;
}
location ~* 1\.jpg$ {
return 403;
}
結(jié)果如下:
402 Payment Required
--------------------------------------------------------------------------------
nginx/0.8.7
看來是返回的是:402 上面一個呢。 按理論說,1.jpg 配置 比 .jpg 更準(zhǔn)確,看來跟上面說的順序不同,那它會不會是那個在前以那個匹配呢? 我們再測試下:
location ~* 1\.jpg$ {
return 403;
}
location ~* \.jpg$ {
return 402;
}
返回結(jié)果是:
403 Forbidden
--------------------------------------------------------------------------------
nginx/0.8.7
哈哈,恰好相反,看來我的推斷是正確的,如果都是正則,都能夠匹配,以配置文件出現(xiàn)順序來,誰在前誰優(yōu)先。 一口氣說了,不知道朋友你,明白我的思路嗎?這樣的比較會很多很多,大家可以逐一測試。 熟悉location 配置,對于熟練運用nginx 是一個必備基礎(chǔ)。 因為nginx 太靈活,也太流行了。上面的問題,也許朋友你,會遇到。希望對你有幫助。
- Nginx服務(wù)器中的location配置詳解
- 詳解nginx中l(wèi)ocation、rewrite用法總結(jié)
- nginx location中uri的截取的實現(xiàn)方法
- 詳解Nginx location 匹配規(guī)則
- nginx location 配置 正則表達(dá)式實例詳解
- nginx?location/區(qū)別詳解
- Nginx服務(wù)器中l(wèi)ocation配置的一些基本要點解析
- 詳解nginx rewrite和根據(jù)url參數(shù)location
- nginx?配置指令之location使用詳解
- 深入解析nginx路由location匹配規(guī)則及其優(yōu)先級
相關(guān)文章
Centos 6.5 64位中Nginx詳細(xì)安裝部署教程
Nginx是一個web服務(wù)器也可以用來做負(fù)載均衡及反向代理使用,目前使用最多的就是負(fù)載均衡,具體簡介我就不介紹了百度一下有很多,下面直接進入安裝步驟,需要的朋友可以參考下2017-08-08編寫Go程序?qū)ginx服務(wù)器進行性能測試的方法
這篇文章主要介紹了編寫Go程序?qū)ginx服務(wù)器進行性能測試的方法,包括對其負(fù)載均衡和緩存等方面的測試,極力推薦!需要的朋友可以參考下2015-06-06基于Xen的VPS ubuntu+nginx+php安裝教程
跟蹤vps已經(jīng)很久了,但是因為需要特殊端口開服務(wù),所以符合條件的多為Xen平臺的vps。眾多比較之后選擇了vpslink在西雅圖機房,速度還不錯。2010-07-07nginx配置教程之a(chǎn)dd_header的坑詳解
這篇文章主要給大家介紹了關(guān)于nginx配置教程之a(chǎn)dd_header坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02