题 同一IP地址和同一端口上的多个SSL域?


这是一个 典型问题 关于在同一IP上托管多个SSL网站。

我的印象是每个SSL证书都需要它自己独特的IP地址/端口组合。但是 回答我发布的上一个问题 与这种说法不一致。

使用来自该问题的信息,我能够获得多个SSL证书,以便在相同的IP地址和端口443上工作。我很困惑为什么这个工作给出了上面的假设并且被其他人强化了每个SSL域网站上的同一台服务器需要自己的IP /端口。

我怀疑我做错了什么。可以通过这种方式使用多个SSL证书吗?


107
2018-02-04 22:36




这个Q机构说多个证书,答案是正确的。但标题说多个域和你 可以有多个域,一个证书 (并且没有SNI),请参阅 serverfault.com/questions/126072/... 和 serverfault.com/questions/279722/... 也交叉安全.SX。 - dave_thompson_085


答案:


有关Apache和SNI的最新信息,包括其他HTTP特定RFC,请参阅 Apache Wiki


FYII:“一个IP上的多个(不同的)SSL证书”由TLS升级的魔力带给您。 它适用于较新的Apache服务器(2.2.x)和合理的最新浏览器(不知道我的头脑版本)。

RFC 2817(在HTTP / 1.1中升级到TLS)具有血腥的细节,但基本上它适用于很多人(如果不是大多数人)。
您可以使用openssl重现旧的时髦行为 s_client 命令(或任何“足够老”的浏览器)。

编辑添加:显然 curl 可以比openssl更好地向您展示这里发生的事情:


在SSLv3

mikeg@flexo% curl -v -v -v -3 https://www.yummyskin.com
* About to connect() to www.yummyskin.com port 443 (#0)
*   Trying 69.164.214.79... connected
* Connected to www.yummyskin.com (69.164.214.79) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/local/share/certs/ca-root-nss.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: serialNumber=wq8O9mhOSp9fY9JcmaJUrFNWWrANURzJ; C=CA; 
              O=staging.bossystem.org; OU=GT07932874;
              OU=See www.rapidssl.com/resources/cps (c)10;
              OU=Domain Control Validated - RapidSSL(R);
              CN=staging.bossystem.org
*    start date: 2010-02-03 18:53:53 GMT
*    expire date: 2011-02-06 13:21:08 GMT
* SSL: certificate subject name 'staging.bossystem.org'
       does not match target host name 'www.yummyskin.com'
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
curl: (51) SSL: certificate subject name 'staging.bossystem.org'
does not match target host name 'www.yummyskin.com'

使用TLSv1

mikeg@flexo% curl -v -v -v -1 https://www.yummyskin.com
* About to connect() to www.yummyskin.com port 443 (#0)
*   Trying 69.164.214.79... connected
* Connected to www.yummyskin.com (69.164.214.79) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/local/share/certs/ca-root-nss.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: C=CA; O=www.yummyskin.com; OU=GT13670640;
              OU=See www.rapidssl.com/resources/cps (c)09;
              OU=Domain Control Validated - RapidSSL(R);
              CN=www.yummyskin.com
*    start date: 2009-04-24 15:48:15 GMT
*    expire date: 2010-04-25 15:48:15 GMT
*    common name: www.yummyskin.com (matched)
*    issuer: C=US; O=Equifax Secure Inc.; CN=Equifax Secure Global eBusiness CA-1
*    SSL certificate verify ok.

68
2018-02-04 23:46



那非常有用 - 谢谢!有关如何为TLS而不是SSL配置Apache的任何信息? - Josh
我认为Apache 2.2只需要在其密码列表中启用TLS位。我承认我从来没有看到整个“从SSL升级到TLS”这一点直到这两个网站。我对TLS文档的理解是,谈判这种升级是一种允许的(但不寻常的)情况...... - voretaq7
这是我第一次看到它,我仍然试图把我的下巴从地板上拉下来...... - Josh
好吧,我的答案长度增加了三倍 - 显然curl可以同时进行SSLv3和TLSv1谈判,这样我就可以显示失败和成功。我希望我有一个协议调试器方便显示神奇的部分。 (还测试并高兴地报告johnlai2004的服务器正确否认SSLv2连接:-) - voretaq7
这非常有帮助,我希望johnlai2004接受你的答案。非常感谢! - Josh


是的,但有一些警告。

这是通过服务器名称指示(Transport Layer Security)的扩展来实现的。

什么是服务器名称指示?

服务器名称指示 (RFC 6066;废弃 RFC 4366RFC 3546)是对...的延伸 传输层安全性 它允许客户端告诉服务器它尝试访问的主机的名称。

根据规范,SNI与TLS 1.0及更高版本兼容,但实现可能有所不同(见下文)。它不能与SSL一起使用,因此连接必须协商TLS(请参阅 RFC 4346附录E.)用于SNI。这通常会在支持的软件中自动发生。

为什么需要SNI?

在正常情况下 HTTP 连接时,浏览器通过服务器通知服务器它尝试访问的服务器的主机名 Host: 头。这允许单个IP地址上的Web服务器为多个主机名提供内容,这通常被称为 基于名称的虚拟主机

另一种方法是为要提供的每个Web主机名分配唯一的IP地址。这通常是在网络的早期阶段完成的,之后人们普遍知道IP地址将耗尽且保护措施开始,并且仍然以这种方式为SSL虚拟主机(不使用SNI)完成。

由于这种传输主机名的方法需要已建立连接,因此它不适用于SSL / TLS连接。在建立安全连接时,Web服务器必须已经知道它将向客户端提供哪个主机名,因为Web服务器本身正在设置安全连接。

SNI通过让客户端将主机名作为TLS协商的一部分进行传输来解决此问题,以便服务器已经知道应该使用哪个虚拟主机来为连接提供服务。然后,服务器可以使用证书和配置来获取正确的虚拟主机。

为什么不使用不同的IP地址?

HTTP Host: 标题被定义为允许从单个IP地址提供多个Web主机,因为IPv4地址短缺,早在20世纪90年代中期就被认为是一个问题。在共享Web托管环境中,可以使用单个IP地址以这种方式提供数百个独立的,不相关的Web站点,从而节省地址空间。

然后,共享托管环境发现,IP地址空间的最大消费者是安全网站需要具有唯一IP地址,因此需要将SNI作为通往IPv6的权宜之计。今天,如果没有明显的理由,有时很难获得少至5个IP地址(/ 29),这通常会导致部署延迟。

随着IPv6的出现,不再需要这种地址保护技术,因为单个主机可以分配比它今天整个互联网所包含的IPv6地址更多的IPv6地址,但这些技术可能仍将在未来用于服务传统IPv4连接。

注意事项

某些操作系统/浏览器组合不支持SNI(见下文),因此使用SNI并不适合所有情况。定位此类系统/浏览器组合的网站必须放弃SNI并继续为每个虚拟主机使用唯一的IP地址。

特别值得注意的是,Windows XP上没有版本的Internet Explorer支持SNI。由于这种组合仍然代表了一个显着的(但稳步下降; 2012年12月根据NetMarketShare的互联网流量的约16%)部分互联网流量,SNI将不适合针对这些用户群的网站。

支持

许多(但不是全部)常用软件包支持SNI。

(此列表中的遗漏并不一定意味着缺乏支持;这意味着我可以输入的数量有限,或者我无法在搜索中快速找到信息。如果您的软件包未列出,则搜索因为它的名字加上 sni 应该揭示是否存在支持以及如何设置支持。)

图书馆支持

大多数软件包依赖外部库来提供SSL / TLS支持。

  • GNU TLS
  • JSSE(Oracle Java)7或更高版本, 仅作为客户
  • libcurl 7.18.1或更高版本
  • NSS 3.1.1或更高版本
  • OpenSSL 0.9.8j或更高版本
    • OpenSSL 0.9.8f或更高版本,带有配置标志
  • Qt 4.8或更高

服务器支持

大多数流行服务器软件的当前版本都支持SNI。大多数安装说明适用于:

客户支持

大多数当前的Web浏览器和命令行用户代理都支持SNI。

桌面

  • Chrome 5或更高版本
    • Windows XP上的Chrome 6或更高版本
  • Firefox 2或更高版本
  • Internet Explorer 7或更高版本,在Windows Vista / Server 2008或更高版本上运行
    • 无论IE版本如何,Windows XP上的Internet Explorer都不支持SNI
  • Konqueror 4.7或更高
  • Opera 8或更高版本(可能需要启用TLS 1.1才能运行)
  • Windows Vista / Server 2008或更高版本或Mac OS X 10.5.6或更高版本上的Safari 3.0

移动

  • 适用于3.0 Honeycomb或更高版本的Android浏览器
  • iOS 4或更高版本的iOS Safari
  • Windows Phone 7或更高版本

命令行

  • cURL 7.18.1或更高版本
  • wget 1.14或更高(分发可能已经向后移动了一个 补丁 对于SNI支持)

没有支持

  • 黑莓浏览器
  • Windows XP上的Internet Explorer(任何版本)

(注意:此答案的一些信息来自 维基百科。)


96
2017-08-14 23:05



好多了:-)希望这可能最终获得比目前接受的更高的分数,除了顶部的最后一次编辑,遗憾的是大部分不正确。 - Bruno
@Bruno如果你找到几百人投票,我当然不会抱怨。 :) - Michael Hampton♦
最新的BlackBerry Browser(10?)使用最新版本的WebKit,因此它很可能现在支持SNI。 - dave1010


问题:

当Web客户端和Web服务器通过HTTPS相互通信时, 最先 需要发生的事情是安全握手。

以下是此类握手的简化示例:

tls handshake

如果这是HTTP而不是HTTPS,客户端发送的第一件事就是这样:

GET /index.html HTTP/1.1
Host: example.com

这使得单个IP地址上的多个虚拟主机成为可能,因为服务器确切地知道客户端想要访问哪个域,即example.com。

HTTPS是不同的。就像我之前说的那样,握手先于其他一切。如果您查看上面说明的握手的第三步(证书),服务器需要在握手时向客户端提供证书,但不知道客户端尝试访问哪个域名。服务器唯一的选择是每次都发送相同的证书,即默认证书。

您仍然可以在Web服务器上设置虚拟主机,但服务器始终会向每个客户端发送相同的证书。如果您尝试在服务器上托管example.com和example.org网站,则当客户端请求HTTPS连接时,服务器将始终为example.com发送证书。因此,当客户端通过已建立的HTTPS连接请求example.org时,会发生以下情况:

enter image description here

此问题有效地将您可以通过HTTPS服务的域的数量限制为每个IP地址一个。

解决方案:

解决此问题的最简单方法是让客户端告诉服务器它想要访问哪个域 在握手期间。这样服务器就可以提供正确的证书。

这正是如此 SNI,或服务器名称指示。

使用SNI,客户端将其想要访问的服务器名称作为第一条消息的一部分发送,即上面握手图中的“Client Hello”步骤。

一些较旧的Web浏览器不支持SNI。例如,在Windows XP上 不是Internet Explorer的单个版本 支持SNI。在使用SNI虚拟主机的服务器上通过HTTPS访问资源时,将向您显示通用证书,这可能会导致浏览器显示警告或错误。

enter image description here

我在这里简化了一些事情来解释问题背后的原理和解决方案。如果你想要一个更技术性的解释,那么 维基百科 页面或 RFC 6066 可能是一个很好的起点。您还可以找到支持SNI的服务器和浏览器的最新列表 维基百科


37
2017-08-14 19:13





http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI

客户端浏览器还必须支持SNI。以下是一些浏览器:

* Mozilla Firefox 2.0 or later
* Opera 8.0 or later (with TLS 1.1 enabled)
* Internet Explorer 7.0 or later (on Vista, not XP)
* Google Chrome
* Safari 3.2.1 on Mac OS X 10.5.6 

16
2018-02-05 00:46





基于名称的虚拟主机需要服务器名称指示(RFC6066)TLS扩展才能通过HTTPS工作。

扩展已广泛实施,我还没有遇到任何与当前软件有关的问题,但如果您依赖SNI,有些客户(不支持它的客户)可能会被路由到您的默认站点。


6
2017-08-14 19:10



除了Falcon的回答,IIS还需要进行一些特殊更改才能使多个IIS站点在同一IP上工作。您必须手动编辑服务器的配置文件或使用CLI工具进行绑定更改,GUI工具无法执行此操作。在IIS中,它被称为为主机头分配SSL证书。 Apache暂时没有遇到这个问题。 - Brent Pabst
好吧,那清除了一些。你怎么知道客户端(浏览器)是否支持这个?例如,如果我想检查MSIE6,如何在不安装虚拟XP机器的情况下进行测试? - Luc
@Luc en.wikipedia.org/wiki/Server_Name_Indication#Support - cjc
@Falcon SNI不适用于XP上的IE;它仍占桌面互联网用户的近四分之一。当四分之一的潜在访客不工作时,我不会称之为“广泛实施”。 - Chris S
@MichaelHampton IE使用本机Windows加密堆栈进行SSL。 XP不支持SNI,因此任何版本的IE运行的XP都没有。 IE仅支持Vista和更新操作系统中的SNI。 - Chris S