关键在于单个server块内用空格分隔多个域名,如server_name example.com www.example.com;,匹配优先级为精确>左通配符>正则,HTTPS需SAN证书覆盖所有域名,并设default_server兜底未匹配请求。

在 Nginx 中用 server_name 实现多域名虚拟主机,关键不是堆砌多个 server 块,而是让一个 server 块响应多个域名的请求——前提是这些域名都指向同一站点内容,且你清楚匹配逻辑和 HTTPS 限制。
单个 server 块绑定多个域名
只需在 server_name 指令后用空格分隔所有目标域名:
- ✅ 正确写法:
server_name example.com www.example.com shop.example.com; - ❌ 错误写法:
server_name "example.com, www.example.com";(引号+逗号会被当做一个非法域名) - ❌ 错误写法:
server_name example.com\nwww.example.com;(换行不识别,必须在同一行)
这样配置后,只要客户端 HTTP 请求中的 Host 头匹配其中任意一个,Nginx 就会将请求交给这个 server 块处理。注意:$host 变量仍保留原始访问域名,可用于日志标记、条件跳转或路径拼接。
匹配优先级必须理清
Nginx 不是按配置顺序扫描,而是按三类规则分组比对,命中即停:
-
精确匹配最优先:如
server_name api.example.com;,只响应Host: api.example.com -
左通配符次之:如
server_name *.example.com;,可匹配shop.example.com,但不匹配example.com或dev.test.example.com -
正则匹配最灵活但最慢:如
server_name ~^([a-z0-9\-]+)\.example\.com$;,需转义点号,结尾加$防止部分匹配
若同时存在 example.com 和 *.example.com,前者永远胜出——别指望靠书写顺序控制优先级。
HTTPS 必须配套 SAN 证书
HTTP 层靠 Host 头路由,但 TLS 握手阶段依赖 SNI,Nginx 只用 server_name 列表里的第一个域名去校验证书 SAN 扩展:
- 如果证书只含
example.com,而你写server_name example.com www.example.com;,访问www.example.com会提示证书错误 - 正确做法:申请证书时明确包含全部域名,例如 Certbot 命令:
certbot -d example.com -d www.example.com -d shop.example.com - 证书本身无顺序,但 Nginx 加载时只检查首个
server_name是否在 SAN 中
未匹配请求必须兜底
用户直接用 IP 访问、Host 头填错域名,或 DNS 解析异常时,Nginx 默认把请求交给该端口下第一个 server 块——极易暴露测试页或跳错站:
- HTTP 兜底建议:
server { listen 80 default_server; server_name _; return 444; } - HTTPS 兜底必须设置:
server { listen 443 ssl default_server; server_name _; ssl_certificate /dev/null; return 444; }(避免证书警告) -
server_name _;是通用占位符,匹配所有未显式声明的 Host 值
不复杂但容易忽略。


















