关键是要让Nginx将客户端原始域名作为SNI名称发送给后端云存储,需配置proxy_ssl_server_name on和proxy_ssl_name $host(或$http_x_forwarded_host),并确保proxy_pass使用域名、开启证书校验及正确信任CA链。

要让 Nginx 在反向代理到多证书云存储(如对象存储网关、S3 兼容服务、私有 MinIO 集群等)时正确匹配证书,关键不是只开 proxy_ssl_server_name on,而是让它把客户端请求的原始域名作为 SNI 名称发给后端——否则云存储服务无法识别该返回哪张证书,TLS 握手失败,常见报错为 SSL certificate verify failed 或直接 502/403。
必须启用 SNI 并动态传真实 Host
云存储通常按租户或桶域名区分证书(例如 bucket-a.example.com、bucket-b.example.com),共用同一个 IP 或 VIP。Nginx 默认用 proxy_pass 中写的地址(如 https://10.10.20.30)作为 SNI 值,这会导致后端返回默认证书甚至拒绝连接。
- 在
location或upstream块中添加:proxy_ssl_server_name on; - 紧接着设置:
proxy_ssl_name $host;(推荐)或proxy_ssl_name $http_host; - 确保
proxy_pass使用域名而非 IP,例如proxy_pass https://storage-gw.internal;;若必须用 IP,请配合proxy_ssl_name显式指定变量
应对云存储网关透传 Host 被覆盖的情况
部分云存储前置网关(如自建 Ceph RGW、MinIO Gateway 模式、或某些企业级对象存储)会强制改写 Host 头为内部服务名(如 rgw.internal),导致 $host 失真,SNI 错配。
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
- 在上游网关开启“原始 Host 透传”,通常表现为传递
X-Forwarded-Host头 - Nginx 中改用:
proxy_ssl_name $http_x_forwarded_host; - 同时补上:
proxy_set_header X-Forwarded-Host $host;,方便后端日志溯源
验证 SNI 是否真正生效
光看配置是否写对没用,得确认 TLS 握手发出的 SNI 值就是用户访问的域名。
- 在云存储后端(如 MinIO 日志、RGW debug 日志或 Nginx upstream debug)中开启 TLS 握手日志,搜索
client sent server name字样 - 用 OpenSSL 手动模拟:
openssl s_client -connect storage-gw.internal:443 -servername bucket-a.example.com -showcerts,观察返回证书的 CN 或 SAN 是否匹配 - 对比相同请求走 Nginx 代理前后 SNI 值是否一致(可用 tcpdump 抓包 + Wireshark 查 Client Hello 的 Server Name 扩展)
绕过证书校验仅限测试环境
云存储自签名或内网 CA 签发的证书常导致 proxy_ssl_verify on 失败,但生产环境不应关闭校验。
- 测试阶段可临时加:
proxy_ssl_verify off; - 生产环境务必配置:
proxy_ssl_trusted_certificate /etc/nginx/ssl/storage-ca.crt;,且确保证书链完整(含中间 CA) - 若云存储使用通配符证书(如
*.example.com),注意proxy_ssl_name值需严格匹配其 SAN,不能是 IP 或不相关子域










