在 Nginx 中,通过 server_name
区分同一端口下不同域名/主机名的请求,核心是利用虚拟主机(Server Block) 机制,按以下逻辑匹配:
1. 匹配优先级规则
Nginx 收到请求后,先提取 Host
头(请求的域名/IP:端口),按以下顺序找对应 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. 关键配置细节
(1)listen
端口与 IP 绑定
若需区分同一端口但不同 IP(服务器多网卡场景),可在 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. 调试与验证
(1)检查配置语法
nginx -t # 验证配置文件是否正确
(2)查看请求匹配日志
在 error_log
开启 debug
级别(临时调试用,别长期开):
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
或正则)
→ 解决:严格按通配符/正则规则写,正则用 ~
标记并转义 .
(如 ~^www\.example\.com$
)。
问题3:HTTPS 提示证书错误
→ 原因:SNI 未生效(旧浏览器/客户端不支持),或证书绑定错误
→ 解决:确认客户端支持 SNI,检查 ssl_certificate
与 server_name
对应关系。
通过 server_name
配合 listen
,可精准区分同一端口的不同域名请求,核心是利用 Nginx 的虚拟主机匹配规则。调试时重点抓 Host
头和日志,就能快速定位问题~
阅读原文:原文链接
该文章在 2025/7/1 23:29:42 编辑过