如何在SSL上设置Apache NameVirtualHost?

我想设置两个DNS的Alogging指向我的Ubuntu的实例。 然后,Apache应该相应地读取域名,并将传入的请求指向正确的物理path。

我已经设置了所有这些是/etc/apache2/ports.conf的内容

它担心我的WinXP用户无法访问我的SSL网站根据下面的评论,所以我应该如何做不同?

NameVirtualHost *:80 Listen 80 <IfModule mod_ssl.c> # If you add NameVirtualHost *:443 here, you will also have to change # the VirtualHost statement in /etc/apache2/sites-available/default-ssl # to <VirtualHost *:443> # Server Name Indication for SSL named virtual hosts is currently not # supported by MSIE on Windows XP. NameVirtualHost *:443 Listen 443 </IfModule> <IfModule mod_gnutls.c> NameVirtualHost *:443 Listen 443 </IfModule> 

大多数人拥有WinXP和Internet Explorer,所以有点关注。 我怎样才能设置不同的SSL,使其为每个人工作?

在同一个Apache Httpd服务器(以及任何HTTPS服务器)上使用多个主机名会带来两个问题:

  • 为了连接安全,客户端必须首先validation服务器证书。
  • 如果有多个证书可用于服务器,则服务器必须能够获得从客户端请求中select哪个证书。

HTTPS是基于SSL / TLS的HTTP:build立安全隧道的SSL / TLS握手由客户端在创buildTCP连接之后,在进行任何HTTP交换之前启动。 HTTPS交换的所有后续HTTP通信通过此SSL / TLS连接完成。

服务器证书作为SSL / TLS握手的一部分由服务器发送。 validation过程依赖于(a)validation证书是可信的,(b)validation它是针对客户端打算联系的服务器发出的。 这个答案在StackOverflow中有更多的细节。

在HTTP中,所请求的主机名在HTTP Host头中发送。 这就是基于名称的虚拟主机是如何工作的:派发是基于Apache Httpd内部的Host头完成的。

但是,在SSL / TLS成功完成之前,HTTP Host头不可用于Apache Httpd。 因此,在发送服务器证书之前,它不可用。

有两种方法可以帮助Apache Httpdselect在握手期间使用哪个证书,而不依赖任何HTTP通信:

  • 使用每个IP地址/端口组合的证书。 这是传统的方式。
  • 使用SSL / TLS的服务器名称指示扩展 ,在SSL / TLS握手期间发送,从而build立安全通道。 这个选项的问题是并不是所有的浏览器都支持它。 特别是,它不支持XP上的任何版本的IE浏览器(以及一些移动浏览器,我认为)。

如果您不能使用SNI或在您的服务器上有多个IP地址,则可以使用对您要提供的所有主机名有效的证书。 这可以通过使用:

  • 颁发给通配符名称的证书(但不鼓励其使用 ),或者
  • 具有多个主题备用名称DNS条目的证书。 这应该是您的首选选项。

如果你真的想尝试SNI,它应该使用最新版本的Apache Httpd 2,使用最新版本的OpenSSL(如果使用主代码库提供的mod_ssl )。 这是logging在这里: http : //wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI

SSL警告是关于基于名称的 SSL站点。 传统的SSL在发送HTTPstream量之前encryption连接,如果没有弄错的话,它会encryptionTCP连接而不是HTTP会话。 由于在HTTP协议中select了虚拟主机,并且服务器在使用http之前需要build立安全连接,所以每个IP /端口组合只能select一个证书。 默认情况下,该链接的网站。

这改变了,因为你现在可以使用TLS( gnutls )进行encryption,这实际上是SSL的“新版本”,并允许基于名称的encryption。 但是,旧版操作系统和浏览器(如Windows XP)不支持此function。

这是可能的,如果你使用Firefox或铬在XP而不是IE浏览器,它工作得很好。

如果您希望随时使用,请为SSL版本的网站configuration多个IP和/或端口。 如果您只有一个需要SSL的网站,则不需要进一步的configuration

编辑:问题也改变了

如果只有一个IP用于多个SSL域名,另一种可能性是为默认文档根目录configuration一个<VirtualHost _default_:443>,并且在其内部使用RewriteRule来为每个需要从不同文档根目录提供的域名。 例如:

 <VirtualHost _default_:443> DocumentRoot /var/www/https_one ... RewriteEngine On RewriteCond %{HTTP_HOST} ^https_two\.example\.com$ RewriteRule (.*) /var/www/https_two/$1 RewriteCond %{HTTP_HOST} ^https_three\.example\.com$ RewriteRule (.*) /var/www/https_three/$1 </VirtualHost> 

由于mod_rewrite在头文件已经发送的时候运行,所以在SSL握手阶段很难绕过识别HTTP主机的问题。 您仍然需要一个对所有域名都有效的证书,假设您不希望访问者提示他们通过浏览器接受安全exception。

虽然上面的@Bruno提供的答案确实解决了问题,但是如何以低于可行的解决scheme来build立基于SSL / TLS名称的虚拟主机,还是有一个问题,提供者)为他们的机器额外的IP地址,也取决于httpd.conf的监听参数

IOW,在@ Bruno的答案中没有解决scheme – 您必须使用基于IP的虚拟主机。

另一方面,@ocsarjd确实解决了如何为基于名称的虚拟SSL主机提供支持,另外还为那些坚持在XP上运行IE的人提供了解决scheme。

使用:

 <VirtualHost _default_:443> 

然后mod_rewrite为浏览器提供了无法利用SNI的支持,因此,没有人需要购买和/或绑定额外的IP地址给服务器,以便Apache侦听基于IP的虚拟主机方法中的连接。

具有讽刺意味的是,@布鲁诺的答案确实涵盖了所有这些谈判如何以及为何发生的原因,以及过时的浏览器如何不能在Apache服务器上正确地合并基于名称的SSL虚拟主机。

由于OP提出这个问题已经有一段时间了,所以我build议不要包含这些过时的浏览器,因为这是客户端的人员select运行不安全的软件的select,在我看来,这只是一个人被忽略….

据说,一个类似于自定义404页面的默认SSL虚拟主机告诉访问者他们正在操作一个不安全的浏览器客户端实际上是为了这里几年,因为肯定会有人拒绝停止使用IE版本,因为XP是EOL的,所有(所谓的)“现代”浏览器(IE / Edge,Firefox,Chrome / Chromium,Opera,Safari)都没有收到补丁,基于HTTPS的基于networking的虚拟主机通过SNI。