← 返回题目列表

TLS SNI 是什么?为什么 HTTPS 多域名部署需要它?

高频 中等 第 11 / 29 题 更新于 2026/07/31
HTTPSTLSSNI证书虚拟主机

简化版

SNI 是 TLS 的 Server Name Indication 扩展,客户端在 TLS 握手早期告诉服务器自己要访问哪个域名。它解决同一 IP 部署多个 HTTPS 站点时,服务器不知道该返回哪张证书的问题。

详细版

没有 SNI 时,TLS 握手先于 HTTP 请求发生,服务器在看到 HTTP Host 之前就必须发证书。如果同一个 IP 上有多个域名,服务器不知道该选哪张证书。

有了 SNI:

  1. 客户端在 ClientHello 中带上目标域名。
  2. 服务器根据 SNI 选择对应证书和 TLS 配置。
  3. 证书域名与用户访问域名匹配,握手继续。
  4. HTTP 请求里仍然会带 Host,用于应用层路由。

SNI 是现代 HTTPS 虚拟主机、CDN、多租户网关的基础能力。注意传统 SNI 明文可见,ECH 是为隐藏 ClientHello 中敏感信息而设计的新机制。

完整版教学

一、为什么 HTTP 的 Host 解决不了 HTTPS 证书选择

HTTP 明文请求里有 Host,服务器可以等请求进来后按域名路由。但 HTTPS 先做 TLS 握手,握手成功后才有 HTTP 请求。服务器必须在握手阶段就发证书,此时还没看到 HTTP Host

HTTPS 顺序:
TCP connect
TLS ClientHello
TLS ServerHello + Certificate   <- 这里就要选证书
HTTP GET / Host: example.com     <- 这时太晚了

所以仅靠 HTTP Host 无法解决“同一 IP 多 HTTPS 域名选证书”的问题。

记忆钩子:Host 是 HTTP 层的门牌号,SNI 是 TLS 握手阶段提前递过去的门牌号。

二、SNI 在握手里怎么工作

客户端发 ClientHello 时,在扩展字段里带上 server_name。服务器读到这个域名后,选择匹配证书、私钥、TLS 参数,再继续握手。

ClientHello:
  extensions:
    server_name = www.example.com

Server:
  choose certificate for www.example.com
  send Certificate

举例:1.2.3.4:443 同时服务 a.comb.com。客户端访问 b.com 时带 SNI=b.com,服务器返回 b.com 的证书;否则可能默认返回 a.com 证书,浏览器报证书域名不匹配。

三、SNI 和 Host 的区别

SNI 和 Host 都携带域名,但层次、时机和用途不同。SNI 用于 TLS 层选择证书,Host 用于 HTTP 层虚拟主机和应用路由。

字段所在层发送时机主要用途
SNITLSClientHello选择证书/TLS 配置
HostHTTPTLS 建立后HTTP 虚拟主机路由
:authorityHTTP/2TLS 建立后类似 Host 的语义

二者通常应该一致。若 SNI 是 a.com,Host 是 b.com,网关可能拒绝、路由错乱或触发安全策略。

四、CDN 和网关为什么依赖 SNI

CDN 节点会承载海量域名。它不可能给每个域名单独占一个 IP,所以必须靠 SNI 在 TLS 握手时选择证书。企业 API 网关、多租户 Ingress 也类似。

CDN edge IP: 203.0.113.10
  ├─ img.a.com     -> cert A
  ├─ static.b.com  -> cert B
  └─ api.c.com     -> cert C

如果客户端太旧不支持 SNI,CDN 只能返回默认证书,这就是很多老设备访问现代 HTTPS 站点失败的原因之一。

五、SNI 的隐私问题和 ECH

传统 SNI 在 ClientHello 中是明文的,中间网络设备能看到用户要访问的域名。即使 HTTPS 加密了 HTTP 内容,SNI 仍可能泄露访问目标。

可见信息:
IP = 203.0.113.10
SNI = private.example.com

不可见信息:
URL path、Cookie、HTTP body

ECH(Encrypted ClientHello)尝试加密 ClientHello 中的敏感扩展,包括真实 SNI。但它依赖客户端、DNS、服务端/CDN 支持,部署还在逐步推进。

六、排障时怎么判断 SNI 问题

SNI 错误常表现为证书域名不匹配、默认站点证书、某些客户端访问失败。排查时可以用 openssl s_client -servername 指定 SNI 对比结果。

openssl s_client -connect 1.2.3.4:443 -servername www.example.com

如果不带 -servername 和带上后证书不同,就说明服务器按 SNI 选择证书。负载均衡、Nginx、Ingress 配置错误时,SNI 是排查重点。

七、常见误区与追问

  • 误区:Host 能决定 HTTPS 返回哪张证书。 证书在 HTTP 请求前就要发出,必须靠 TLS 层的 SNI。
  • 误区:SNI 会加密隐藏域名。 传统 SNI 明文可见,ECH 才是加密 ClientHello 的方向。
  • 误区:SNI 和 Host 可以随便不一致。 不一致会导致证书、路由和安全策略问题。
  • 追问:不支持 SNI 的客户端会怎样? 服务器通常返回默认证书,可能造成证书域名不匹配。
  • 追问:CDN 为什么需要 SNI? 一个边缘 IP 承载多个域名,必须在握手时选择正确证书。
  • 追问:如何排查 SNI?openssl s_client -servername、抓包 ClientHello 或查看网关访问日志。

八、加强记忆

SNI 记成“TLS 版 Host,但更早出现”:它在 ClientHello 里告诉服务器目标域名,用来选证书;HTTP Host 在 TLS 之后才出现,用来做应用路由。多域名 HTTPS、CDN、Ingress 都离不开它。