Apache 不带 www 访问报 NET::ERR_CERT_AUTHORITY_INVALID 且重定向失败
原因分析
SSL证书报错
TLS握手在HTTP请求处理之前完成,重定向逻辑要等证书校验通过后才会生效,因此证书错误无法通过重定向规避。
报错核心原因有两个:
- 现有Let's Encrypt证书未覆盖裸域
example.com。申请证书时若只指定了www.example.com,证书的SAN(主体备用名称)列表中不会包含裸域,浏览器校验域名与证书不匹配,就会返回证书无效错误,部分Chrome版本会将该场景归类为NET::ERR_CERT_AUTHORITY_INVALID。注意证书目录以example.com命名不代表证书包含该域名,certbot默认以申请时传入的第一个域名作为目录名。 - 若确认证书已包含两个域名仍报错,需检查443端口是否存在其他默认虚拟主机,裸域请求可能命中了配置自签证书的默认站点。
重定向失效
现有配置存在逻辑冲突和缺失:
- 80端口同时使用
mod_alias的Redirect和mod_rewrite的RewriteRule,两套规则执行优先级不同会互相干扰;且Redirect目标为HTTP协议的www域名,不符合最终HTTPS的要求,会产生多余跳转。 - 80端口的重写规则通过
%{SERVER_NAME}拼接跳转地址,只会原样保留原请求域名,没有统一到www域名的逻辑。 - 443端口虚拟主机未配置裸域到www的重定向规则,请求跳转到HTTPS裸域后直接访问业务,不会继续跳转。
- 附加配置错误:80端口
Directory块路径(/var/www/example/public)与DocumentRoot路径(/var/www/release.example/public)不一致,会导致目录权限、Symfony路由规则不生效。
修复方案
1. 重新签发覆盖双域名的证书
必须先让证书同时信任裸域和www域名,才能正常处理HTTPS裸域的重定向:
certbot --apache -d example.com -d www.example.com
签发后执行certbot certificates可确认证书覆盖的域名列表。
2. 替换VirtualHost配置
推荐拆分为三个职责独立的虚拟主机,避免规则冲突:
- 80端口虚拟主机:统一处理所有HTTP请求,跳转到HTTPS www域名
- 443裸域虚拟主机:处理HTTPS裸域请求,跳转到HTTPS www域名
- 443 www虚拟主机:运行业务服务
HTTP 80端口配置
<VirtualHost *:80> ServerAdmin email@example.com ServerName example.com ServerAlias www.example.com ServerSignature Off RewriteEngine On RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [L,R=301,NE] ErrorLog ${APACHE_LOG_DIR}/http_redirect_error.log CustomLog ${APACHE_LOG_DIR}/http_redirect_access.log combined </VirtualHost>
HTTPS 443裸域跳转配置
<IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin email@example.com ServerName example.com ServerSignature Off RewriteEngine On RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [L,R=301,NE] Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem ErrorLog ${APACHE_LOG_DIR}/ssl_apex_error.log CustomLog ${APACHE_LOG_DIR}/ssl_apex_access.log combined </VirtualHost> </IfModule>
HTTPS 443 www业务配置
<IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin email@example.com ServerName www.example.com ServerSignature Off DocumentRoot /var/www/release.example/public DirectoryIndex index.php <Directory /var/www/release.example/public> Options FollowSymLinks AllowOverride All Require all granted </Directory> <FilesMatch \.php$> SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost" </FilesMatch> Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> </IfModule>
可选简化写法
如果不想拆分两个443虚拟主机,可以保留原有单443结构,在虚拟主机内添加基于Host的判断规则:
RewriteEngine On RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [L,R=301,NE]
其余业务、SSL配置保持不变即可。
验证步骤
- 执行
apache2ctl configtest检查配置语法,确认无报错后重启Apache:systemctl restart apache2 - 301永久重定向会被浏览器持久缓存,测试阶段建议使用无痕窗口,避免旧缓存干扰。
内容的提问来源于stack exchange,提问作者dodo
相关产品推荐
相关产品推荐

