Why can’t I use SSL with name-based/non-IP-based virtual hosts?

参考apache的文档

Why can’t I use SSL with name-based/non-IP-based virtual hosts?

The reason is very technical, and a somewhat “chicken and egg” problem. The SSL protocol layer stays below the HTTP protocol layer and encapsulates HTTP. When an SSL connection (HTTPS) is established Apache/mod_ssl has to negotiate the SSL protocol parameters with the client. For this, mod_ssl has to consult the configuration of the virtual server (for instance it has to look for the cipher suite, the server certificate, etc.). But in order to go to the correct virtual server Apache has to know the Host HTTP header field. To do this, the HTTP request header has to be read. This cannot be done before the SSL handshake is finished, but the information is needed in order to complete the SSL handshake phase. Bingo!
Why is it not possible to use Name-Based Virtual Hosting to identify different SSL virtual hosts?

Name-Based Virtual Hosting is a very popular method of identifying different virtual hosts. It allows you to use the same IP address and the same port number for many different sites. When people move on to SSL, it seems natural to assume that the same method can be used to have lots of different SSL virtual hosts on the same server.

It comes as rather a shock to learn that it is impossible.

The reason is that the SSL protocol is a separate layer which encapsulates the HTTP protocol. So the SSL session is a separate transaction, that takes place before the HTTP session has begun. The server receives an SSL request on IP address X and port Y (usually 443). Since the SSL request does not contain any Host: field, the server has no way to decide which SSL virtual host to use. Usually, it will just use the first one it finds, which matches the port and IP address specified.

You can, of course, use Name-Based Virtual Hosting to identify many non-SSL virtual hosts (all on port 80, for example) and then have a single SSL virtual host (on port 443). But if you do this, you must make sure to put the non-SSL port number on the NameVirtualHost directive, e.g.

NameVirtualHost 192.168.1.1:80

Other workaround solutions include:

Using separate IP addresses for different SSL hosts. Using different port numbers for different SSL hosts.

相关的中文说明

为什么我不能在相同IP地址下多个域名的虚拟主机上使用SSL?

这个问题十分专业,有些像“先有鸡还是先有蛋”的问题。SSL协议层是在HTTP协议层的前面,当SSL连接建立时,SSL模块在Web模块之前和浏览器进行通讯并交换证书、建立加密隧道。众所周知,Web服务器是通过 HTTP数据包中的”Host”字段来区分虚拟主机的。而SSL模块在把服务器证书发送到浏览器时,还没有收到任何关于HTTP的数据包,更不知道虚拟主机的域名,因此SSL模块只能固定的将一张SSL证书发送到浏览器,而不能根据域名有选择性的发送证书。因此,您无法在一个IP地址的默认SSL 443端口下为多个虚拟主机配置多张证书。

由于一个IP与一个端口号只能对应一张证书,因此可以采用以下方式解决:

(1) 为需要SSL加密的虚拟主机配置不同的IP地址,端口号都使用443。例如: www.domain1.com 的SSL使用 202.96.101.1:443 www.domain2.com的SSL使用 202.96.101.2:443,通过 https://www.domain1.com 和 https://www.domain2.com 访问这2个SSL网站了

(2) 如果只有一个IP地址,可以为多个网站配置不同的SSL端口。例如: www.domain1.com 的SSL使用 202.96.101.1:443 www.domain2.com的SSL使用 202.96.101.1:1000,通过 https://www.domain1.com 和 https://www.domain2.com:1000 访问这2个SSL网站了

如果多个虚拟主机是1个主域名下的多个子域名,情况发生了转变,因为你可以申请通配符SSL证书。

例如: 有2个虚拟主机 abc.domain.com、xyz.domain.com,你申请一张 *.domain.com的证书,按照前面所说的原理,2个虚拟主机都使用同一个IP和默认的443端口,当浏览器访问IP:443端口时,SSL模块把通配符SSL证书传送给浏览器,建立合法的SSL隧道,然后WEB模块接收到HTTP数据包时判断域名选择虚拟主机。

原理是OK的,不幸的是你无法按照这个原理对IIS进行配置,早期的IIS不支持SSL端口配置域名。只有您使用Windows 2003,安装了Service Pack1后,才可以通过命令行为SSL端口配置域名,Apache是可以为SSL端口配置域名。您需要为所有的虚拟主机配置相同的通配符证书。

就是说,我可以建立一个*.domain的域名证书,给所有的子域名来使用。

Leave a Reply

Your email address will not be published. Required fields are marked *