在 nginx 中让一个 server 块响应多个域名,核心是用空格分隔多个域名写在同一个 server_name 后,如 server_name example.com www.example.com demo.example.org;需配合 san 证书支持 https,并通过 $host 变量区分处理请求。

在 Nginx 中让一个 server 块响应多个域名,核心是正确使用 server_name 指令——不是靠写多个 server 块,而是用空格把多个域名并列写在同一行里。
单个 server 块绑定多个域名
语法很简单:在 server_name 后面用空格依次列出所有要支持的域名,不能加逗号、引号或换行。
server_name example.com www.example.com demo.example.org;- 这样只要请求头里的
Host是这三个中的任意一个,且 DNS 已解析到这台服务器,就会由这个server块处理 - 如果整个配置中只有一个
server块,server_name实际上不生效——任何Host都会命中它
匹配优先级与常见写法
Nginx 不按配置顺序匹配,而是按三类规则分组判断:
- 精确匹配(如
example.com)优先级最高 - 左通配符次之(如
*.example.com,能匹配api.example.com,但不匹配example.com) - 正则匹配最低(如
~^www\d+\.example\.com$),且按配置中出现顺序执行 - 建议把主域和常用子域都列全,比如同时写
example.com和www.example.com,避免漏掉变体导致跳转失败或 404
区分访问域名并做不同响应
虽然多个域名共用一套配置,但可通过内置变量 $host 获取真实请求域名:
- 做 301 强制跳转:
if ($host != 'example.com') { return 301 https://example.com$request_uri; } - 记录日志时带上域名:
log_format main '$host - $remote_addr ...'; - 返回头中标记来源:
add_header X-Host $host;
HTTPS 多域名必须用 SAN 证书
HTTP 层可以自由绑定多个域名,但 HTTPS 必须通过 TLS 层验证:
- 单域名证书只认一个域名,其他访问会提示证书错误
- 应使用 SAN(Subject Alternative Name)多域名证书,例如用 Certbot 生成:
certbot -d example.com -d www.example.com -d demo.example.org - Nginx 配置中仍只需一组
ssl_certificate和ssl_certificate_key,指向同一对文件即可 - 确保每个监听
443 ssl的server块也写了对应的server_name,否则 SNI 协商可能选错块











