假设我想要使用 Apache 服务器在同一台机器上运行两个安全站点:
1. https://example.com
2. https://example.ca
上述两个站点都可以使用 443 端口吗?
答案1
正如前面所解释的,SSL 连接是在通过连接发送任何实际数据之前创建的,因此 Apache 无法为每个虚拟站点提供不同的 SSL 证书,因为它不知道请求的服务器名称是什么。这意味着无论实际请求的服务器名称是什么(在本例中为“mysite.com”或“mysite.ca”),Apache 都会使用已配置的默认 SSL 证书进行响应。这可能在“默认”443 VirtualHost 或全局 Apache 配置中声明。
从可用性的角度来看,这意味着您绝对可以从同一个 Apache 主机和 IP 托管两个站点,但用户在接受证书时会收到警告,告知他们证书适用于错误的站点。解决此问题的唯一方法是使用两个不同的 IP 地址并配置您的虚拟主机,以便它们分别监听不同的地址。(确保相应地更新 DNS)
一旦证书交换完成,就会应用正常的 VirtualHost 规则,并且如果您愿意的话,您实际上可以在每个服务器名称上托管不同的内容。
这些示例有点粗略,如果您还不了解基础知识,则需要查阅官方 apache 文档以了解设置虚拟主机和配置 ssl 的确切参数名称。
示例:两台服务器位于不同的 IP 地址,具有不同的文档根目录,每台服务器都提供正确的证书
<VirtualHost 1.1.1.1:443>
ServerName mysite.com
DocumentRoot /var/www/comroot
SSLEngine On
// Configure certificate for mysite.com
</VirtualHost>
<VirtualHost 2.2.2.2:443>
ServerName mysite.ca
DocumentRoot /var/www/caroot
SSLEngine On
// Configure certificate for mysite.ca
</VirtualHost>
示例:同一 IP 上的两台服务器使用错误的证书(在其他地方配置)但仍然根据服务器名称提供不同的内容。
<VirtualHost *:443>
ServerName mysite.com
DocumentRoot /var/www/comroot
SSLEngine On
</VirtualHost>
<VirtualHost *:443>
ServerName mysite.ca
DocumentRoot /var/www/caroot
SSLEngine On
</VirtualHost>
答案2
您可以使用几种方法从单个 IP 地址运行多个 SSL 站点,但每种方法都有各自的缺点。
第一种方法是拥有一个涵盖两个网站的 SSL 证书。这里的想法是拥有一个涵盖您想要从单个 IP 地址托管的所有域的 SSL 证书。您可以使用涵盖两个域的通配符证书或使用主题备用名称来执行此操作。
通配符证书可以是 *.example.com,它涵盖 www.example.com、mail.example.com 和 support.example.com。通配符证书存在许多问题。首先,每个主机名都需要有一个公共域,例如,使用 *.example.com,您可以拥有 www.example.com,但不能拥有 www.example.org。其次,您无法可靠地拥有多个子域,即您可以拥有 www.example.com,但不能拥有 www.eu.example.com。这可能适用于早期版本的 Firefox(<= 3.0),但不适用于 3.5 或任何版本的 Internet Explorer。第三,如果您希望由根 CA 签名,通配符证书比普通证书要贵得多。
主体备用名称是一种使用 X509 证书扩展的方法,该扩展列出了适用于该证书的备用主机名。它涉及向证书添加一个“subjectAltName”字段,该字段列出了您希望证书涵盖的每个其他主机。这应该适用于大多数浏览器;当然是所有现代主流浏览器。这种方法的缺点是您必须列出服务器上将使用 SSL 的每个域。您可能不希望这些信息公开。您可能不希望不相关的域列在同一证书上。以后向证书添加其他域也可能很困难。
第二种方法是使用一种称为 SNI(服务器名称指示)的东西,它是 TLS 中的扩展,解决了由于客户端尚未发送 Host: 标头而不知道要向客户端发送哪个证书的“先有鸡还是先有蛋”的问题。作为 TLS 协商的一部分,客户端将所需的主机名作为选项之一发送。唯一的缺点是客户端和服务器支持。浏览器中的支持往往比服务器更好。Firefox 从 2.0 开始支持它。Internet Explorer 从 7 开始支持它,但仅在 Vista 或更高版本上支持它。Chrome 也仅在 Vista 或更高版本上支持它。Opera 8 和 Safari 8.2.1 有支持。其他浏览器可能不支持它。
阻碍采用的最大问题是服务器支持。直到最近,两个主要的 Web 服务器都不支持它。Apache 从 2009 年 7 月发布的 2.2.12 版本开始获得 SNI 支持。截至撰写本文时,IIS 的任何版本都不支持 SNI。nginx、lighttpd 和 Cherokee 都支持 SNI。
展望未来,SNI 是解决 HTTPS 基于名称的虚拟托管的最佳方法,但支持可能还需要一两年的时间。如果您必须在不久的将来顺利进行 HTTPS 虚拟托管,那么基于 IP 的虚拟托管是唯一的选择。
答案3
仅当网站位于其自己的 IP 上时。
SSL 连接发生在客户端请求网站之前,因此当建立 SSL 连接时,服务器不知道客户端将要请求什么。
例如,如果您提供 .com SSL 证书,那么要求 .ca 的客户就会不满意。
解决方案是为 .ca 设置第二个 IP,并让 Web 服务器的单独实例使用 .ca 的 SSL 证书监听该 IP。
答案4
好的答案,但是,使用一个 HTTP 服务器来托管两个站点有一个 SPOF - 即一个 Apache 服务器实例。如果该 Apache 服务器发生故障,则两个站点都无法访问。双端口以太网卡怎么样?或者,更好的是,使用虚拟化。我非常喜欢 xen 或 openVZ 等虚拟化技术。但是,您需要在硬件上花一些钱。