nginx实现多虚拟主机本质是通过多个独立server块隔离配置,每个块用server_name指定专属域名,依据host头精准匹配,并推荐拆分配置文件、https使用san证书及设置default_server兜底。

在 Nginx 中实现多虚拟主机,本质是让一个 Nginx 实例响应多个域名(或 IP/端口)的请求,核心靠 server 块隔离配置。不是靠“一个 server 块管所有站”,而是靠“多个独立的 server 块各管各的站”——每个块对应一个逻辑上完全独立的网站。
按域名区分:每个站点一个 server 块
这是最常用、最清晰的方式。每个 server 块通过 server_name 指定专属域名,Nginx 根据 HTTP 请求头中的 Host 字段精准匹配:
-
server_name site1.com www.site1.com;→ 匹配这两个域名,共用同一套配置 -
server_name site2.com api.site2.com;→ 另一套配置,根目录、日志、SSL 都可完全不同 - 确保每个
server块都有明确的root和index,避免路径冲突 - 监听语句建议写全:
listen 80;和listen [::]:80;,兼顾 IPv4/IPv6
配置文件组织:拆分管理更安全
不要把所有 server 块堆进 nginx.conf。推荐用模块化方式:
- 在
/etc/nginx/conf.d/下为每个站点建独立文件,如site1.com.conf、site2.com.conf - 主配置
nginx.conf的http块中保留include /etc/nginx/conf.d/*.conf; - 这样增删站点只需操作单个文件,测试时也容易定位问题
- 统信 UOS 等系统还支持
sites-available+sites-enabled软链方式,原理相同
HTTPS 必须配 SAN 证书 + 正确 listen
多个域名共用 HTTPS 时,不能只靠 server_name 列出就完事:
- SSL 证书必须是 SAN(Subject Alternative Name)类型,包含所有要使用的域名,例如:
certbot -d site1.com -d www.site1.com -d site2.com - 每个 HTTPS 的
server块都要写listen 443 ssl http2;,并指定ssl_certificate和ssl_certificate_key -
server_name在 HTTPS 块里依然生效,用于 SNI 协商和后续$host变量取值 - 别漏掉
http2参数,现代浏览器默认要求
兜底处理:防 IP 直输或非法 Host 头
没匹配到任何 server_name 的请求,默认会命中第一个监听该端口的 server 块,可能暴露测试页或跳错站:
- HTTP 兜底写法:
server { listen 80 default_server; server_name _; return 444; } - HTTPS 兜底必须带证书(哪怕自签):
server { listen 443 ssl http2 default_server; server_name _; ssl_certificate /path/fallback.crt; ssl_certificate_key /path/fallback.key; return 444; } -
default_server标志确保它优先被选中,return 444是静默关闭连接,比 404 更安全











