必须显式写proxy_ssl_server_name on,因为Nginx默认关闭SNI扩展,导致Client Hello不携带server_name,使依赖SNI的HTTPS后端(如Traefik、ALB、多域名Nginx)只能返回默认证书或中断连接,引发502、SSL握手失败等错误。

不开启 proxy_ssl_server_name on,Nginx 与 HTTPS 后端建立 TLS 连接时根本不会发 SNI 字段——这是 502、握手失败、证书校验错误的底层原因,不是配置顺序或证书路径问题。
为什么必须显式写 proxy_ssl_server_name on
Nginx 默认关闭 SNI 扩展,哪怕 proxy_pass 指向的是 https://api.example.com,它也只解析 DNS 得到 IP,然后用该 IP 建立 TLS 连接,Client Hello 中不含 server_name。上游若依赖 SNI(如 Istio ingress、Traefik、ALB、多域名共 IP 的 Nginx),就只能返回默认证书或直接中断连接。
- 错误日志典型特征:
SSL_do_handshake() failed、tlsv1 alert internal error、temporarily disabled while SSL handshaking to upstream - 该指令仅在
proxy_pass使用https://协议时生效;若回源走 HTTP,整个proxy_ssl_*系列配置被忽略 - 必须放在
location或upstream对应的proxy_pass同一作用域内,不能只写在http块顶层
proxy_ssl_name 必须动态匹配请求域名,不能硬编码
仅开启 proxy_ssl_server_name on 不够:Nginx 还得知道“该发哪个域名过去”。proxy_ssl_name 就是这个值,它决定 Client Hello 中的 SNI 字段内容。
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 推荐用
proxy_ssl_name $host;:已标准化,不含端口,来自 Host 请求头且经 Nginx 解析(如shop-a.com:8443→shop-a.com) - 若 CDN 回源改写了 Host(如 Cloudflare 默认把
Host改成源站域名),$host就失真,此时应启用 CDN 的“透传原始 Host”并改用proxy_ssl_name $http_x_forwarded_host; - 禁止写死
proxy_ssl_name "api.example.com";除非所有请求都指向同一后端域名;多域名场景下硬编码会导致其他请求 SNI 错配 - 注意:
proxy_ssl_name的值必须和proxy_set_header Host保持一致,否则部分严格网关(如某些 Envoy 配置)会拒绝请求
upstream 场景下 proxy_ssl_name 必须是字符串字面量
当你用 upstream 做负载均衡(例如对接多个 api-01.internal:443、api-02.internal:443),Nginx 不会自动从 upstream 名称推导 SNI 值——它只取 IP,SNI 仍需显式指定。
-
upstream块里只需定义地址:upstream api_backend { server api.internal:443; } - 在
location中使用时,proxy_ssl_name必须写成带引号的字符串:proxy_ssl_name "api.internal";(不能是$host或变量) - 这是因为
upstream解析发生在变量展开之前,Nginx 无法在运行时将变量注入 SNI 字段;只有静态字符串才被允许 - 同时仍要保留
proxy_ssl_server_name on;和proxy_set_header Host "api.internal";
验证 SNI 是否真正发出,别只信配置文件
配置写对了 ≠ 实际生效。SNI 是 TLS 层行为,必须从协议层面确认。
- 最可靠方式:在上游服务器(比如另一台 Nginx)开启 debug 日志:
error_log /var/log/nginx/error.log debug;,触发请求后搜索日志中的client sent server name行,看输出是否为你期望的域名 - 快速模拟:在 Nginx 机器上执行
openssl s_client -connect 10.0.0.100:443 -servername shop-a.com,观察返回的证书 Subject CN 或 SAN 是否匹配shop-a.com - 抓包辅助判断:用
tcpdump -i any port 443 -w test.pcap抓 Nginx 到上游的流量,Wireshark 打开后过滤tls.handshake.type == 1,展开 Client Hello 查看Server Name Indication extension字段 - 常见盲区:上游服务本身不支持 SNI(如旧版 Nginx










