Nginx转发www.domain2.com时呈现错误证书问题求助
看起来你的问题根源出在HSTS的强制HTTPS规则,加上你没给www.domain2.com配置对应的HTTPS Server块导致的,我来给你拆解清楚:
问题原因分析
你已经给domain2.com和www.domain2.com配置了80端口的HTTP跳转,但因为你开启了includeSubDomains的HSTS规则,浏览器在第一次访问domain2.com后,会强制所有子域(包括www.domain2.com)使用HTTPS协议。这时候用户输入www.domain2.com,浏览器会直接发起https://www.domain2.com的请求,而你并没有为这个域名配置443端口的Server块,Nginx就会把这个请求匹配到服务器上第一个符合条件的HTTPS Server(也就是你提到的a_subdomain.domain1.com的配置),自然就返回了错误的证书。
解决方案步骤
1. 先确认你的SSL证书覆盖范围
首先要检查domain2.com的SSL证书是否包含www.domain2.com作为Subject Alternative Name(SAN)——简单说就是证书是否同时认可主域名和www子域名。如果证书没包含www.domain2.com,你需要重新申请包含这个域名的证书(比如通配符证书,或者带SAN的单域名证书),否则即使配置了Server块,浏览器还是会报错。
2. 添加HTTPS Server块处理www.domain2.com请求
你有两种配置方式可选:
方式一:单独配置跳转的Server块
这种方式更清晰,专门处理www.domain2.com的HTTPS请求并跳转:
server { listen 443 ssl; server_name www.domain2.com; # 配置和domain2.com相同的证书文件路径 ssl_certificate /path/to/your/domain2_certificate.crt; ssl_certificate_key /path/to/your/domain2_private.key; # 继承你的HSTS配置(或者直接用全局配置) add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always; # 直接跳转到不带www的主域名 return 301 https://domain2.com$request_uri; }
方式二:合并到domain2.com的HTTPS Server块里
如果想简化配置,可以把www.domain2.com加到主域名的Server块的server_name里,然后通过判断Host实现跳转:
server { listen 443 ssl; # 同时包含主域名和www子域名 server_name domain2.com www.domain2.com; ssl_certificate /path/to/your/domain2_certificate.crt; ssl_certificate_key /path/to/your/domain2_private.key; add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always; # 判断如果是www域名就跳转 if ($host = www.domain2.com) { return 301 https://domain2.com$request_uri; } # 这里放domain2.com的正常业务配置(比如root、PHP处理等) root /var/www/domain2; index index.html index.php; # ... 其他原有配置 }
3. 验证并重载Nginx配置
配置完成后,先检查配置文件是否合法:
sudo nginx -t
如果提示test is successful,就重载配置生效:
sudo nginx -s reload
这样处理后,浏览器访问https://www.domain2.com时,Nginx会用正确的证书响应,然后跳转到主域名,就不会再出现证书错误了。
备注:内容来源于stack exchange,提问作者Richard Rosner

