使用不同的 IP 地址是否有助于支持具有较旧 SSL 实现的浏览器?

信息安全 tls 证书
2021-08-11 15:38:45

我们有一个带有两个通配符证书的站点:*.foo.com*.bar.foo.com. 我们所有的子域都解析到相同的 IP 地址。

较新的浏览器可以正常工作,但例如 IE7 就不行。我对这个问题的理解是:在旧版本的 SSL(TLS 1 之前)中,域名本身是加密的。因此,当请求进入服务器时,就会出现先有鸡还是先有蛋的问题:

  • 它需要解密请求以找出域,但是
  • 它需要知道域才能选择正确的证书来解密请求

认为这是问题所在,这也与不同的子域指向同一个 IP 的事实有关。

认为如果我们为这些子域使用不同的 IP 地址,服务器可以通过这种方式区分请求并选择正确的证书。

这个对吗?

3个回答

您的详细信息是错误的(这不是加密本身的问题),但您的总体思路是正确的。

SSL/TLS中,客户端首先连接到服务器并发送一条“ClientHello”消息,说明“我希望与你做一些 SSL”。这发生在 TCP 层之上,以及与 HTTP 相关的任何东西之下;只有在 SSL 隧道创建后,才会在 SSL 隧道中发送 HTTP 请求。SSL 隧道的创建是通过称为“握手”的过程完成的,其中 ClientHello 消息是第一步。

在握手期间,服务器将他的证书发送给客户端。证书包含服务器名称和他的公钥,并由证书颁发机构签名。只有在“验证”证书后,客户端才会接受使用公钥,该过程需要以下两个步骤:

  • 客户端必须验证证书颁发机构对证书的签名。不过,它可能必须在此之前验证证书颁发机构自己的证书;该过程是递归的。证书验证充满了复杂的细节,我将在这里跳过,因为它们与本次讨论无关。
  • 客户端必须检查预期的服务器名称是否确实出现在证书中。因为这就是证书的重点:将公钥(用于加密的数学对象)绑定到身份(服务器名称);只有在以某种方式验证公钥确实是服务器控制相应私钥的那个之后,证书颁发机构才会颁发证书(即签名) 。

一旦客户端合理地确定他拥有正确的公钥,他就可以完成握手:根据协商的密码套件,这需要非对称加密或数字签名;无论哪种方式,服务器都将使用他的私钥。在握手结束时,客户端和服务器最终都会获得一个共享的会话密钥,使用该密钥将进行更多的加密,这次是对称加密。

然后,也只有这样,“应用程序数据”才能通过隧道传输。对于 HTTPS,“应用程序数据”包含实际的 HTTP 请求。

现在,问题如下:客户端想要联系给定的服务器(名称如www.foo.com),但该预期的服务器名称仅与 HTTP 请求一起发送到服务器。在 TCP 级别,仅存在 IP 地址。当服务器需要发送他的证书时,他只知道它是在某个 IP 地址下联系的,但它不知道客户端试图以什么名字来定位它。然而,服务器必须发送一个包含正确名称的证书。当服务器只为每个公共 IP 托管一个 HTTPS 服务器时,这很简单:只有一个可能的名称。由于多个 HTTPS 服务器共享相同的公共 IP,服务器必须进行一些占卜,这在一般情况下对于计算机来说是不可能的(对于占卜者来说已经相当困难了)。

可能的解决方案:

  • 在证书中嵌入多个名称。该服务器只有一个证书,但它包含共享公共 IP 的所有 HTTPS 服务器的名称。这在 X.509 中作为Subject Alt Names扩展受到支持。这要求客户端浏览器以应有的方式实际支持标准,因此这不是给定的。该页面声称大多数浏览器都支持它,但我认为这至少需要进行一些广泛的测试(特别是当扩展中有多个名称并且这些名称包含“wildchar”时*)。

  • 在开始时通过额外的交换来增强协议。这称为STARTTLS选项。在 HTTP 上下文中,这意味着客户端将首先发送一个包含服务器名称的特殊 HTTP 请求,并使用一个特殊命令(即“STARTTLS”而不是普通的“GET”)来表明客户端参与的意愿在同一连接上立即进行 SSL/TLS 握手这曾在某个时候为 HTTP 提出过,但被拒绝了,因为它不适用于现有的 HTTP 代理。STARTTLS 用于其他协议,例如 SSMTP 或 IMAPS,在这些协议中,实际连接始终可用。

  • 让客户端在握手中尽早发送预期的服务器名称,例如通过在 ClientHello 消息中的某处走私它。这称为服务器名称指示这就是 HTTPS 世界的目标。

SNI 最大的问题是 Windows XP 上的 IE 不支持它(它需要 IE 8+,但也需要 Vista 或更高版本;因为 IE 使用的实际 SSL 代码来自操作系统,而不是 IE 本身)。因此,您必须以某种方式诱使使用 WinXP 的客户端切换到 Firefox、Chrome 或其他了解 SNI 并执行 SSL 的浏览器,而不是依赖操作系统提供的实现。

是的。为每个启用 SSL 的域拥有一个单独的 IP 仍然是标准做法。SSL的服务器名称指示扩展看起来相当令人印象深刻。然而,对于大多数驾驶具有显着流量的网站的人来说,饱和还不足以放弃独特的 IP 安排。

从应用协议的角度来看,TLS 属于较低层。这意味着 TLS 握手通常在应用程序协议启动之前执行(STARTTLS 情况除外)。应用层提供基于名称的虚拟服务器功能,所有共同托管的虚拟服务器共享相同的证书,因为服务器必须在 ClientHello 消息之后立即选择并发送证书。这在托管环境中是一个大问题,因为这意味着要么在所有客户之间共享相同的证书,要么为每个客户使用不同的 IP 地址。

X.509 提供了两种已知的解决方法:

  1. 如果所有虚拟服务器都属于同一个域,则可以使用通配符证书。除了可能存在问题的松散主机名选择之外,对于如何匹配通配符证书没有共同的协议。根据所使用的应用程序协议或软件应用不同的规则。
  2. 在 subjectAltName 扩展中添加每个虚拟主机名。主要问题是每当添加新的虚拟服务器时都需要重新颁发证书。

为了提供服务器名称,RFC 4366 传输层安全 (TLS) 扩展允许客户端在扩展的 ClientHello 消息中包含服务器名称指示扩展 (SNI)。此扩展立即提示服务器客户端希望连接的名称,因此服务器可以选择适当的证书发送给客户端。