Nginx 多域名分发需用多个 server 块各绑定专属 server_name,按 Host 头精准路由;HTTPS 需匹配 SAN 证书或单域名证书;应配置 default_server 兜底防误访。

在 Nginx 中用 server_name 实现多域名分发请求,关键不是让多个域名“共存于一个块”就完事,而是明确目标:是把不同域名导向不同后端(分发),还是让多个域名共享同一站点(复用)。你问的是“分发”,那就得靠多个 server 块各自绑定专属域名,Nginx 根据 Host 头精准路由。
每个域名配独立 server 块
这是最清晰、最可控的分发方式。每个 server 块监听相同端口(如 80 或 443),但 server_name 只写自己负责的域名(或一组同属该服务的域名):
-
示例 1(HTTP 分发):
访问api.example.com→ 转发到本地 3000 端口
访问admin.example.com→ 转发到本地 8000 端口
配置如下:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name admin.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
}
}
-
注意点:两个块都
listen 80,但因server_name不同,Nginx 在收到请求时会比对 Host 头,自动选中匹配的块处理,互不干扰。
同一 server 块内用 if + $host 做细粒度分发(慎用)
如果多个子域名逻辑接近(比如都走同一套 Node.js 服务,但路径前缀不同),可合并在一个 server 块里,用 $host 变量做条件判断:
- 支持
if ($host = "shop.example.com") { ... }或map指令映射后端地址 -
不推荐直接用 if 做 proxy_pass:Nginx 官方提醒
if在location外部行为不可靠;更稳妥的做法是用map预定义变量,再在proxy_pass中引用
例如:
map $host $backend {
hostnames;
shop.example.com "http://127.0.0.1:8081";
blog.example.com "http://127.0.0.1:8082";
default "http://127.0.0.1:8080";
}
server {
listen 80;
server_name shop.example.com blog.example.com example.com;
location / {
proxy_pass $backend;
proxy_set_header Host $host;
}
}
HTTPS 分发必须匹配 SAN 证书
如果用 HTTPS 分发,每个 server 块若监听 443 ssl,就必须配对应的证书。常见错误是多个域名共用一个 server 块却只申请了单域名证书——浏览器会报错。
- 方案一(推荐):为每个域名单独申请证书,各配一个
server块,各自指定ssl_certificate - 方案二:统一用 SAN 证书覆盖所有分发域名,放在同一个
server块里,server_name列全,ssl_certificate指向同一份 PEM 文件
例如 SAN 证书含 api.example.com 和 static.example.com,可这样写:
server {
listen 443 ssl http2;
server_name api.example.com static.example.com;
ssl_certificate /etc/nginx/ssl/san-cert.pem;
ssl_certificate_key /etc/nginx/ssl/san-key.pem;
if ($host = "api.example.com") {
proxy_pass http://127.0.0.1:3000;
}
if ($host = "static.example.com") {
proxy_pass http://127.0.0.1:8081;
}
}
⚠️ 注意:if 在 SSL 块里仍需谨慎;生产环境建议优先用 map 或拆成两个 server 块。
兜底 server 防止误入
用户可能直接输 IP 访问,或 Host 头填错,这时 Nginx 默认交给该端口下第一个 server 块——容易暴露默认页或跳错站。
- HTTP 兜底:加一个
default_server,返回 444(关闭连接)或 404 - HTTPS 兜底:同样设
default_server,但必须配一个有效证书(哪怕自签),否则 TLS 握手失败
例如:
server {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 443 ssl http2 default_server;
server_name _;
ssl_certificate /etc/nginx/ssl/default.pem;
ssl_certificate_key /etc/nginx/ssl/default.key;
return 444;
}


















