我的理解是,当Apache收到一个正在监听的TCP端口的请求时(例如80,443),它将通过查看HTTP头Host
来决定请求哪个Host
。 然后服务器将知道它应该将请求redirect到哪个虚拟主机。
但是,如何通过SSL / TLS的HTTP工作? 由于整个HTTP请求正在被encryption(至less这是我相信我已经读过的地方),所以头信息只能在服务器解密数据后才能被读取。 但为了解密,需要知道使用哪个密钥对,因为您可以在Web服务器上安装多个SSL证书。
那么服务器如何知道解密需要哪个密钥呢?
我的猜测是 :
我可以想象,TLS握手提供了必要的信息。
虽然我同意这个问题和我自己的答案是相似的,但我必须说这个问题是不同的。 是否或如何使用独立SSL证书托pipe多个站点是不可能的。 相反,我的问题涉及到底层技术方面。
最初,Web服务器不知道。 这就是您需要为服务器上要托pipe的每个SSL虚拟主机分配一个IP地址的原因。 这样,服务器就知道在IP X上连接时,他需要使用相关虚拟主机的configuration(包括证书)。
这改变了服务器名称指示 ,一个TLS扩展,确实允许客户端在握手过程中指示所需的主机名。 这个扩展名被用在所有的现代操作系统中,但是旧的浏览器或者服务器不支持它,所以如果你期望客户端在WinXP上仍然使用IE 6,那么你就不会运气好了。
看来你对TLS / SSL有一些误解。 HTTP请求没有被服务器的公钥encryption。 它使用前面握手协商的密钥通过对称密码进行encryption。
TLS握手的简要描述:服务器和客户端协商一些密码组,对称密钥和一些其他细节。 为了防止MITM,服务器通常将其证书(链)发送到客户端,并使用证书中的密钥来validation握手。 (还有一些其他的变体,例如客户端authentication或者TLS-PSK,但是它们并没有太多和HTTP一起使用。)客户端可以validation证书(通常的方式)或者忽略它。
虽然在一个IP上使用多个TLS证书时,SNI很重要,但服务器能够解密请求并不是必需的。 没有SNI,服务器不知道应该发送哪个证书链,所以服务器通常select一个(例如第一个虚拟主机),这当然是错误的。 如果服务器挑错证书链,客户端应该拒绝它(所以它不会继续发送HTTP请求)。 但是,如果客户端忽略证书(或者无效证书被标记为对该站点可信),则可以成功继续。 由于用于encryption的对称密钥不依赖于证书(TLS被devise为也可以在没有证书的情况下工作),所以服务器可以解密它。
只是小问题,为什么我写关于TLS,而你问SSL有关:TLS是新版本的SSL。 所有版本的SSL被认为是不安全的一般用法,所以我们现在主要使用TLS(1.0,1.1,1.2)。