这是关于在同一IP上托管多个SSL网站的规范问题。
我的印象是,每个SSL证书都需要它自己的唯一IP地址/端口组合。但是,我对先前发布的问题的回答与此说法不符。
使用该问题的信息,我能够获得多个SSL证书在相同的IP地址和端口443上工作。对于上述假设,并通过其他假设,每个SSL域网站都对此进行了补充,我感到困惑。同一台服务器需要自己的IP /端口。
我怀疑自己做错了什么。可以通过这种方式使用多个SSL证书吗?
这是关于在同一IP上托管多个SSL网站的规范问题。
我的印象是,每个SSL证书都需要它自己的唯一IP地址/端口组合。但是,我对先前发布的问题的回答与此说法不符。
使用该问题的信息,我能够获得多个SSL证书在相同的IP地址和端口443上工作。对于上述假设,并通过其他假设,每个SSL域网站都对此进行了补充,我感到困惑。同一台服务器需要自己的IP /端口。
我怀疑自己做错了什么。可以通过这种方式使用多个SSL证书吗?
Answers:
有关Apache和SNI的最新信息,包括其他特定于HTTP的RFC,请参考Apache Wiki。
仅供参考:TLS升级的魔力带给您“一个IP上的多个(不同)SSL证书”。它可以与较新的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.
是的,但是有一些警告。
这是通过服务器名称指示(传输层安全性的扩展)来完成的。
服务器名称指示(RFC 6066;废弃的RFC 4366和RFC 3546)是传输层安全性的扩展,它允许客户端告诉服务器它要访问的主机的名称。
根据规范,SNI与TLS 1.0及更高版本兼容,但实现方式可能有所不同(请参见下文)。它不能与SSL一起使用,因此连接必须协商TLS(请参阅RFC 4346附录E)才能使用SNI。通常,使用支持的软件会自动发生这种情况。
在正常的HTTP连接中,浏览器会使用Host:
标头将尝试访问的服务器的主机名通知服务器。这允许单个IP地址上的Web服务器为多个主机名提供内容,这通常称为基于名称的虚拟主机。
替代方法是为每个要提供的Web主机名分配唯一的IP地址。这通常是在Web成立之初就完成的,当时人们普遍知道IP地址将用尽并开始采取保护措施,但对于SSL虚拟主机(不使用SNI)仍然可以通过这种方式进行。
因为这种传输主机名的方法要求已经建立连接,所以它不适用于SSL / TLS连接。在建立安全连接时,Web服务器必须已经知道它将为客户端提供哪个主机名,因为Web服务器本身正在建立安全连接。
SNI通过让客户端在TLS协商中传输主机名来解决此问题,因此服务器已经知道应该使用哪个虚拟主机来为连接提供服务。然后,服务器可以将证书和配置用于正确的虚拟主机。
HTTP Host:
标头的定义是由于IPv4地址的短缺,允许从一个IP地址为一个以上的Web主机提供服务,这早在1990年代中期就被认为是一个问题。在共享的Web托管环境中,可以使用单个IP地址以这种方式为数百个唯一的,不相关的网站提供服务,从而节省了地址空间。
然后,共享主机环境发现IP地址空间的最大消耗者是对安全网站具有唯一IP地址的需求,这使SNI成为通向IPv6的权宜之计。如今,有时很难在没有明显理由的情况下获得多达5个IP地址(/ 29),这通常会导致部署延迟。
随着IPv6的出现,不再需要这种地址保存技术,因为单个主机可以分配给它的IPv6地址比今天整个Internet所包含的更多,但是在将来很可能仍会使用该技术为旧版IPv4提供服务。连接。
某些操作系统/浏览器组合不支持SNI(请参阅下文),因此并不适合在所有情况下使用SNI。针对此类系统/浏览器组合的站点将不得不放弃SNI,并继续为每个虚拟主机使用唯一的IP地址。
特别要注意的是,Windows XP上的Internet Explorer版本均不支持SNI。由于此组合仍占互联网流量的很大一部分(但稳步下降;根据NetMarketShare,2012年12月,互联网流量约为16%),因此SNI对于以这些用户群为目标的网站而言是不合适的。
许多但不是全部常用软件包都支持SNI。
(此列表中的遗漏并不一定意味着缺乏支持;这意味着我可以输入多少字,或者我无法快速在搜索中找到信息。如果您的软件包未列出,请进行搜索名称,并sni
应说明是否存在支持以及如何设置。)
大多数软件包都依赖外部库来提供SSL / TLS支持。
最新版本的流行服务器软件支持SNI。安装说明可用于以下大多数:
当前大多数Web浏览器和命令行用户代理都支持SNI。
(注意:有关此答案的一些信息是从Wikipedia获得的。)
问题:
当Web客户端和Web服务器通过HTTPS相互通信时,首先需要做的就是安全握手。
这是这种握手的简化示例:
如果这是HTTP而不是HTTPS,则客户端发送的第一件事就是这样的:
GET /index.html HTTP/1.1
Host: example.com
由于服务器确切知道客户端要访问哪个域(即example.com),因此可以在单个IP地址上使用多个虚拟主机。
HTTPS是不同的。就像我之前说的,握手先于其他一切。如果您看一下上面说明的握手的第三步(证书),则服务器需要向客户端出示证书作为握手的一部分,但不知道客户端尝试访问哪个域名。服务器唯一的选择是每次发送相同的证书,即默认证书。
您仍然可以在Web服务器上设置虚拟主机,但是服务器将始终向每个客户端发送相同的证书。如果您尝试在服务器上同时托管example.com和example.org网站,则当客户端请求HTTPS连接时,服务器将始终为example.com发送证书。因此,当客户端通过已建立的HTTPS连接请求example.org时,就会发生这种情况:
此问题有效地限制了您可以通过HTTPS服务器将每个IP地址限制为一个域。
解决方案:
解决此问题的最简单方法是让客户端告诉服务器在握手期间要访问哪个域。这样服务器可以提供正确的证书。
这正是SNI或服务器名称指示的作用。
使用SNI,客户端将发送要访问的服务器名称作为第一条消息的一部分,即上面的握手图中的“客户端问候”步骤。
一些较旧的Web浏览器不支持SNI。例如,在Windows XP上,没有单个版本的Internet Explorer支持SNI。在使用SNI虚拟主机的服务器上通过HTTPS访问资源时,系统将为您提供通用证书,这可能会导致浏览器显示警告或错误。
我在这里简化了事情,只是为了解释问题和解决方案背后的原理。如果您想要更多的技术说明,那么Wikipedia页面或RFC 6066可能是一个很好的起点。您还可以在Wikipedia上找到支持SNI的服务器和浏览器的最新列表。
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
服务器名称指示(RFC6066)TLS扩展是基于名称的虚拟主机在HTTPS上运行所必需的。
该扩展已得到广泛实施,目前的软件还没有遇到任何问题,但是如果您依赖于SNI,则可能会将某些客户端(不支持该客户端)路由到您的默认站点。