随着 HTTPS 成为安全 Web 通信的标准,一个新的挑战出现了:如何在单个 IP 地址上托管多个受 SSL 保护的网站?在 HTTPS 早期,每个安全域名都需要自己的专用 IP,因为服务器在握手阶段无法判断该提供哪张 SSL 证书。全球仅有约 40 亿个 IPv4 地址,托管服务商急需一种从单个 IP 为多个安全网站提供服务的方法。服务器名称指示(SNI)由此诞生,解决了这一限制。

什么是服务器名称指示(SNI)?

SNI 是 TLS 协议中的一项特性,允许浏览器在握手一开始就告诉服务器它试图连接的主机名。这看似小事,却影响巨大——它使一个拥有单个 IP 的服务器能够为不同域名提供多张 SSL 证书。在 SNI 出现之前,这不可能实现:若服务器托管多个域名,在手握阶段只能提供单张证书,这意味着要么使用通配符证书或 SAN 证书,要么为每个域名分配专用 IP。SNI 彻底改变了这一点,如今浏览器会在 Client Hello 消息中包含目标主机名,让服务器获得在 SSL 连接过程中提供正确证书所需的信息。

SNI 在 HTTPS 连接中如何工作

浏览器尝试连接安全网站的第一步是 Client Hello 消息,它启动 TLS 握手,告诉服务器"我想开始一个安全会话"。早先的握手不提及目标域名,当同一 IP 托管多个站点时,服务器不得不盲目响应一张证书。有了 SNI,浏览器在 Client Hello 消息中直接包含预期主机名,服务器便可返回请求域名对应的正确 SSL 证书。这一微小改动使虚拟主机、CDN、反向代理等共享基础设施能够在单个 IP 背后为大量域名正确支持 HTTPS。

为何 SNI 对单 IP 托管多张 SSL 证书至关重要

在 SNI 之前,若要托管多个启用 HTTPS 的域名,每个都需要自己的 IP。这不仅不便,而且昂贵且不可持续,尤其在 IPv4 地址日益短缺的情况下。如今,单台拥有单个 IP 的服务器就能为其托管的每个域名提供正确的 SSL 证书。许多行业依赖 SNI 开展核心业务:共享托管服务商常在单台机器上运行成百上千个域名;CDN 需要在分布式网络上为众多客户域名动态提供 SSL;SaaS 公司或电商平台等组织在同一套基础设施下管理多个品牌域名或子域名。通过消除每站点专用 IP 的需求,SNI 显著降低了基础设施成本与 IP 消耗,也简化了扩展——你可以随时启用新的安全域名而无需重新配置网络或申请更多 IP。

SNI 与 SAN 证书:托管多域名哪种更好?

在托管多个启用 HTTPS 的域名时,SNI 与 SAN 证书是最常见的两种方案,它们解决同一问题但方式迥异。SNI 允许服务器在单个 IP 上使用多张 SSL 证书,灵活且每域名可独立拥有自己的证书,适合频繁增删域名的场景。SAN(Subject Alternative Name)证书常被称为多域名证书,允许单张证书覆盖多个域名。

特性SNISAN 证书
每域名独立证书是否,所有域名共用一张证书
证书续期难度单个域名可独立管理续期续期会影响所有域名
IP 地址要求单个 IP 即可单个 IP 即可
浏览器兼容性极老的浏览器不支持对旧设备兼容性更好
域名间隐私证书各自独立所有域名在一张证书中可见

若你追求灵活性、按域名控制,或托管大量互不相关的站点,请使用 SNI;若你的域名紧密耦合(如同一品牌下的产品站),或需要支持老旧浏览器与遗留设备,请使用 SAN 证书。在现代部署中,SNI 通常是首选,并常与可按域名签发和续期证书的自动化工具搭配使用。

SNI 的局限与安全顾虑

虽然 SNI 解决了 HTTPS 托管中的一大难题,但它并非没有局限,尤其在兼容性与隐私方面。

老旧浏览器与操作系统:部分遗留系统不支持 SNI,例如未装 Service Pack 3 的 Windows XP 上的 Internet Explorer、Android 2.x 及更早版本、某些极老的 Java 客户端或嵌入式设备。这些客户端不在 TLS 握手中发送主机名,服务器便不知该提供哪张证书,可能回退到默认证书或终止连接。

证书不匹配风险:若客户端不支持 SNI 且使用了回退证书,可能不匹配请求域名,直接触发"您的连接非私密"的 HTTPS 警告,瞬间削弱用户信任。

主机名未加密:SNI 的主要安全隐患在于它在 TLS 握手中以明文发送主机名,使 ISP 与公共网络上的攻击者可见。即便握手完成后流量被加密,连接建立过程仍存在弱安全环节。为此,加密 SNI(ESNI)作为 TLS 1.3 的一部分被引入,并正演进为加密客户端 Hello(ECH),旨在连初始主机名也保持私密。SNI 仍被广泛使用且有效,但了解其短板有助于在设计时规避,尤其在隐私或向后兼容至关重要时。

SNI 兼容性:站点所有者须知

如今 SNI 几乎处处受支持。除非你的用户停留在过时系统,否则无需担心。桌面浏览器(Chrome、Firefox、IE 7+、Safari、Opera)、移动浏览器(iOS Safari 4.0+、Android 3.x+、Windows Phone 7+)以及 Apache、Nginx、IIS 8+、LiteSpeed、Caddy 等 Web 服务器,还有 OpenSSL 0.9.8f、Java 1.7+、Python 2.7.9+/3.2+、Node.js、Go 等编程库均支持 SNI。除遗留企业系统或冷门 IoT 设备外,SNI 已被广泛支持。

如何在 Web 服务器上启用 SNI

启用 SNI 通常只需正确配置 Web 服务器,现代环境默认支持,无需特殊许可或额外费用。

Apache(启用 mod_ssl 后,配置基于名称的虚拟主机并指定不同 SSL 证书时 SNI 自动生效):

<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /path/to/example.crt
SSLCertificateKeyFile /path/to/example.key
</VirtualHost>

<VirtualHost *:443>
ServerName blog.example.com
SSLEngine on
SSLCertificateFile /path/to/blog.crt
SSLCertificateKeyFile /path/to/blog.key
</VirtualHost>

Nginx(使用多个 server 块并各自指定 server_name 与证书):

server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/example.crt;
ssl_certificate_key /etc/ssl/example.key;
}

server {
listen 443 ssl;
server_name blog.example.com;
ssl_certificate /etc/ssl/blog.crt;
ssl_certificate_key /etc/ssl/blog.key;
}

只要 Nginx 版本支持 TLS(多数都支持),SNI 便会自动选用正确证书。SNI 也支持多数现代负载均衡器与 CDN,包括 AWS Application Load Balancer、Cloudflare、Fastly、Akamai,以及 HAProxy、Envoy 等反向代理。在这类环境中启用 SNI 涉及上传 SSL 证书并将其映射到相应主机名,平台会在配置成功后于 TLS 握手中自动选对证书。

总结

服务器名称指示(SNI)虽不为多数用户所察觉,却在现代 Web 运作中扮演关键角色。它让多个安全网站得以共享同一 IP 地址,这在 HTTPS 早期每个安全站点都需专用 IP 时并不可行。SNI 通过让浏览器在 TLS 握手中告知服务器目标域名改变了这一点,对管理成百上千万域名的 CDN、托管服务商和大型平台影响深远。没有 SNI,规模化 HTTPS 将需要数量不可能的 IP 地址。