HTTPS现在基本是标配,但配起来出错的情况真的不少。很多错误看起来各不相同,其实原因就那几类,摸清楚了基本不会被绕晕。
证书不受信任 / NET::ERR_CERT_AUTHORITY_INVALID
这个报错最常见的原因是证书链不完整。SSL证书分为根证书、中间证书和叶证书,浏览器需要能从你的证书一路验证到它信任的根证书。如果中间证书没有正确配置,浏览器就会报错。
解决方法:去证书提供商那里下载完整的证书链文件(通常是fullchain.pem或者包含中间证书的bundle.crt),配置Nginx或Apache时要用完整链文件,不要只用叶证书。
# Nginx正确配置示例
ssl_certificate /etc/ssl/certs/fullchain.pem; # 完整链
ssl_certificate_key /etc/ssl/private/privkey.pem;
用Let’s Encrypt的话,certbot会自动生成完整链,不存在这个问题。
证书和域名不匹配
申请证书时填写的域名要和实际访问的域名完全一致。
example.com和www.example.com是两个不同的域名,申请时要确认包含两者,或者申请通配符证书*.example.com- 子域名也要单独申请,或者申请SAN证书把多个域名写进去
用certbot申请时可以-d参数指定多个域名:
certbot --nginx -d example.com -d www.example.com
HTTP和HTTPS混合内容警告(Mixed Content)
站点改成HTTPS后,如果页面里还有图片、JS、CSS是通过HTTP加载的,浏览器会报Mixed Content警告,严重的会直接阻止加载。
WordPress用户可以安装Really Simple SSL插件,会自动把绝大多数HTTP资源替换成HTTPS。
也可以在wp-config.php里加:
define('FORCE_SSL_ADMIN', true);
然后检查数据库里有没有硬编码的HTTP链接,用插件”Better Search Replace”全局替换一遍。
证书已过期
Let’s Encrypt证书每90天过期一次,如果没有设置自动续期会出问题。
# 检查自动续期定时任务
crontab -l | grep certbot
# 手动测试续期(不会真正续期)
certbot renew --dry-run
建议同时在证书到期前一周设置监控告警,推荐用UptimeRobot,免费版就能监控SSL证书到期时间。
HSTS导致无法访问
这个坑比较隐蔽。如果之前开启了HSTS(HTTP Strict Transport Security),浏览器会强制用HTTPS访问你的域名,并把这个记录缓存下来。
如果后来证书出了问题或者你想临时改回HTTP,浏览器会拒绝访问,报ERR_SSL_PROTOCOL_ERROR,清缓存也没用。
解决方法:在Chrome地址栏输入chrome://net-internals/#hsts,找到你的域名,点Delete,清除HSTS记录。
如果是Nginx配置了HSTS响应头:
add_header Strict-Transport-Security "max-age=31536000" always;
先把max-age改成0,等待缓存过期后再处理其他问题。
快速自查工具
遇到HTTPS问题先去 SSL Labs 跑一遍,它会给出详细的证书链、配置问题和评级,大部分问题在报告里都能找到线索。