Nginx

當主機頭包含冒號字元時,NGINX 路由到錯誤的虛擬主機

  • March 11, 2022

我的 nginx.conf 有幾個“伺服器”部分和一個包羅萬象的伺服器部分。這是一個範例 nginx.conf 給你一個想法:

user www-data;
worker_processes auto;
worker_cpu_affinity auto;
pid /run/nginx.pid;

events {
   worker_connections 4000;
   use epoll;
   accept_mutex off;
}

http {
   include /etc/nginx/mime.types;
   default_type application/octet-stream;
   error_log /var/log/nginx/error.log;

   server {
       listen 80;

       server_name foo.com;

       location / {
           default_type text/plain;
           return 200 "hello from foo.com";
       }

       error_page 500 502 503 504 /500.html;
   }

   server {
       listen 80 default_server;
       server_name _;

       location / {
           return 403 "sorry";
       }
   }

}

如果“主機”標頭不是“foo.com”,我希望伺服器返回 403。

顯然有人在我的伺服器上執行 Burp Suite,當他們發送“Host: foo.com:more-stuff-here”標頭時,我注意到一個有趣的行為:NGINX 將請求路由到第一個“伺服器”部分。它看起來好像忽略了標頭值中的冒號及其後面的所有內容。

我可以使用上面的 nginx.conf 在本地重現它:

$ curl -H "Host: foo.com" http://127.0.0.1
hello from foo.com

$ curl -H "Host: foo.com:unexpected-content" http://127.0.0.1
hello from foo.com

$ curl -H "Host: bar.com" http://127.0.0.1
sorry

為什麼 NGINX 會這樣做?這是預期的行為嗎?我應該在 nginx.conf 中進行哪些更改以確保帶有“Host: foo.com:more-stuff-here”標頭的請求轉到預設塊?

**更新:**對於研究同一問題的任何人,我還在NGINX 問題跟踪器中創建了一張票

HTTP RFC中 host 頭的定義表明 Host 頭的形式應該是host:port,並且:port是可選的。

nginx 將冒號後面的所有內容視為主機的埠,但它與您的上下文無關,因為您沒有以這種方式指定伺服器塊。所以它使用它可以找到的最接近的匹配,沒有“埠”的主機。

以下可能適用於default_server

server {
   listen 80 default_server;

   server_name _ ~example\.com:;

   location / {
       return 403 "sorry";
   }
}

重要的部分是波浪號~,它表示正則表達式匹配。

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