HSTS导致www.subdomain.domain.com无法重定向至subdomain.domain.com问题
问题根本原因
你遇到的拦截和.htaccess规则优先级无关,Web请求的处理顺序为TLS证书校验 → 接收HTTP请求 → 执行服务器重写规则,证书校验发生在整个流程的最前端,远早于.htaccess规则加载。
当用户访问https://www.subdomain.domain.com时,浏览器首先会校验服务器返回的证书:你当前使用的*.domain.com通配符证书仅能匹配一级子域名,无法覆盖*.*.domain.com层级的域名,会直接触发证书不匹配错误,请求根本不会发送到后端执行你的重定向逻辑。加上你开启了带includeSubDomains参数的HSTS,浏览器会强制所有子域名走HTTPS,连降级到HTTP重试的机会都没有,所以直接抛出NET::ERR_CERT_COMMON_NAME_INVALID错误。
可行解决方案
方案1:补充双层通配符证书(最推荐)
直接在现有证书中增加*.*.domain.com的通配符SAN扩展,目前包括免费的Let's Encrypt在内的主流CA都支持签发多通配符域名证书,你可以将*.domain.com和*.*.domain.com都加入同一张证书,覆盖所有一级、二级子域名的HTTPS请求,证书校验通过后你的现有重写规则就可以正常执行。
如果使用了CDN或负载均衡,需要将更新后的证书同步到所有边缘节点。
方案2:调整HSTS配置(仅允许合规微调时可选)
如果暂时无法申请双层通配符证书,可以修改HSTS规则,取消根域名全局的includeSubDomains参数,改为仅给*.domain.com匹配的一级子域名返回带includeSubDomains的HSTS头:
RewriteCond %{HTTP_HOST} ^[^.]+\.domain\.com$ [NC] Header set Strict-Transport-Security "max-age=63072000; includeSubDomains"
调整后多层子域名不会被强制走HTTPS,用户首次访问http://www.subdomain.domain.com时,服务器可以在80端口的HTTP请求阶段就执行重定向,直接跳转到https://subdomain.domain.com,规避证书校验问题。
注意:该方案会降低全站安全等级,需要提前和需求方确认合规性。
方案3:DNS层面拦截跳转
如果你的DNS服务商支持URL重定向记录,可以直接配置规则将所有www.*.domain.com的请求提前重定向到*.domain.com,在请求到达你的服务器前就完成跳转,规避证书校验问题。
方案4:从源头限制非法子域名生成
在用户创建子域名的环节增加校验规则,禁止用户创建带www.前缀的子域名,从根源上避免出现www.subdomain.domain.com这类需要跳转的多层子域名。
内容的提问来源于stack exchange,提问作者FamousWolluf

