我在 apache 中定义了 3 个站点,site1、site2、site3。对于 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>
答案1
是的,这是正确的。您的浏览器打开与服务器的连接并请求 TLS 协商。通过 SNI,给出所需站点的提示。Apache 没有为此配置证书,并且“随机”选择(实际上,选择第一个配置的)连接证书。
仅当建立连接后,浏览器才可以请求网站。
请注意,浏览器应该告知用户该证书对于网站无效。
这种黑客式的方法实际上是一种黑客行为:当 SSL 诞生时,您必须为每个 SSL 站点指定一个 IP。引入 SNI 是为了允许更多 SSL(实际上是 TLS)站点共享一个 IP。您可以强制 apache 拒绝来自非 SNI 客户端的连接,但不能强制它拒绝来自其他站点的连接。
在这些情况下,最好的策略是为托管服务器创建一个“后备”证书,并设置一个后备站点,并将其配置为第一个(如果您使用 Debian,则为 000-default)。这样,访问不存在的 TLS 站点的访问者将看到警告标志,而不是其他站点。