Nginx

Nginx 沒有選擇前綴最長的位置

  • June 26, 2022

在這個簡化的 nginx 設置中,我有兩個 nginx 位置塊,一個用於 SSL 證書更新,一個用於快速代理(用於 uwsgi/Django )。

當通過 acme.sh 進行 SSL 證書更新時,它會將文件放入/var/www/example.com/public/.well-known/acme-challenge/其中,然後測試它們是否已提供。然而,快速代理(Django)正在處理請求/.well-known/acme-challenge/.......而不是location = /\.well-known/acme-challenge/位置塊。

如何告訴 nginx 使用正確的塊?如果我刪除快速代理位置塊,則該location = /\.well-known/acme-challenge/塊工作正常。

這是配置:

server { 
   listen 443 ssl http2; 
   listen [::]:443 ssl http2; # For IP6 
   server_name www.example.com; 
   charset utf-8; 
   root /var/www/example.com/public; 

   # acme.sh SSL certificate issues
   location /\.well-known/acme-challenge/ {
   }

   # Finally, send all non-media requests to the Django server.
   location / {
       uwsgi_pass django;
       include /home/michael/project/conf/uwsgi/params;  
   } 

nginx 文件說:

當 nginx 選擇一個位置塊來服務請求時,它首先檢查指定前綴的位置指令,記住具有最長前綴的位置,然後檢查正則表達式。如果與正則表達式匹配,則 Nginx 選擇此位置,否則,它會選擇之前記住的位置。

對我來說/\.well-known/acme-challenge/是最長的前綴,所以它應該“贏”。

您是否查看了該location指令的文件?

位置可以由前綴字元串或正則表達式定義。正則表達式使用前面的“ ~*”修飾符(用於不區分大小寫的匹配)或“ ~”修飾符(用於區分大小寫的匹配)指定。

為了找到與給定請求匹配的位置,nginx 首先檢查使用前綴字元串(前綴位置)定義的位置。其中,匹配前綴最長的位置被選中並記憶。然後按照它們在配置文件中出現的順序檢查正則表達式。正則表達式的搜尋在第一次匹配時終止,並使用相應的配置。如果找不到與正則表達式的匹配項,則使用前面記住的前綴位置的配置。

location /\.well-known/acme-challenge/是一個前綴字元串,但你試圖逃避 a.因為它是一個正則表達式。這不起作用。

對於網址https://www.example.com/.well-known/acme-challenge/foo

server { 
   listen 443 ssl http2; 
   server_name www.example.com; 

   # 1. Prefix string, NO MATCH.
   location /\.well-known/acme-challenge/ {
   }

   # 2. Longest matching prefix string.
   location /.well-known/acme-challenge/ {
   }

   # 3. First case sensitive regex match.
   location ~ /\.well-known/acme-challenge/ {
   }

   # 4. Another case sensitive regex match.
   location ~ ^/\.well-known/acme-challenge/ {
   }

   # 5. Matching prefix string, but not the longest.
   location / {
   }
}

如果您擁有所有這些,則將使用正則表達式匹配 #3,因為它是第一個匹配的正則表達式。與僅在 URI 路徑開頭匹配的 #4 不同,它也會匹配/any/path/having/.well-known/acme-challenge/in/it,類似於前綴字元串匹配。

TL;DR:#2 和#4 是等價的,兩者都可以實現你的目標。

為了完整起見,評估順序為:

  1. #1 前綴,不匹配
  2. #2 前綴,匹配(長度=28)
  3. #5 前綴,匹配(長度=1)
  4. #3 正則表達式,匹配 => 選擇

#4 不會被評估。沒有#3 & #4,#2 會贏。

引用自:https://serverfault.com/questions/1104119