欢迎光临
我们一直在努力

SNI(Server Name Indication服务器名称指示)介绍(客户端在TLS ClientHello中携带目标域名,让服务器知道应返回哪个域名证书)服务器多域名、ESNI/ECH

文章目录

  • 深入理解 SNI(Server Name Indication)
  • 一、为什么需要 SNI
  • 二、SNI 的核心原理
  • 三、SNI 工作流程
    • 没有 SNI
    • 有 SNI
  • 四、SNI 在 TLS 中的位置
  • 五、SNI 最大的价值
    • 1. 一个 IP 支持多个 HTTPS 网站
    • 2. 降低 HTTPS 部署成本
    • 3. CDN 的基础能力之一
  • 六、Nginx 中的 SNI
  • 七、Kubernetes Ingress 中的 SNI
  • 八、SNI 与 Host Header 的区别
    • SNI
    • Host Header
    • 对比
  • 九、如何查看 SNI
    • 示例
    • 不带 SNI 的情况
  • 十、SNI 的安全问题
  • 十一、ESNI / ECH
    • ESNI(Encrypted SNI)
    • ECH(Encrypted Client Hello)
  • 十二、SNI 与 TLS 终止
  • 十三、典型应用场景
    • CDN
    • API Gateway
    • Kubernetes
    • 云负载均衡
  • 十四、SNI 与 HTTP/2 / HTTP/3
  • 十五、抓包观察 SNI
  • 十六、常见面试题
    • 1. 为什么 HTTPS 需要 SNI?
    • 2. SNI 在哪一层?
    • 3. SNI 和 Host Header 区别?
    • 4. SNI 是否加密?
  • 十七、总结
  • 最后一句话

深入理解 SNI(Server Name Indication)

在现代 HTTPS 通信中,一个 IP 地址往往需要承载多个 HTTPS 网站。 但 TLS 握手发生在 HTTP 请求之前,服务器还不知道客户端到底想访问哪个域名。

这时候,SNI(Server Name Indication)就登场了。

SNI 是 TLS 协议中的一个扩展,用于让客户端在 TLS 握手阶段提前告诉服务器:

“我要访问的域名是哪个。”

它是现代 HTTPS 虚拟主机能力的核心基础之一。


一、为什么需要 SNI

先看一个经典问题。

假设:

同一个服务器 IP:
203.0.113.10

托管两个 HTTPS 网站:
example.com
api.example.com

HTTPS 连接建立时:

  • 客户端先发起 TLS 握手
  • 服务器需要立即返回证书
  • 但此时 HTTP 请求还没发送
  • 服务器并不知道客户端访问哪个域名
  • 于是问题来了:

    服务器该返回哪个 TLS 证书?

    如果没有 SNI:

    • 一个 IP 基本只能对应一个 HTTPS 证书
    • 多 HTTPS 虚拟主机难以实现

    这就是早期 HTTPS 部署成本高的重要原因之一。


    二、SNI 的核心原理

    SNI 的思路非常简单:

    客户端在 TLS ClientHello 中携带目标域名。

    这样服务器在握手阶段就能知道:

    客户端想访问:
    example.com

    于是服务器就可以:

    • 选择正确证书
    • 选择正确 TLS 配置
    • 路由到对应虚拟主机

    三、SNI 工作流程

    下面是 HTTPS 建立连接时的流程。

    没有 SNI

    Client —- TLS Handshake —-> Server

    Server:
    “你访问哪个域名?”

    Client:
    “还没说……”

    服务器无法正确选择证书。


    有 SNI

    Client —- ClientHello(SNI=example.com) —-> Server

    Server:
    “哦,你要访问 example.com”
    “这是对应证书”

    服务器可以正确返回:

    • example.com 的证书
    • 对应 TLS 配置(注:不同域名必须有独立的 TLS 配置,“正确 TLS 配置” = 与目标域名匹配的证书 + 协议参数 + 安全策略)

    四、SNI 在 TLS 中的位置

    SNI 位于:

    TLS ClientHello Extension

    也就是说:

    客户端在 TLS 握手第一阶段就会发送。

    大致结构:

    ClientHello
    ├── TLS Version
    ├── Cipher Suites
    ├── Extensions
    │ └── server_name (SNI)
    │ └── example.com


    五、SNI 最大的价值

    1. 一个 IP 支持多个 HTTPS 网站

    这是最核心价值。

    例如:

    203.0.113.10
    ├── a.com
    ├── b.com
    ├── c.com

    每个域名:

    • 都有独立证书
    • 都能正常 HTTPS

    没有 SNI 基本无法实现。


    2. 降低 HTTPS 部署成本

    以前:

    一个 HTTPS 网站
    ≈ 一个独立 IP

    IPv4 非常昂贵。

    SNI 出现后:

    多个 HTTPS 网站共享同一 IP

    极大推动 HTTPS 普及。


    3. CDN 的基础能力之一

    CDN 边缘节点通常:

    一个 IP 承载成千上万域名

    例如:

    • CDN
    • 云负载均衡
    • API Gateway
    • Ingress Controller

    都严重依赖 SNI。


    六、Nginx 中的 SNI

    Nginx 会根据 SNI 自动选择 server block。

    例如:

    server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate example.crt;
    }

    server {
    listen 443 ssl;
    server_name api.example.com;

    ssl_certificate api.crt;
    }

    客户端:

    SNI=api.example.com

    Nginx:

    返回 api.crt


    七、Kubernetes Ingress 中的 SNI

    Ingress Controller 本质也依赖 SNI。

    例如:

    spec:
    tls:
    hosts:
    api.example.com
    secretName: apicert

    Ingress Controller:

  • 读取 SNI
  • 匹配 host
  • 返回对应证书
  • 因此:

    TLS Host Routing
    本质上就是 SNI Routing


    八、SNI 与 Host Header 的区别

    很多人容易混淆:

    • SNI
    • HTTP Host Header

    它们完全不是一个层次。


    SNI

    发生在:

    TLS 层

    发送时间:

    TLS 握手阶段

    用途:

    选择证书


    Host Header

    发生在:

    HTTP 层

    发送时间:

    TLS 建立完成后

    用途:

    路由 HTTP 请求


    对比

    项目SNIHost Header
    所属层 TLS HTTP
    发送时间 TLS 握手时 HTTP 请求时
    作用 选择证书 路由请求
    是否加密 明文(传统 TLS) HTTPS 下会被加密

    九、如何查看 SNI

    可以使用 OpenSSL。

    示例

    openssl s_client \\
    -connect example.com:443 \\
    -servername example.com

    其中:

    -servername

    就是显式指定 SNI。


    不带 SNI 的情况

    openssl s_client -connect example.com:443

    有些网站会:

    • 返回错误证书
    • TLS 握手失败
    • 返回默认站点

    因为服务器不知道你访问哪个域名。


    十、SNI 的安全问题

    这里有个重要知识点:

    传统 SNI 是明文的。

    即使使用 HTTPS:

    TLS ClientHello
    中的 SNI 仍然可见

    因此:

    • ISP
    • 防火墙
    • 中间网络设备

    仍然能看到:

    你访问了哪个域名

    虽然看不到:

    • 完整 URL
    • Cookie
    • HTTP 内容

    但域名本身仍会暴露。


    十一、ESNI / ECH

    为了解决 SNI 明文问题:

    后来提出:

    ESNI(Encrypted SNI)

    后来演进为:

    ECH(Encrypted Client Hello)

    目标:

    加密 TLS ClientHello

    包括:

    • SNI
    • 扩展信息

    这样网络中间人无法看到目标域名。


    十二、SNI 与 TLS 终止

    很多网关都会做 TLS Termination:

    Client
    ↓ HTTPS
    Load Balancer / Gateway
    ↓ HTTP
    Backend Service

    在 TLS 终止阶段:

    • 网关读取 SNI
    • 选择证书
    • 建立 TLS

    例如:

    • Nginx
    • Envoy
    • HAProxy
    • Kong
    • AWS ALB

    都 heavily 使用 SNI。


    十三、典型应用场景

    CDN

    Cloudflare
    Fastly
    CloudFront


    API Gateway

    Kong
    APISIX
    Traefik


    Kubernetes

    Ingress Controller
    Gateway API


    云负载均衡

    AWS ALB
    GCP Load Balancer
    Azure Front Door


    十四、SNI 与 HTTP/2 / HTTP/3

    SNI 与 HTTP 版本无关。

    即使:

    • HTTP/2
    • HTTP/3

    底层 TLS 仍然需要:

    SNI

    尤其:

    HTTP/3 使用 QUIC + TLS 1.3:

    ClientHello 中依旧存在 SNI


    十五、抓包观察 SNI

    使用 Wireshark:

    过滤:

    tls.handshake.extensions_server_name

    即可看到:

    Server Name: example.com

    这是分析 TLS 流量时非常常见的方法。


    十六、常见面试题

    1. 为什么 HTTPS 需要 SNI?

    因为:

    TLS 握手先于 HTTP 请求

    服务器需要提前知道域名来选择证书。


    2. SNI 在哪一层?

    TLS 层


    3. SNI 和 Host Header 区别?

    • SNI:TLS 阶段选证书
    • Host Header:HTTP 阶段路由请求

    4. SNI 是否加密?

    传统 TLS 中:

    不加密

    ECH 才会加密。


    十七、总结

    SNI 本质上是:

    TLS 握手阶段的“域名提示机制”

    它解决了:

    一个 IP 承载多个 HTTPS 网站

    的问题。

    现代互联网大量基础设施都依赖 SNI:

    • CDN
    • Ingress
    • API Gateway
    • 云负载均衡
    • Service Mesh

    可以说:

    没有 SNI,就没有今天低成本、大规模 HTTPS 的普及。


    最后一句话

    记住这句话:

    Host Header 决定 HTTP 路由
    SNI 决定 TLS 证书

    这是理解现代 HTTPS 网关体系的关键。

    赞(0)
    未经允许不得转载:171主机测评 » SNI(Server Name Indication服务器名称指示)介绍(客户端在TLS ClientHello中携带目标域名,让服务器知道应返回哪个域名证书)服务器多域名、ESNI/ECH
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址