我的 apache2 配置有问题:我在服务器上有两个网站:
- 域名1.tdl
- 域2.tdl
其中之一 (domain2.tdl) 必须并且可以在端口 443 上访问(使用 SSL)。所有域都必须并且可以通过端口 80 访问。但是当我们尝试在端口 443 上访问 domain1.tdl 时,会显示 domain2.tdl 文件。因此,在端口 443 上,domain2.tdl 可由 domain1.tdl和domain2.tdl 访问。我不要!
我的配置:
域 1.tdl:
<VirtualHost *:80>
DocumentRoot /home/sites/domain1.tdl/www
ServerName domain1.tdl
ServerAlias www.domain1.tdl
ServerAdmin [email protected]
RewriteEngine on
<Directory "/home/sites/domain1.tdl/www">
AllowOverride All
allow from all
Options -Indexes
</Directory>
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /home/sites/domain1.tdl/www
ServerName domain1.tdl
ServerAlias www.domain1.tdl
ServerAdmin [email protected]
RewriteEngine on
<Directory "/home/sites/domain1.tdl/www">
AllowOverride All
allow from all
Options -Indexes
</Directory>
域 2.tdl:
<VirtualHost *:80>
DocumentRoot "/home/sites/domain2.tdl/web"
ServerName domain2.tdl
ErrorLog /var/log/apache2/site/error_domain2.tdl.log
CustomLog /var/log/apache2/site/access_domain2.tdl.log combined
<Directory "/home/sites/domain2.tdl/web">
allow from all
Options -Indexes
</Directory>
ServerAlias www.domain2.tdl
</VirtualHost>
<VirtualHost domain2.tdl:443>
DocumentRoot "/home/sites/domain2.tdl/web"
ServerName domain2.tdl
ErrorLog /var/log/apache2/site/error_domain2.tdl.log
CustomLog /var/log/apache2/site/access_domain2.tdl.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/private/domain2.tdl/domain2.tdl.crt
SSLCertificateKeyFile /etc/ssl/private/domain2.tdl/domain2.tdl.key
SSLCACertificateFile /etc/ssl/private/domain2.tdl/GandiStandardSSLCA.pem
SSLVerifyClient None
<Directory "/home/sites/domain2.tdl/web">
allow from all
Options -Indexes
</Directory>
ServerAlias www.domain2.tdl
</VirtualHost>
解释
当您使用 NameVirtualHosts 时,Apache 将使用 Host: 标头中给出的主机名来确定您应该访问的虚拟主机。这在历史上一直是 SSL 的问题——因为整个会话都是加密的,包括Host: 标头,Apache 需要解密会话才能确定要使用哪个虚拟主机。但是解密所需的信息在 VirtualHost 部分内,创建了一个陷阱 22 - apache 需要一个 VirtualHost 但它不知道是哪个,所以它会选择它找到的第一个。
最近的 SSL 实现包括 SNI,这使得提供未加密的主机名成为可能。但是为了让它工作,服务器和客户端都需要运行相当新的 SSL 版本,虽然您可以控制服务器,但通常您无法控制客户端。
解决方案
首先,由于您不希望通过 SSL 访问 domain1.tdl,您可以简单地删除
VirtualHost:443
domain1 的部分。(这不会解决当前的问题,但是如果您不想使用它,您不应该保留配置;在某些时候它会给您带来问题!)其次,您需要创建一些方法来在 SSL 协商后检查主机名是否正确,并且只允许流量流向正确的主机名。最简单的方法是使用 mod_rewrite 并进行标头检查,并拒绝所有主机名不正确的流量。这是一个例子:
如果您只想让他们知道不允许访问,您可以发出错误消息:
这些命令应该在 domain2.tdl:443 的 VirtualHost 指令中。