首页/网络/协议速查/SNI 服务器名称指示

SNI 服务器名称指示

ClientHello 里带上目标域名,让同一 IP 的多站点各用各的证书;它本身不加密,是旁路探测 HTTPS 域名的常见依据。

协议速查网络更新于 2026-10-13

SNI 是什么

SNI(Server Name Indication)是 TLS 握手中 ClientHello 携带的扩展:客户端在第一条消息里就把要访问的域名(明文)告诉服务器。它解决的是「一个 IP 上托管多个 HTTPS 站点时,服务器该出示哪张证书」——没有 SNI,服务器只能回默认证书,域名一多必然证书不匹配。该扩展由 RFC 3546 引入,现行规范是 RFC 6066,TLS 1.3 中依然保留(另有加密版本 ECH 在推进)。

基本信息

所在位置TLS ClientHello 中的 server_name 扩展
适用平台所有现代浏览器、curl、OpenSSL 及 Nginx/Apache/HAProxy 等
规范RFC 6066 §3(原 RFC 3546)
可见性握手阶段明文传输,链路设备可解析
作用服务器据此选择证书与虚拟主机

典型使用场景

  • 同一台服务器用一张 IP 承载多个不同域名站点,按域名返回各自证书
  • 排查「证书域名不匹配」:确认客户端是否真的发出了 SNI
  • 老客户端或直接以 IP 访问时,验证默认站点会给出哪张证书
  • 在无 DNS 环境用 --resolve 强制指定域名做 HTTPS 验证
  • 分析链路设备是否按 SNI 做阻断或审计

带 SNI 与不带 SNI 对比

带 SNI 与不带 SNI 对比
# 带 SNI:服务器按域名给出对应证书
openssl s_client -connect 203.0.113.10:443 -servername www.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
# 不带 SNI:通常落到默认站点,证书可能与域名不符
openssl s_client -connect 203.0.113.10:443 </dev/null 2>/dev/null | openssl x509 -noout -subject
# 指定域名但不改 DNS,验证站点证书
curl -v --resolve www.example.com:443:203.0.113.10 https://www.example.com 2>&1 | grep -i -E 'subject|issuer'

常见现象与归因

现象原因验证方法
同 IP 两个域名,只有一个证书报警该域名不是默认 server,请求也没带 SNI加 -servername 指定域名复测是否恢复正常
浏览器正常但脚本请求失败老版本客户端或直连 IP 时不发 SNI抓 ClientHello 看有无 server_name 扩展
特定域名握手被重置中间设备按 SNI 关键字阻断换出口线路或改用 IP 直连做对比
证书域名与访问域名不一致默认证书配置错或虚拟主机顺序问题openssl x509 查看 SAN 列表
Nginx 中用 listen 443 ssl default_server 指定无 SNI 请求落到的默认站;建议把默认证书配成主站证书,避免直接访问 IP 时看到无关域名。
SNI 本身不加密也不认证:域名会被路径上的设备记录,隐私敏感场景要评估 ECH 等加密方案;同时不要把它当成任何安全控制手段。

易错点

  • 把 SNI 当成安全机制:它明文传输且可被伪造,只用于选择证书
  • 多个虚拟主机都没配 default_server,无 SNI 请求落到第一个 server 块,返回无关证书
  • 某些防火墙按 SNI 阻断,表现为「特定域名 https 握手重置」,换 IP 直连仍复现,容易误判成服务器问题
  • 只测带 SNI 的访问就宣布上线,忽略老客户端与 IP 直连场景的证书报错

数据来源与参考

  • RFC 6066 §3
  • RFC 8744

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌