在 Nginx 中,通過 server_name
區(qū)分同一端口下不同域名/主機名的請求,核心是利用虛擬主機(Server Block) 機制,按以下邏輯匹配:
1. 匹配優(yōu)先級規(guī)則
Nginx 收到請求后,先提取 Host
頭(請求的域名/IP:端口),按以下順序找對應(yīng) server
:
| | | |
---|
| server_name example.com www.abc.com; | | |
| server_name *.example.com; | | |
| server_name mail.*; | | |
| server_name ~^api\d+\.example\.com$; | | |
| server_name _; | | |
示例:
server {
listen 80;
server_name example.com www.example.com; # 精確匹配
...
}
server {
listen 80;
server_name *.example.com; # 匹配 blog.example.com 等子域
...
}
server {
listen 80;
server_name ~^api\d+\.example\.com$; # 正則匹配 api1.example.com 等
...
}
server {
listen 80;
server_name _; # 其他未匹配的請求走這里
return 404;
}
2. 關(guān)鍵配置細節(jié)
(1)listen
端口與 IP 綁定
若需區(qū)分同一端口但不同 IP(服務(wù)器多網(wǎng)卡場景),可在 listen
指定 IP:
server {
listen 192.168.1.10:80; # 僅處理 192.168.1.10 的 80 端口請求
server_name site1.com;
...
}
server {
listen 192.168.1.20:80; # 僅處理 192.168.1.20 的 80 端口請求
server_name site2.com;
...
}
(2)Host
頭缺失的處理
若請求無 Host
頭(或非法值),Nginx 會找默認 server(同端口下,第一個 server
或顯式標記 default_server
的):
server {
listen 80 default_server; # 標記為默認,處理無 Host 或不匹配的請求
server_name _;
return 400; # 直接返回錯誤
}
(3)HTTPS 場景的 SNI 支持
TLS 握手時,瀏覽器通過 SNI(Server Name Indication) 傳遞 server_name
,Nginx 需開啟支持(默認開啟,舊版本需編譯時加 --with-http_ssl_module
):
server {
listen 443 ssl;
server_name site1.com;
ssl_certificate /etc/nginx/certs/site1.crt;
ssl_certificate_key /etc/nginx/certs/site1.key;
...
}
server {
listen 443 ssl;
server_name site2.com;
ssl_certificate /etc/nginx/certs/site2.crt;
ssl_certificate_key /etc/nginx/certs/site2.key;
...
}
3. 調(diào)試與驗證
(1)檢查配置語法
nginx -t # 驗證配置文件是否正確
(2)查看請求匹配日志
在 error_log
開啟 debug
級別(臨時調(diào)試用,別長期開):
error_log /var/log/nginx/error.log debug;
重啟 Nginx 后,請求日志會顯示 server_name
匹配過程。
(3)用 curl
模擬請求
指定 Host
頭測試不同域名:
curl -H "Host: example.com" http://127.0.0.1 # 匹配 example.com 的 server
curl -H "Host: blog.example.com" http://127.0.0.1 # 匹配 *.example.com 的 server
4. 常見問題
問題1:修改 server_name
后不生效
→ 原因:瀏覽器緩存/未重啟 Nginx
→ 解決:nginx -s reload
重啟,或用 curl
繞開瀏覽器緩存測試。
問題2:通配符/正則匹配失效
→ 原因:語法錯誤(如通配符 *.com
不匹配 a.b.com
,需寫成 *.b.com
或正則)
→ 解決:嚴格按通配符/正則規(guī)則寫,正則用 ~
標記并轉(zhuǎn)義 .
(如 ~^www\.example\.com$
)。
問題3:HTTPS 提示證書錯誤
→ 原因:SNI 未生效(舊瀏覽器/客戶端不支持),或證書綁定錯誤
→ 解決:確認客戶端支持 SNI,檢查 ssl_certificate
與 server_name
對應(yīng)關(guān)系。
通過 server_name
配合 listen
,可精準區(qū)分同一端口的不同域名請求,核心是利用 Nginx 的虛擬主機匹配規(guī)則。調(diào)試時重點抓 Host
頭和日志,就能快速定位問題~
閱讀原文:原文鏈接
該文章在 2025/7/1 23:29:42 編輯過