Nginx配置指令location匹配符優先順序和安全問題
最近一直在做location 配置,遇到優先順序別問題(如果配置不當可能存在安全隱患哦),以下是個人學習一點體會。
一、 location 的匹配符
1.等於匹配符:=
等於匹配符就是等號,特點可以概括為兩點:
精確匹配
不支援正規表示式
2.空匹配符
空匹配符的特點是:
匹配以指定模式開始的 URI
不支援正規表示式
3.正則匹配符:~
正則匹配符是可以使用正規表示式的匹配符。不過這裡要強調的是,一般來說~是指:
區分大小寫的正則匹配
而~*表示:
不區分大小寫的正則匹配
但是對於一些對大小寫不敏感的作業系統,這兩者沒有區別。另外一個就是^~,其表示以指定模式開始的正則匹配。
4.內部訪問符:@
一般用於錯誤頁面等,這個暫不討論。
二、匹配符優先順序
1.=
2.空匹配符,滿足精確匹配時
3.^~
4.~或~*
5.空匹配符,滿足以指定模式開始時的匹配時
這樣說比較抽象,我們來看例子吧。
2.1 等於匹配符與精確匹配時的空匹配符
看下面的例子(用到我們此前一起完成的Hello World模組):
location /poechant {
hello_world no1;
}
location = /poechant {
hello_world no2;
}
如果我們的請求是http://my.domian/poechant,則我們發現兩個location都與請求的 URI 匹配,這時根據我們的優先順序順序,第一個是精確匹配時的空匹配符,第二個是等於匹配符,所以第二個的優先順序高,也就是應該輸出:
hello_world, no2
同時也說明 Nginx 的 locatoin 不是按照配置檔案中的書寫順序來匹配的。
2.2 精確匹配時的空匹配符與正則匹配的^~
下面這個例子中,兩者開始都精確匹配了,連這個正則匹配都是精確匹配。
location ^~ ^/poechant$ {
hello_world no1;
}
location /poechant {
hello_world no2;
}
匹配哪一個?你測試一下,會得到:
hello_world, no2
與我們上面說的優先順序順序相吻合。
2.3 其他匹配優先順序比較的例項
略
三、實戰經驗總結
1.location 匹配的優先順序(來自實踐總結中)
(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全部註釋掉,不然會認為#2 與#4 完全一樣。會提示:重複配置,提示如下
D:
ginx-0.8.7>nginx -s reload
[emerg]: duplicate location “/a/” in D:
ginx-0.8.7/conf/nginx.conf:53
瀏覽測試:每次都是訪問:http://localhost:9999/a/1.jpg (在windows 安裝測試,然後埠是9999) 檔案a/1.jpg 根本不存在。關鍵是測試看頁面返回情況。
a.用上面的配置請求後的結果
——————————————————————————–
nginx/0.8.7
從測試中可以看到,優先順序最高的是:= 號。 它會最先匹配到。
b.接下來我們 遮蔽掉 #6 如下:
# location = /a/1.jpg {
# return 400;
# }
然後過載配置:D:
ginx-0.8.7> nginx -s reload 並訪問:http://localhost:9999/a/1.jpg ,返回以下結果:
401 Authorization Required
——————————————————————————–
nginx/0.8.7
結論:從這個測試發現,沒有“=”情況下,location 後面直接接完整路徑是優先匹配。 通過測試發現,如果將:location/a/1.jpg 改成:location /a/1.jpg
會出現意外情況,直接出現是:return 402. 從這一點,可以推測到nginx 匹配優先是:網站路徑,並且不帶正規表示式的優先。
c.同理測試 遮蔽掉 #5 如下:註釋及重新載入同上.
訪問:http://localhost:9999/a/1.jpg 返回如下結果。
402 Payment Required
——————————————————————————–
nginx/0.8.7
結論:通過這個測試可以得出:location ^~ 優先順序 高於 location ~* 優先順序 ,其中:^~ 主要後面接路徑。
c.同理測試 遮蔽掉 #4 如下:註釋及重新載入同上.
訪問:http://localhost:9999/a/1.jpg 返回如下結果。
403 Forbidden
——————————————————————————–
nginx/0.8.7
結論:從以上比較得到,正則優先 未帶任何匹配符的路徑匹配
d.同理測試 遮蔽掉 #3 如下:註釋及重新載入同上. 並且去掉#2 的註釋“#”
訪問:http://localhost:9999/a/1.jpg 返回如下結果。
——————————————————————————–
nginx/0.8.7
結論:比較有意思是:/a/ 與 / 應該是 同種型別的匹配表示式, 可以從中得到,該匹配順序是,將路徑從右匹配, 可以推測形如逐個字元,那個先匹配到,就是那個優先。 因此得到是:/a/ 優先於 / .
以上測試,是我測試結果,優先順序別以以上規律。 在實際我們書寫中,經常會犯錯誤。 還記得前段時間:80後安全團隊曝nginx漏洞 其實,個人認為不能算是nginx 漏洞,只是,我們不瞭解nginx 配製規則,而出現一個配置上面致命漏洞而已。 其實,通過上面優先順序,我們在配置時候可能也一樣經常犯一個致命錯誤。
#以下是隨便寫例子,個人可能各不相同
#假設站點在:/home/www/html/目錄下,所有的php 及上傳檔案都在這個目錄下面。
location ~* .php$ {
proxy_pass http://www.a.com;
}
location /upload/ {
alias /home/www/html/upload/;
}
而且,這個upload 目錄,是靜態目錄,我們想法是下面所有檔案是不能夠執行的,包括php檔案。
如果有使用者訪問:http://www.a.com/upload/1.css , 會直接顯示該css, 但是,如果有使用者訪問:http://www.a.com/upload/1.php 類似檔案,正如上面所說,實際匹配到:~* .php$ 了。 upload 下面是執行了。
從這個裡面,我們發現一個問題,實際沒有達到我們要求。 靜態目錄下面的檔案一樣執行了。 這下比較麻煩了。 一旦出現個什麼上存漏洞的,別人上存了一個php,我們還以為,我們配置是ok的。 覺得很安全,缺在不知不覺中被別人開啟一扇門。
那麼我們怎麼樣修改呢?
location ~* .php$ {
proxy_pass http://www.a.com;
}
location ^~ /upload/ {
alias /home/www/html/upload/;
}
對,就是必須用:”^~” ,這樣是不是就已經安全了呢。 如果你再訪問下:http://www.a.com/upload/1.php 你會發現,這段程式碼原始碼顯示出來了。 這個其實對於我們而言也是不想見到了。 一段顯示原始碼,在各個搜尋引擎,很容易通過所有特殊關鍵字,搜尋到改檔案的。
那麼我們該怎麼樣配置安全的上存目錄呢? 對,你想到了:限制允許的特殊檔案型別。
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 不能訪問,有可以避免原始碼顯示。
剛才從匹配結果已經知道了,同級不帶任何匹配符的,是以右為準匹配。 那麼,如果都用正規表示式,以什麼方式匹配呢?
測試如下:(新建配置檔案,server 包含)
location ~* .jpg$ {
return 402;
}
location ~* 1.jpg$ {
return 403;
}
結果如下:
402 Payment Required
——————————————————————————–
nginx/0.8.7
看來是返回的是:402 上面一個呢。 按理論說,1.jpg 配置 比 .jpg 更準確,看來跟上面說的順序不同,那它會不會是那個在前以那個匹配呢? 我們再測試下:
location ~* 1.jpg$ {
return 403;
}
location ~* .jpg$ {
return 402;
}
返回結果是:
403 Forbidden
——————————————————————————–
nginx/0.8.7
哈哈,恰好相反,看來我的推斷是正確的,如果都是正則,都能夠匹配,以配置檔案出現順序來,誰在前誰優先。 一口氣說了,不知道朋友你,明白我的思路嗎?這樣的比較會很多很多,大家可以逐一測試。 熟悉location 配置,對於熟練運用nginx 是一個必備基礎。 因為nginx 太靈活,也太流行了。上面的問題,也許朋友你,會遇到。希望對你有幫助。
相關文章
- 談Nginx的Location匹配優先順序Nginx
- nginx的location匹配順序、優先順序,location對映衝突排查Nginx
- Nginx location 在配置中的優先順序Nginx
- nginx location規則優先順序比較Nginx
- Nginx的location規則:優先順序和路徑替換Nginx
- 高效能Web伺服器Nginx的配置與部署研究(16)小議location匹配模式優先順序Web伺服器Nginx模式
- 42. nginx 匹配的 try_file 與前端路由的優先順序問題Nginx前端路由
- nginx快取優先順序Nginx快取
- C++操作符的優先順序C++
- Yarn任務優先順序配置Yarn
- scala隱式轉換優先順序問題
- SpringBoot配置檔案優先順序載入順序Spring Boot
- 關於CSS樣式的優先順序問題CSS
- CSS優先順序CSS
- Java 修飾符順序問題Java 修飾符
- iOS Autolayout 修改約束優先順序崩潰問題iOS
- html優先順序和層疊性HTML
- 中斷優先順序
- 埃航和737MAX墜毀:軟體優先順序問題
- 快應用tabs和video元件滑動事件優先順序問題IDE元件事件
- python運算子及優先順序順序Python
- NTP時間伺服器優先順序配置伺服器
- 無順序約束的字串匹配問題字串匹配
- Oracle RAC引數設定優先順序別問題分析Oracle
- nginx location指令Nginx
- nginx location匹配規則Nginx
- Nginx Location 路徑匹配Nginx
- Nginx中的一些匹配順序Nginx
- HttpClient和HttpGet 引數的優先順序HTTPclient
- gc current block busy和LMS優先順序GCBloC
- Android程式優先順序Android
- SQL 優先順序join>whereSQL
- java運算子優先順序Java
- php運算子優先順序PHP
- css優先順序彙總CSS
- 美團二面:SpringBoot讀取配置優先順序順序是什麼?Spring Boot
- toString()和valueOf()函式呼叫和優先順序函式
- [勝通]程式優先順序和程式nice值?