HTTPS 深入浅出 - 什么是 SNI?

SNI(Server Name Indication)是 TLS 的扩展,用来解决一个服务器拥有多个域名的情况。

在客户端和服务端建立 HTTPS 的过程中要先进行 TLS 握手,握手后会将 HTTP 报文使用协商好的密钥加密传输。

在 TLS 握手信息中并没有携带客户端要访问的目标地址。这样会导致一个问题,如果一台服务器有多个虚拟主机,且每个主机的域名不一样,使用了不一样的证书,该和哪台虚拟主机进行通信?

和 HTTP 协议用来解决服务器多域名的方案类似,HTTP 在请求头中使用 Host 字段来指定要访问的域名。TLS 的做法,也是加 Host,在 TLS 握手第一阶段 ClientHello 的报文中添加。

SNI 在 TLSv1.2 开始得到支持。从 OpenSSL 0.9.8 版本开始支持。所以基本市场上的终端设备都支持。

我使用的是 Mac,操作系统为 macOS 10.13,openssl 版本为 2.2.7。

使用 WireShark 抓包看一下 ClientHello:

HTTPS 深入浅出 - 什么是 SNI?_第1张图片

可以看到包中的 SNI 扩展字段:

Extension: server_name
    Type: server_name (0x0000)
    Length: 19
    Server Name Indication extension
        Server Name list length: 17
        Server Name Type: host_name (0)
        Server Name length: 14
        Server Name: www.github.com

这里指定了该 TLS 握手的目标域名为 www.github.com

通过 SNI,拥有多虚拟机主机和多域名的服务器就可以正常建立 TLS 连接了。

你可能感兴趣的:(计算机网络,计算机网络的原理和实践)