使用 SNI,一个 IP 地址上有多个拥有自己的 SSL 证书 (LetsEncrypt) 的域名。对于其中一个主域名,我们假设https://thedomain.tld,访问https://www.thedomain.tld导致浏览器错误(SSL 证书不匹配),而不是为 www.thedomain.tld 提供内容或重定向。我尝试了多种方法。例如:
<IfModule mod_ssl.c>
<VirtualHost 0.0.0.1:443>
ServerName domain.tld
ServerAlias www.domain.tld
DocumentRoot /var/www/domain.tld/
...
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/domain.tld/cert.pem
...
<Directory /var/www/domain.tld>
Options -ExecCGI -Indexes -Includes +FollowSymLinks
AllowOverride FileInfo AuthConfig
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^/(.*)$ https://%1/$1 [R=301,L]
...
版本:Apache 2.4.18
附注:在一个服务器上,这工作得很好(专用 Ubuntu 16.04)。在另一个服务器上(Amazon Ubuntu 16.04),它重定向或引用 www 或不带 www 的任何内容的能力都不存在。
答案1
首先,如果你服务http://www.thedomain.tld我会考虑将其重定向到https://thedomain.tld。这解决了用户在浏览器中输入 www.thedomain.tld 的问题(但不能解决输入 https: 或已经有 https 链接/书签或被浏览器/HSTS 强制使用 https 的用户的问题)。
如果您不提供纯 http,那么很遗憾,您需要一个在证书的 SAN 字段(如果不存在 SAN,则为 CN 字段)包含 www.thedomain.tld 或 *.thedomain.tld 的证书。
Apache 生成的任何东西都无法绕过它。浏览器在 TCP 连接后获得的第一件事是证书。如果 SAN/CN 与浏览器想要的主机名不完全匹配,游戏就结束了。浏览器会显示警告,甚至不会发送 http 请求,因此 Apache 根本不会响应。
重定向不会同样发生。
如果您单独获取 www.thedomain.tld 证书,而不是 thedomain.tld 证书,则需要将单独的 ServerName 放在单独的 Apache VirtualHost 中。但这会带来维护麻烦。
我建议使用单个证书(SAN 字段可以包含多个名称),然后 ServerName+ServerAlias 配置将按照您指定的方式工作。
答案2
我能够通过使用两个 SSL 证书来破解重定向,从而解决这个问题。这不是我喜欢的方法,但现在它起作用了。
www. 是该网站的权威网站,因此我做了以下操作:
- 颁发另一份证书
domain.tld
全面重定向https://域名.tld到https://www.domain.tld
<VirtualHost *:443> ServerName domain.tld DocumentRoot /var/www/domain.tld SSLEngine on SSLCertificateFile /etc/letsencrypt/live/domain.tld/cert.pem ... RedirectMatch 301 (.*) https://www.domain.tld$1 </VirtualHost> <VirtualHost *:443> ServerName www.domain.tld ...