必须开启proxy_ssl_server_name on,否则Nginx不发送SNI导致多租户云存储无法识别租户域名、TLS握手失败,缓存无法建立;需配合proxy_ssl_name $host和proxy_set_header Host $host确保SNI与Host一致,并在proxy_cache_key中包含$host以隔离租户缓存。

要让 Nginx 在代理请求到多租户云存储(如对象存储、SaaS 文件服务)时,正确完成 HTTPS 回源并命中缓存,关键不是只配 proxy_cache,而是确保 TLS 握手阶段就精准传递租户域名——这必须靠 proxy_ssl_server_name 和配套指令协同实现。
为什么多租户回源必须开启 proxy_ssl_server_name
多租户云存储常采用“单 IP + 多域名 + 独立证书”架构(例如 tenant-a.example.com、tenant-b.example.com 共享同一组后端节点)。Nginx 默认不发送 SNI 字段,上游只能返回默认或泛域名证书。一旦证书 SAN 不匹配 proxy_ssl_name 指定的值,就会触发 TLS 握手失败,缓存根本无法建立。
- 不启用
proxy_ssl_server_name on→ Client Hello 无 SNI → 上游无法识别目标租户 → 返回错误证书或直接断连 - 即使缓存配置完整(
proxy_cache、proxy_cache_key等),连接层失败则整个请求终止,缓存形同虚设
核心三步配置:SNI 开关 + 动态域名 + Host 一致性
以下配置需放在 location 或 upstream 块中,缺一不可:
-
启用 SNI 扩展:
proxy_ssl_server_name on; -
动态传租户域名:
proxy_ssl_name $host;(推荐)或proxy_ssl_name $http_x_forwarded_host;(若 CDN 已透传原始 Host) -
保持 Host 请求头一致:
proxy_set_header Host $host;(避免后端因 Host 不匹配拒绝请求或返回 404)
应对 CDN 或边缘网关导致的 Host 失真
当流量经 Cloudflare、阿里云全站加速等 CDN 回源至你的 Nginx,再由 Nginx 二次回源至云存储时,CDN 往往会覆盖 Host 头为源站域名(如 origin.example.com),导致 $host 不再是用户原始租户域名。
- 在 CDN 控制台开启“透传原始 Host”,通常表现为自动添加
X-Forwarded-Host头 - Nginx 中改用:
proxy_ssl_name $http_x_forwarded_host; - 同时补上:
proxy_set_header X-Forwarded-Host $host;,方便云存储侧日志或鉴权识别真实租户
缓存与回源联动的关键细节
仅解决 TLS 握手还不够,要让缓存真正生效,还需注意:
-
proxy_cache_key应包含租户标识,例如:proxy_cache_key "$scheme$request_method$host$uri$is_args$args";,避免不同租户的同名资源互相覆盖 - 若云存储要求特定 SNI 值(如强制使用
storage.tenant-a.com而非tenant-a.example.com),则proxy_ssl_name需映射该值,可用 map 块做域名转换 - 确认 OpenSSL 版本 ≥ 1.0.2h(Nginx 编译时依赖),旧版本不支持动态 SNI 设置


















