Nginx通过server_name严格绑定子域名并配合proxy_pass实现多租户隔离,需保留$host头、设置X-Forwarded-*头、后端控制Cookie Domain,HTTPS推荐泛域名证书统一覆盖。

在 Nginx 中用 proxy_pass 实现多租户系统的独立子域名代理,核心是按 Host 头区分租户、精准路由到对应后端服务,同时确保各租户的会话、静态资源、Cookie 等不越界。这不是简单写几行 proxy_pass 就能跑通的事,关键在于隔离逻辑是否闭环。
子域名与租户的映射关系要明确
Nginx 本身不管理租户,它只负责把 sales.example.com、hr.example.com 这类请求,准确转发给对应的后端服务实例(比如不同端口、不同容器、或带租户标识的统一服务)。你需要提前约定好映射规则:
-
tenant1.example.com→ 后端服务 A(如http://127.0.0.1:8081) -
tenant2.example.com→ 后端服务 B(如http://127.0.0.1:8082) - 或统一后端但强制注入租户标识(如
proxy_set_header X-Tenant-ID "tenant2";)
注意:不能靠 URL 路径(如
/tenant1/)做主隔离方式,因为多租户系统通常要求完全独立的子域名体验,且路径方式容易绕过、不利于 SEO 和 Cookie 隔离。
每个 server 块必须严格绑定子域名
用 server_name 明确限定作用域,避免 fallback 或误匹配:
server {
listen 80;
server_name sales.example.com;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name hr.example.com;
location / {
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}-
$host保留原始子域名,方便后端识别租户; -
X-Forwarded-*系列头确保后端能拿到真实客户端信息; -
不要漏掉
proxy_set_header Host,否则后端可能收到localhost:8081这类错误 Host,导致静态资源 404 或重定向异常。
租户间必须隔离 Cookie 和会话域
子域名代理生效后,浏览器默认把 example.com 下所有子域名的 Cookie 当作同域共享。这对多租户是严重风险:
-
sales.example.com登录后,hr.example.com可能意外携带同一 session ID; - 解决办法是在后端设置 Cookie 的
Domain属性为具体子域名(如Domain=sales.example.com),Nginx 无法替代后端做这件事; - 若后端不可控,可考虑用 Nginx 重写 Set-Cookie 头(需
headers-more-nginx-module模块):more_set_headers "Set-Cookie: $sent_http_set_cookie; Domain=$host";
但该方式较脆弱,优先推荐后端规范处理。
HTTPS 与证书管理要同步覆盖全部子域名
启用 HTTPS 后,每个 server_name 都需要匹配有效的 TLS 证书:
- 使用泛域名证书(
*.example.com)最省事,一张证书覆盖所有租户子域名; - 若用单域名证书,需为每个子域名单独配置
ssl_certificate和ssl_certificate_key; - 切勿让某个子域名走 HTTP 而其他走 HTTPS,会导致混合内容警告和安全降级。
不复杂但容易忽略。


















