Apache Canonical Host 带有一个 SSL 证书,适用于带 www 和不带 www 的

Apache Canonical Host 带有一个 SSL 证书,适用于带 www 和不带 www 的

使用 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://域名.tldhttps://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
    ...
    

相关内容