![为什么为一个 VirtualHost 配置了 mod_ssl 的 apache 可以响应对任何域的请求?](https://linux22.com/image/549287/%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%BA%E4%B8%80%E4%B8%AA%20VirtualHost%20%E9%85%8D%E7%BD%AE%E4%BA%86%20mod_ssl%20%E7%9A%84%20apache%20%E5%8F%AF%E4%BB%A5%E5%93%8D%E5%BA%94%E5%AF%B9%E4%BB%BB%E4%BD%95%E5%9F%9F%E7%9A%84%E8%AF%B7%E6%B1%82%EF%BC%9F.png)
我刚刚设置了启用了 mod_ssl 的 Apache 2.2.18,并将其配置为在端口 443 上监听一个 IP 地址。有许多域的 DNS 记录指向此 IP 地址。但我想为特定域及其 DocumentRoot 配置带有“VirtualHost”的 Apache。
我在 httpd.conf 中的配置是这样的:
Listen 1.2.3.4:443
NameVirtualHost 1.2.3.4:443
<VirtualHost 1.2.3.4:443>
DocumentRoot /data/www/domain.com
ServerName www.domain.com
SSLEngine On
</VirtualHost>
但是,我的问题和疑问是,这个 Apache 将此 VirtualHost 用于指向同一 IP 地址的任何域。它似乎忽略了“ServerName”参数。我想仅在特定域上运行此 SSL-Apache。有人可以帮忙吗?
答案1
这是由 SSL 的工作方式导致的。要理解这一点,您首先需要知道当您从网站请求页面时实际发生了什么。
请求的简要摘要https://example.com/
:
- 你通过端口 443 与 IP 1.2.3.4 建立连接
- SSL 握手和密钥交换。此时证书开始发挥作用
实际数据是加密发送的:
GET / HTTP/1.1 Host: www.example.com
问题是,
www.example.com
证书确定后域名就会被人知道。
解决方案是信噪比其中Host
标头字段在 SSL 握手之前发送。这是一项相对较新的技术,可能并非所有浏览器都支持。
答案2
通常情况下,SSL 在任何通信之前建立。
HTTP 协议通过Host:
标头告诉通信中的服务器名称是什么。
因此,SSL 在知道请求的主机名之前就建立了。
为了确保大多数浏览器都接受 SSL 证书,您应该执行以下操作之一:
创建通配符 SSL。然后,所有对 *.somedomain.com 的请求都将被浏览器接受。
创建 SSL 证书,并在“主题备用名称”中将所有需要的域名作为备用。不适用于所有浏览器,但适用于大多数主流浏览器。
使用 SNI:http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI在主流浏览器中再次运行...因为我们最好的朋友 IE6 不支持 SNI。