必须启用 proxy_ssl_server_name on 并配合 proxy_ssl_name $host(或 $http_x_forwarded_host),才能使 Nginx 反向代理在多租户 SaaS 场景下正确传递租户域名级 SNI 信息,避免 TLS 握手失败;同时缓存键需包含 $host 等域名变量以实现租户隔离。

要让 Nginx 在反向代理缓存请求到多租户 SaaS 平台时正确传递 SNI 信息,核心不是只开 proxy_ssl_server_name on,而是确保 TLS 握手时发送的 Server Name 值,精准对应租户域名——否则上游网关无法选出对应证书,TLS 握手失败,缓存层直接中断。
必须启用 SNI 并绑定真实租户域名
Nginx 默认不发 SNI,proxy_ssl_server_name on 是强制开启 Client Hello 中 server_name 扩展的开关。但它默认用 proxy_pass 后写的地址(比如 https://10.0.0.100)作为 SNI 值,这对单 IP 多租户场景完全无效。必须配合 proxy_ssl_name 指令动态注入租户标识:
- 在
location块中添加proxy_ssl_server_name on; - 紧接配置
proxy_ssl_name $host;——$host已标准化(小写、去端口),比$http_host更可靠 - 若使用 CDN 回源,且 CDN 覆盖了原始 Host,需在 CDN 开启“透传原始 Host”,并在 Nginx 改用
proxy_ssl_name $http_x_forwarded_host;
缓存策略需与 SNI 域名对齐
当 Nginx 启用 proxy_cache 时,缓存键(proxy_cache_key)必须包含 SNI 对应的域名维度,否则不同租户的响应会相互覆盖:
- 避免仅用
$scheme$proxy_host$request_uri——$proxy_host是后端地址,固定不变 - 推荐缓存键含
$host或$http_x_forwarded_host,例如:proxy_cache_key "$host$request_uri$is_args$args"; - 同时设置
proxy_cache_valid 200 302 10m;等规则,确保租户级响应按需缓存
upstream 场景下不能依赖自动解析
若用 upstream 定义后端集群(如多个 SaaS 网关实例),Nginx 解析域名后只保留 IP,SNI 信息丢失。此时 proxy_ssl_name 必须显式指定字符串值:
- upstream 块中定义
server gateway.tenant-a.com:443;等具体域名 - 在 location 中仍需写
proxy_ssl_name "gateway.tenant-a.com";(带双引号) - 若租户动态切换,可用
map指令映射:map $host $sni_name {<br> default "default.gateway.com";<br> "app.tenant-b.io" "gateway.tenant-b.com";<br>}
再配置proxy_ssl_name $sni_name;
验证是否真正生效
光看配置是否写对不够,得确认 SNI 值实际发出且被上游识别:
- 在上游 SaaS 网关(如另一台 Nginx)开启 debug 日志:
error_log /var/log/nginx/error.log debug; - 重启后发起租户请求,搜索日志中
client sent server name行,确认输出为app.tenant-a.com这类真实租户域名 - 若日志显示
server name: ""或固定 IP,则说明proxy_ssl_name未生效或变量为空











