nginx反向代理多证书后端需同时启用proxy_ssl_server_name on和proxy_ssl_name $host,否则tls握手失败导致502或证书错误;sni值必须动态匹配用户访问域名,禁用写死配置,并在cdn场景下改用$http_x_forwarded_host确保准确透传。

要让 Nginx 在反向代理到多证书后端(比如单 IP 托管多个域名、SaaS 多租户、云存储网关等)时不出错,关键不是只写 proxy_ssl_name,而是它必须和 proxy_ssl_server_name on 配合使用,并且值要准确反映用户真正访问的域名。否则 TLS 握手直接失败,返回 502 或证书校验错误。
必须成对启用:proxy_ssl_server_name + proxy_ssl_name
proxy_ssl_server_name on 是开关,不加它,Nginx 根本不会在 TLS ClientHello 中发送 SNI 字段——哪怕你写了 proxy_ssl_name $host 也白搭。开启之后,Nginx 才会把 proxy_ssl_name 的值填进 SNI 扩展里发给后端。
- location 块中必须同时出现这两行:
proxy_ssl_server_name on;proxy_ssl_name $host; - 推荐用
$host(自动标准化、小写、不含端口),比$http_host更可靠 - 单独写其中一条,等于没配
动态传值优先,避免写死
后端如果是多域名共存(如 tenant-a.example.com、tenant-b.example.com 共用一个 VIP),SNI 必须随请求变化。写死 proxy_ssl_name "api.example.com" 只适用于所有流量都指向同一后端域名的极简场景。
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 正确做法:用变量,例如
proxy_ssl_name $host;或proxy_ssl_name $upstream_sni;(配合 map 提取) - 错误做法:写死为内部域名(
"backend.internal")或 IP,上游证书 SAN 不匹配,握手必败 - 如果用 upstream 块做负载均衡,
proxy_ssl_name不能省略,且值必须是字符串(加引号),如proxy_ssl_name "api.example.com";
应对 CDN 或网关覆盖 Host 头的情况
Cloudflare、阿里云全站加速、WAF 等常会改写回源 Host 头为源站配置名(如 origin.example.com),导致 $host 失真,SNI 错配。
- 在 CDN 控制台开启“透传原始 Host”,通常表现为传递
X-Forwarded-Host头 - Nginx 中改用:
proxy_ssl_name $http_x_forwarded_host; - 顺手加上:
proxy_set_header X-Forwarded-Host $host;,方便后端日志溯源和业务识别
验证是否真正生效
配置写对不等于跑对,得确认 TLS 握手发出的 SNI 值就是用户访问的域名。
- 在上游服务(如另一台 Nginx 或 MinIO)开启 debug 日志,搜索
client sent server name - 用 OpenSSL 手动模拟:
openssl s_client -connect backend.internal:443 -servername your-domain.com -showcerts,看返回证书的 SAN 是否匹配 - 若用 tcpdump 抓包,Wireshark 中展开 TLS → Client Hello → Extension → Server Name,直接查看字段内容










