Nginx
當主機頭包含冒號字元時,NGINX 路由到錯誤的虛擬主機
我的 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"; } }
重要的部分是波浪號
~
,它表示正則表達式匹配。