我在 apache、site1、site2、site3 中定义了 3 个站点,对于 1 和 2,我从 Let's encrypt 请求 ssl 证书并正常工作,但不适用于站点 3。问题是每当我访问https://site3时,我总是会获得证书从其他网站之一,我认为从第一个定义。
这是apache应该如何工作还是我的配置错误?不确定当我没有定义证书时应该看到什么,也许是一些“无证书”错误?!
/etc/httpd/conf/httpd.conf
# http site 1
<VirtualHost site1.com:80>
DocumentRoot /var/www/html/site1.com
ServerName site1.com
<Directory "/var/www/html/site1.com">
Require all granted
DirectoryIndex index.html index.php
</Directory>
</VirtualHost>
# http site 2
<VirtualHost site2.com:80>
DocumentRoot /var/www/html/site2.com
ServerName site2.com
<Directory "/var/www/html/site2.com">
Require all granted
DirectoryIndex index.html index.php
</Directory>
</VirtualHost>
# http site 3 (only one WITHOUT ANY SSL)
<VirtualHost site3.com:80>
DocumentRoot /var/www/html/site3.com
ServerName site3.com
<Directory "/var/www/html/site3.com">
Require all granted
DirectoryIndex index.html index.php
</Directory>
</VirtualHost>
Include /etc/httpd/conf/httpd-le-ssl.conf >>>>>>>
/etc/httpd/conf/httpd-le-ssl.conf
# SSL site 1
<IfModule mod_ssl.c>
<VirtualHost site1.com:443>
DocumentRoot /var/www/html/site1.com
ServerName site1.com
<Directory "/var/www/html/site1.com">
Require all granted
DirectoryIndex index.html index.php
</Directory>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/www.site1.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.site1.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.site1.com/chain.pem
</VirtualHost>
</IfModule>
# SSL site 2
<IfModule mod_ssl.c>
<VirtualHost site2.com:443>
DocumentRoot /var/www/html/site2.com
ServerName site2.com
<Directory "/var/www/html/site2.com">
Require all granted
DirectoryIndex index.html index.php
</Directory>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/www.site2.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.site2.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.site2.com/chain.pem
</VirtualHost>
</IfModule>
是的,这是正确的。您的浏览器打开与服务器的连接并要求进行 TLS 协商。通过 SNI,提示什么是想要的站点。Apache 没有为此配置的证书,并且“随机”选择(实际上,选择第一个配置的)连接证书。
只有在建立连接后,浏览器才能请求站点。
请注意,浏览器应通知用户该证书对该站点无效。
这种骇人听闻的方式实际上是一种骇客:当 SSL 诞生时,您必须为每个 SSL 站点专用一个 IP。引入 SNI 是为了允许更多 SSL(实际上是 TLS)站点共享一个 IP。您可以强制 apache 拒绝来自非 SNI 客户端的连接,但不能强制它拒绝其他站点的连接。
在这些情况下,最好的办法是为托管服务器创建一个“备用”证书,带有备用站点,并将其配置为第一个(如果您使用 debian,则为 000-default)。这样,请求不存在的 tls 站点的访问者将看到一个警告标志,而不是其他站点。