靠 server_name 实现租户隔离的核心是每个租户独占专属域名并配置独立 server 块,禁止混用;需设 default_server 兜底返回 444 或 403;HTTPS 下证书必须包含全部域名 SAN;root 和 location 需物理隔离。

靠 server_name 实现租户隔离,核心是让每个租户独占一个或一组明确绑定的域名,Nginx 通过 Host 请求头精准匹配对应 server 块,不混淆、不 fallback。
用独立 server 块绑定专属域名
每个租户必须有自己独立的 server 块,server_name 只写该租户的域名(支持空格分隔多个别名,如 tenant-a.com www.tenant-a.com)。不能把多个租户的域名混在一个块里——那会共享 root、location 和权限,失去隔离性。
- ✅ 正确:每个租户一个 server 块,域名不重叠
- ❌ 错误:一个块里写
server_name a.com b.com,然后靠 if 判断切换 root —— 这不是隔离,是伪多租户
避免默认 server 拦截非预期请求
如果没有显式匹配的 server_name,Nginx 会把请求交给“默认 server”(通常是配置文件中第一个 listen 相同的块)。这对租户环境很危险:别人随便用 IP 或错误 Host 访问,可能看到某个租户的首页。
- 显式定义一个“兜底 server”,返回 444(直接关闭连接)或 403
- 确保所有租户 server 块的
listen指令带default_server标志的只有那个兜底块 - 例如:
server { listen 80 default_server; return 444; }
HTTPS 下必须配 SAN 证书,且顺序无关但覆盖要全
租户走 HTTPS 时,TLS 握手阶段只看 server_name 列表里的第一个域名去选证书。如果证书没包含其余域名,浏览器就报错。
- 生成证书时必须用
-d列出该租户全部域名,比如:certbot -d shop.tenant-b.com -d admin.tenant-b.com - Nginx 配置中
server_name的顺序不影响证书加载逻辑,但所有域名都得在证书的 SAN 字段里 - 别指望用通配符证书覆盖所有租户——
*.example.com只能匹配二级子域,不能跨租户复用
配合文件系统与 location 做纵深隔离
server_name 是第一道路由关卡,但租户间资源还需物理隔离:
- 每个租户的
root指向独立目录,比如/var/www/tenant-c/public - 敏感路径(如
/admin、/api)用location单独限制,不继承其他租户规则 - 必要时结合 Linux 文件权限(如
chown tenant-c:tenant-c),防止配置失误导致越权读取


















