HTTPS 证书最怕第一次申请成功,三个月后续期失败才发现入口已经过期。
\n
家庭服务上 HTTPS 以后,浏览器不再弹红字只是第一步。真正麻烦的是证书续期、验证方式、DNS 记录和反代配置之间的关系。第一次申请证书时,人通常在旁边盯着;续期发生在几个月后,如果日志没人看、提醒没人设,等家里人说页面打不开时,问题已经影响使用了。
先选清楚验证方式
HTTP challenge 依赖 80 端口能被验证服务访问到,DNS 记录要指向当前入口,NPM 或其他反代不能把验证路径转走。它的优点是直观,缺点是入口链路和端口策略必须配合。家里如果 80 端口被其他服务占用,或者入口只打算开放 443,就要提前评估是否适合。
DNS challenge 不依赖入口端口,但依赖 DNS 服务商 API 和域名解析权限。它适合通配符证书,也适合不想开放 HTTP 验证入口的场景。代价是 API 凭据要安全保存,不能随手写在公开文档或截图里。无论哪种方式,我都会把验证方式、域名、DNS 服务商、续期账号写在维护记录里。
我还会记录证书使用范围。单域名证书适合一个入口一个服务,通配符证书适合多子域统一管理,但权限影响也更大。通配符证书一旦被误用,影响的不是单个页面,而是一批入口。所以证书放在哪台机器、被哪些反代规则引用、谁有权限更新,都要有清单。
续期失败要按链路排查
证书失败不要只盯着 NPM 面板上的错误提示。HTTP challenge 先查域名解析是否到当前公网入口,再查 80 端口是否真的到达 NPM,最后看验证路径有没有被错误代理。DNS challenge 先查 API 凭据是否有效,再查 TXT 记录是否成功写入、是否被缓存延迟影响。
我会用几条命令把问题拆开:dig example.com 看解析,curl -I http://example.com/.well-known/acme-challenge/test 看 HTTP 路径,openssl s_client -connect example.com:443 -servername example.com 看当前证书链。命令不需要每天跑,但续期失败时它们比反复点按钮更快。
证书目录必须持久化
在 NPM 里,./letsencrypt:/etc/letsencrypt 不是可有可无的缓存目录。它保存证书文件、账户信息和续期历史。容器可以重建,证书目录不能随手删;否则可能触发重复申请、限频、证书丢失或历史配置失效。和它配套的 ./data:/data 也要一起备份,因为证书绑定在哪些 Proxy Host 上,规则在 data 里。
我在升级前会先复制 data 和 letsencrypt,并记录证书到期时间。恢复时不会只看 NPM 页面,而是访问实际域名,确认浏览器显示的证书颁发对象、有效期和链路都对。证书相关问题很容易被缓存掩盖,所以最好用无痕窗口、手机网络或 openssl 再测一遍。
过期提醒比事后抢修可靠
证书有效期应该进入月度巡检。Uptime Kuma、脚本或监控系统都可以做证书过期提醒,阈值不必太激进,提前 20 到 30 天知道就足够安排处理。提醒内容要包括域名、剩余天数和入口位置,避免收到一条“证书快过期”却不知道是哪台机器。
我也会保留上一份可用配置的回滚方案。续期脚本失败时,不能为了“修好 HTTPS”随手删除证书目录;更稳的做法是备份现场、确认验证方式、看日志,再决定是否手工重新申请。HTTPS 的维护重点不是证书申请按钮,而是让续期、备份、提醒和失败排查形成闭环。
如果浏览器已经提示证书失效,我会先确认系统时间是否正确,再看证书链和到期时间。NAS 时间漂移、路由器 DNS 缓存、反代没有热加载,都可能让问题看起来像同一种“HTTPS 不可信”。把这些因素拆开,处理速度会快很多。
证书替换后还要确认客户端看到的确实是新证书。有些反代会保留旧连接,移动端 App 也可能缓存状态。我会用 openssl 看服务端返回,再用浏览器重新打开域名,最后抽查一个真实客户端。只有入口、证书链和客户端表现都一致,才算续期闭环完成。
自签证书和内网证书我会单独标记,避免和公网可信证书混在一起。家庭内部测试可以临时使用,但长期入口要写清签发来源、信任范围和到期提醒。
最后我会把证书续期时间写进月度清单,和反代备份一起检查。
这条记录会和域名清单放在一起,方便迁移入口时核对。
此处评论已关闭