SSL证书部署翻车实录:当HTTPS网站突然罢工时的8个排查姿势
上周三凌晨2点,我的手机突然被运维报警轰炸——刚部署SSL证书的电商站全面瘫痪。顶着黑眼圈爬起来排查时才发现,原来SSL部署的水比想象中深得多。今天就把这次血泪史整理成系统化的排查逻辑,下次你遇到类似情况时至少能少掉几根头发。
1. 先确认是不是SSL的问题
很多同学一看到HTTPS访问失败就直奔证书配置,结果发现其实是服务器宕机(别问我怎么知道的)。先用两个命令快速验证:
# 检查HTTP端口是否存活
curl -I http://example.com
# 检查HTTPS端口是否监听
netstat -tuln | grep 443
我习惯用这个顺序排查:网络连通性 → 服务状态 → 端口监听 → 证书配置。就像修车先看有没有油,再检查火花塞。
2. 证书链完整性检查
这次事故的罪魁祸首就是中间证书缺失。用OpenSSL诊断时发现个有意思的现象:
# 完整链能显示3层证书
openssl s_client -connect example.com:443 -showcerts
# 而我们的配置只返回了2层
-----BEGIN CERTIFICATE-----
[服务器证书]
-----END CERTIFICATE-----
(中间证书神秘消失)
血泪教训:某些CA提供的证书包里有多个.crt文件,要全部拼接到配置里。我后来养成了用SSL Shopper在线验证的习惯。
3. 时间同步问题
有次客户报障说证书”未生效”,结果发现服务器时间停留在1970年(是的,就是那个著名的Unix纪元)。现在我会第一时间检查:
# 服务器时间
date
# 证书有效期
openssl x509 -in certificate.crt -noout -dates
特别是K8s环境里的容器,经常因为时间不同步导致证书验证失败。建议所有服务器都配个NTP服务。
4. 协议/加密套件兼容性
老安卓设备访问失败?可能是TLS1.3支持问题。用这个命令模拟不同客户端:
# 测试TLS1.2兼容性
openssl s_client -connect example.com:443 -tls1_2
我现在的Nginx配置里一定会加上这段万能套件(当然要根据业务调整安全级别):
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256...';
5. 混合内容阻塞
最狡猾的问题之一:页面能打开但样式全乱。浏览器控制台会报:
Mixed Content: The page was loaded over HTTPS,
but requested an insecure script 'http://cdn.example.com/jquery.js'
我的解决方案是:
- 用
<meta http-equiv="Content-Security-Policy">
强制HTTPS - 或者更暴力的Nginx全局替换:
sub_filter 'http://' 'https://';
6. HSTS的甜蜜陷阱
启用HSTS后想回退HTTP?浏览器会无情拒绝。有次我在测试环境折腾了半天才发现这个”安全特性”:
Strict-Transport-Security: max-age=31536000; includeSubDomains
紧急方案:清浏览器HSTS列表,或者用新的域名测试。
7. 负载均衡器的神操作
AWS ALB有个坑:证书要挂在监听器上,而不是EC2实例。其他平台也各有各的脾气:
- Azure需要上传PFX格式证书
- 阿里云SLB要开启”双向认证”才能用自有证书
8. 证书缓存引发的血案
你以为改完配置就完事了?这些地方可能缓存旧证书:
- CDN边缘节点(记得手动刷新)
- 本地浏览器(Ctrl+F5不是万能的,试试隐私模式)
- 代理服务器(特别是企业网络)
凌晨4点终于修复时,我对着屏幕发誓要写这篇排查指南。下次你再遇到SSL问题,不妨按这个清单逐项检查,至少能省下两小时的生命值。如果还有其他奇葩案例,欢迎在评论区分享你的惊魂夜~
太实用了!上周也遇到同样问题,折腾到凌晨3点才发现是证书链不完整😭
求问楼主,nginx怎么判断443端口是不是被占用了?
时间同步那个坑最离谱,有次发现服务器时间居然比现实慢了两天…