htaccess HSTS 防止从 www.subdomain.domain.com 重定向到 subdomain.domain.com

htaccess HSTS prevents redirection from www.subdomain.domain.com to subdomain.domain.com

我有一个网站,用户可以为该网站创建无限的子域。
我们的一位客户希望我们在 header 上启用 HSTS,因此我将以下规则添加到我的 .htaccess:

Header set Strict-Transport-Security "max-age=63072000; includeSubDomains"

我们有一个通配符证书*.domain.com来保护所有子域,因为我们不想为每个子域制作一个单独的证书。

问题是当有人要 www.subdomain.domain.com 他们需要被重定向到 subdomain.domain.com
但是 Chrome 正在阻止重定向,因为 *.*.domain.com 级别上没有有效的证书并且 HSTS 规则使 Chrome 完全阻止重定向并出现 NET::ERR_CERT_COMMON_NAME_INVALID 错误。

重要的 .htaccess 部分:

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [R=301,QSA,NC,L]

RewriteCond %{HTTPS} off
RewriteRule ^/?(.*) https://%{HTTP_HOST}%{REQUEST_URI} [NC,QSA,R=301,L]

Header set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set Cache-Control "no-store, no-cache, must-revalidate"

我原以为到 non-www 的 www 重定向会先进行,因为它在 .htaccess 文件中的位置更高。

...and the HSTS rules makes Chrome block the redirect completely with a NET::ERR_CERT_COMMON_NAME_INVALID error

这与 HSTS 无关。该错误是“因为 *.*.domain.com 级别没有有效证书”。在尝试实施 HSTS 之前,您可能会遇到同样的错误。 (除非你只通过 HTTP 测试过 www 子域?!)

没有捷径。如果您需要通过 HTTPS 访问 www 子域,那么您需要一个涵盖该主机名的有效安全证书。

I was expecting that the www to non-www redirect would go first because it is higher in the .htaccess file.

NET::ERR_CERT_COMMON_NAME_INVALID 是在 SSL 握手期间发生的 浏览器 错误。这一切都发生在 before .htaccess 甚至被处理(在传输任何数据之前)。


旁白:尽管你真的需要 www 子域吗?

如果您不想在 www sub-subdomain 上启用 HSTS,您需要在 header 周围放置一个 <If> 语句并且不要在 includeSubDomains 中使用你的 HSTS 规则。

如果没有 <If "%{HTTP_HOST} != 'www.sub.example.com'> 围绕 HSTS 的 Header 指令,那么 header 将被发送到该子域,无论 .htaccess 文件中规则的顺序如何。

当您在 HSTS 规则中使用 includeSubDomains 时,当您访问 sub.example.com 甚至 example.com.

时,www.sub.example.com 的 HSTS 将被启用

现在您已经为该 www 子域启用了 HSTS,您无法为已经访问过您站点的浏览器撤销它。此时,您最好的做法是获取涵盖 www 子域的证书。您可能可以将 at 作为主题备用名称 (SAN) 添加到现有证书中。