Caddy 中间证书过期排查:3 个检查点定位,两条路径一次搞定
【免费下载链接】caddyFast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS项目地址: https://gitcode.com/GitHub_Trending/ca/caddy
凌晨 2 点,值班群弹出第一条用户反馈:网页打不开,浏览器弹"您的连接不是私密连接"。你第一件事打开控制台敲openssl x509查域名证书,有效期还剩下两个月——证书明明没过期,为什么 HTTPS 全挂了?这种"叶证好好的、连接却报证书错误"的故障,大概率是Caddy 中间证书过期:服务端送出的完整证书链里,垫在中间的那一环失效了。
先别急着改配置。用下面的分诊流程,几分钟就能确认到底是不是中间证书在作妖。
3 个检查点:快速确认是不是 Caddy 中间证书过期
检查点 1:服务端叶证本身是否有效。在服务器上直连自己的站点,确认第一张证书的有效期:
openssl s_client -connect example.com:443 -servername example.com \ -showcerts 2>/dev/null | openssl x509 -noout -issuer -subject -dates如果叶证(subject 是域名的那张)没过期,别停在这里,继续第二点。
检查点 2:看服务端实际送出了几张证书、中间那张是谁。-showcerts的输出里,Certificate chain:段应至少有两张:索引 0 是叶证,索引 1 是中间证书。把索引 1 单独拿出来看日期,或直接验证整条链:
openssl verify -CAfile 中间证书.pem 叶证书.pem返回untrusted、certificate has expired或干脆提示拿不到签发者,基本可以锁定:中间证书过期(或链路缺环)。
检查点 3:排除本地干扰。用一台不同运营商网络(或手机热点)的机器复测。都报同样的错,说明问题在服务器送出的链路上,而不是某台客户端的根证书库太旧。
三步走完,结论无非两种:叶证本身到期(那就是常规续期问题),或者中间证书失效(本文主角)。Caddy 证书链 排查的关键就在第 2 步——多数人会漏掉"服务端到底送了几张证书"这个细节。
为什么好好的证书链会突然断:担保链与 CA 轮换
打个比方。你去找一个陌生供应商签单,他递来一份介绍信:供应商本人(服务器证书)由区域公司(中间证书)担保,区域公司再由集团总部(根证书)担保。浏览器不直接认供应商,它沿着这条担保链一路验到内置的总部名单。
这条链上任何一环失效,整个信任就断了。而CA 会定期轮换中间证书——Let's Encrypt 的中间证书(E5、E6、R10、R11……)每隔几年换代一次,旧的到点即废。如果你的服务器用的是手工配置的固定证书链文件,叶证每 90 天自动续期续得再勤,链文件里那张老中间证书照样会到期。这就是"证书没过期、HTTPS 却挂了"的根源。
Caddy 证书链 排查时,这个认知能帮你直接排除"叶证没问题就是没事"的错觉:链上最短的那块板决定水位。
两条修复路径:先止血,再断根
临时方案:手动补齐证书链(止血)
从 CA 官网下载当前有效的中间证书,把它拼到叶证后面,组成完整链文件,再让 Caddy 的tls指令指向它:
example.com { tls /etc/certs/example-chain.pem /etc/certs/example.key }改完用caddy reload --config Caddyfile热加载,再跑一遍检查点 2 确认链完整。注意这只是止血:叶证到期会再触发同样的问题,而你的链文件下次换中间证书时还得手动改一遍。
长期方案:让 Caddy 自动维护证书链(断根)
只要不写auto_https off,Caddy 默认会对域名启用自动 HTTPS:证书签发、续期、连同中间证书在内的整条链,都由它对接 ACME 协议自动拉取和维护。CA 轮换中间证书时,下次续期拿到的自然就是新链。你只需要确认两点:
{ storage file_system /var/lib/caddy # 固定存储,避免证书随容器重建丢失 renewal_window_ratio 0.5 # 提前约一半有效期就续 }相关逻辑集中在 modules/caddytls/,配置解析在 caddyconfig/httpcaddyfile/tlsapp.go。把renewal_window_ratio调小一点(如0.5),相当于把续期动作往前挪,给"续期失败再来一次"留出缓冲窗口。
把故障挡在门外:日志 + metrics 双保险
📋 治完一次,就该防下一次。展开两个手段就够:
- 日志:Caddy 的 TLS 事件(签发、续期、失败)都会进日志。全局设
log { level info },然后对关键词续期失败(renewal 相关报错)做日志采集告警。链问题往往在续期那一刻就埋下伏笔,而不是故障当天。 - metrics:全局开启
metrics后,Prometheus 端点里带有 TLS 证书到期时间戳。配一条规则:到期时间 - now() < 30 天就告警,中间证书这类"隐藏环"过期前 30 天就能被抓到。
两个手段选一个落地即可;有 Prometheus 的就走 metrics,没有的就把日志接进告警管道。预警的本质是让告警比用户反馈先 30 天到达。
✅ 证书链健康自查清单
- 最近一次用
openssl s_client -showcerts核过服务端实际送出的证书张数(≥2)? - 链中每张证书的
notAfter都确认过,而不只是叶证? - Caddy 的证书存储路径固定且已备份(
storage配置),重建机器不会丢链? - 手动维护的证书域,知道对应 CA 的中间证书轮换公告在哪看?
- 自动 HTTPS 域未误开
auto_https off/disable_certs? - 续期日志里有失败记录吗?(翻最近一次续期的日志段)
- metrics 或日志告警已覆盖"证书 30 天内到期"这一事件?
勾完这 7 项,下次凌晨 2 点的证书告警,大概率轮不到你。
【免费下载链接】caddyFast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS项目地址: https://gitcode.com/GitHub_Trending/ca/caddy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考