日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

nginx 配置文件的匹配规则

發(fā)布時間:2024/8/23 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nginx 配置文件的匹配规则 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引出

之前在對php-fpm 進行nginx代理時, 為了對后臺限定 IP 訪問, 添加了如下配置:

location ^~ /admin {allow 127.0.0.1;deny all; }

結(jié)果呢? 所有admin路徑下的php文件, 全都沒有解析, 變成文件下載了. 當時我不知道是什么問題, 不過將這段配置去掉之后, 問題就消失了. 所以, 我可以肯定的是, 一定是這段路徑匹配的問題, 導致沒有走php-fpm的解析.

探究

為了探究原因, 我查找資料并做了嘗試. 如果想直接看結(jié)果, 可以跳過這一 part.

在上方出現(xiàn)問題的場景中, nginx的配置文件大體如下:

server {listen 80;server_name localhost;root /var/www/html;index index.php;location / {try_files $uri $uri/ /index.php?$args;}location ~ \.php$ {try_files $uri =404;//...此處省略 fpm 配置}location ^~ /admin {allow 127.0.0.1;deny all;} }

經(jīng)過思考, 當我訪問localhost/admin/test.php的時候, nginx沒有執(zhí)行第二個匹配規(guī)則, 沒有將文件交由php-fpm解析器執(zhí)行, 進而導致其作為靜態(tài)文件直接下載.

接下來, 就是驗證這個想法了. 最簡單的驗證方法, 就是在nginx匹配規(guī)則中, 直接返回 HTTP 響應嗎. 這樣用curl看一下響應碼, 就知道執(zhí)行了哪個規(guī)則了.

說干就干, 修改配置文件如下:

server {listen 80;server_name localhost;location / {return 300;}location ~ \.php$ {return 200;}location ^~ /admin {return 100;} }

和猜想的一樣, 即使匹配規(guī)則在前面, 但是仍然先匹配到了規(guī)則^~. 也就是說規(guī)則 ^~ 比規(guī)則 ~的匹配優(yōu)先級更高.

不過還有一點無法確定, 即使先匹配到了后面的規(guī)則, 那也不能說明前面的規(guī)則就不走了啊. nginx也有可能是按照順序依次進行匹配的.

為了驗證, 我們將第三個配置規(guī)則中的return 100刪掉. 此時, 如果能夠匹配到php的規(guī)則, 那么就會返回響應碼200, 如果不能, 應該提示找不到文件. 測試一下.

至此說明匹配到 ^~ 規(guī)則的時候, 就會直接執(zhí)行而不進行后續(xù)的匹配了. 那問了, 有可能是因為兩個匹配規(guī)則的優(yōu)先級不同, 故而忽略了優(yōu)先級低的匹配規(guī)則.

為了驗證nginx對于相同優(yōu)先級的匹配規(guī)則, 是否會進行后續(xù)匹配, 再次進行實驗. 修改配置文件如下:

server {listen 80;server_name localhost;location ~ hp$ {return 400;}location ~ php$ {return 500;} }

配置文件中兩個正則匹配, 我的想法是這樣的, 此時訪問, 會返回響應嗎 400, 說明匹配了第一個規(guī)則, 然后我將第一個規(guī)則中的return 400刪除, 如果返回了 500, 就說明nginx在匹配了第一個規(guī)則之后, 繼續(xù)執(zhí)行了下一個匹配. 很嚴謹. 先訪問一下:

很好, 符合預期, 然后將第一個規(guī)則中的return刪除, 再次訪問:

這次返回了 404, 這說明, nginx在執(zhí)行到第一個匹配的時候, 就停止匹配, 不再進行后續(xù)匹配了.

至此, nginx的匹配規(guī)則基本上已經(jīng)復現(xiàn)出來了.

  • 按照優(yōu)先級從高到低的順序進行匹配
  • 相同優(yōu)先級的, 按照配置文件中的順序進行匹配
  • 當匹配到一條規(guī)則之后, 停止后續(xù)匹配.
  • 匹配規(guī)則

    接下來整理一下nginx路徑的匹配規(guī)則, 以下優(yōu)先級按照從高到底排序:

    • location = /xxx: 路徑精確匹配
    • location ^~ /xxx: 路徑前綴匹配
    • location ~ xxx: 路徑正則匹配
    • location ~* xxx: 路徑正則匹配, 不區(qū)分大小寫, 與正則匹配的優(yōu)先級相同
    • location /xxx : 路徑前綴匹配
    • location / : 通用匹配, 當其他都沒有匹配的時候, 會走到這里.

    nginx會按照優(yōu)先級從高到低依次進行匹配, 在第一個匹配成功的時候執(zhí)行操作并停止匹配.

    回顧

    匹配規(guī)則看上去很簡潔. 現(xiàn)在可以回頭看一下我們最初遇到的問題了.

    我們想讓某后臺地址限定 IP 訪問, 故而添加了這樣的配置:

    location ~ \.php${//... } location ^~ /admin {allow 127.0.0.1;deny all; }

    現(xiàn)在應該很清楚了吧, 所有admin下的路徑, 因為規(guī)則^~的優(yōu)先級更高, 故而解析到了后面的規(guī)則, 而沒有執(zhí)行php的解析操作. 又因為沒有解析操作, 故而 php 文件都當做資源文件返回了.

    那么問題來了, 如果我想對admin路徑下的路徑執(zhí)行訪問限制, 改怎么辦呢?

    • 將規(guī)則^~改成~ ? 不行, 因為優(yōu)先級相同, 先匹配到前面的 php 正則匹配, 后面的限制沒有效果

    • 將規(guī)則^~改成~并提到前面? 不行, 因為優(yōu)先級相同, 先匹配到限制, 如果通過不會進行后面的 php 解析.

    這不陷入死循環(huán)了么? 我又想對某個路徑執(zhí)行限制, 如果限制通過的話, 又需要能夠正常解析. 怎么破? 這里我探索出來的思路是, 他不是不認識php文件么, 我讓他認識認識不就完了么. 直接將匹配的解析過程嵌套寫入, 配置文件大體如下:

    location ^~ /admin{deny all;location ~ \.php$ {//...}}

    這樣的話, 就可以達到在執(zhí)行 IP 限制的前提下, 又能夠正常解析php-fpm.

    那么一個新的問題來了, 這不就相當于將 php 的解析復制了一遍么? 也太不優(yōu)雅了. 我想到的方案是, 通過nginx的include命令. 通過將php文件的解析配置單獨放到一個配置文件php-fpm.conf.common文件中, 內(nèi)容如下:

    location ~ \.php${// ... }

    這樣, 原本的配置文件就可以改寫成如下形式了:

    location ^~ /admin {allow 127.0.0.1;deny all;# 這里因為相對路徑使用的是 nginx.conf 的路徑, 所以需要再走一層include ./conf.d/php-fpm.conf.comon } include ./conf.d/php-fpm.conf.common

    此時, 就能夠?qū)崿F(xiàn)之前的目的了, admin路徑下的php文件僅對指定 ip 開放, 且通過時能夠正常進行解析.

    有可能有更優(yōu)雅的解決方案, 我看網(wǎng)上有些實現(xiàn)是通過rewrite的方式來實現(xiàn)的, 但是我試了很多次都沒有成功. 如果你有更好的方式, 還望不吝賜教.


    經(jīng)過幾天的實驗, 終于把nginx的執(zhí)行順序搞懂了, 感謝我的中學老師會了我控制變量法.

    總結(jié)

    以上是生活随笔為你收集整理的nginx 配置文件的匹配规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。