证书运维:签发、续期与 HSTS 的纪律
十几张证书、多台服务器、两种验证通道。证书这张纸背后的运维体系:自动化、双路径、台账,以及为什么 preload 永不撤销。
网站的证书是最典型的“出事前没人想起”的东西。签发那天皆大欢喜,到期那天全网红牌。我们手上运转的证书已经两位数,这篇把整套运维体系写下来。
签发:两条验证通道
证书签发的核心问题是向签发机构证明你控制这个域名,主流两条通道。HTTP 验证:在网站根下放一个验证文件,签发机构来读——前提是这个域名的解析直达你的服务器。DNS 验证:往域名解析里加一条临时记录——前提是你有解析服务的接口权限。
两条通道各有一片死区。HTTP 通道怕 CDN:如果域名指向了边缘节点,验证请求会被边缘接住,需要验证穿透,或不带缓存的路径直达。DNS 通道怕没有接口权限:解析服务不开放接口,就只能手工加记录,自动化无从谈起。我们的实战组合是:解析直连的站点走 HTTP 验证全自动;泛域名证书(一张管所有子域名)必须走 DNS 验证,为此专门配了解析接口的凭据,让自动化跑通。
还有一个部署细节值得单说:多路径环境的证书要同时落到“容器视图”和“宿主机备份”两条路径,续期钩子里做完同步再平滑重载——只落一条路径,另一边就是定时炸弹。
续期:自动化之外的人肉兜底
签发时把续期动作写成钩子,之后全自动,这是标准做法。但我们的台账上还有人工流程,原因写得很直白:自动化的链条上任何一环都可能静默断掉——解析服务的接口凭证过期了、磁盘满了写不进文件、钩子里的重载命令权限变了,任何一种都会让“自动续期”变成“悄无声息地失效”,然后在某个凌晨,所有浏览器亮红牌。
人工流程三件事:一张台账(每张证书的到期日、验证通道、部署路径);每月一次到期窗口巡检;每次续期后验证线上真的换新了——看证书的实际有效期,不是看工具输出“成功”。这套人肉流程不是对自动化的不信任,是对“静默失败”的防御纵深。
验证通道的选择决策树
把签发通道的选择整理成决策树,三问定案。第一问:域名的解析是否直达你的服务器且八十端口可从公网访问?是,走 HTTP 验证,全自动无维护。第二问:要签的是泛域名吗?是,只能走 DNS 验证,没有选择。第三问:解析服务有没有接口权限?有,自动化;没有,两条路——手工加记录(每次续期手工,可接受但不优雅),或者把域名解析迁到有接口的服务商(一劳永逸,迁移成本半小时)。我们的组合就是按这棵树长出来的:解析直连的站点全走 HTTP 验证,泛域名走配好接口凭据的 DNS 验证,面板托管作为展示与托管的第二落点。
一个反面案例:面板自动签发的失败
集成化管理面板自带的证书签发功能,在这台服务器上全线失败,报错指向“无法确定验证方式”。深挖发现:面板的验证方式需要临时占用八十端口起一个临时服务应答验证请求,而八十端口被面板自己的反代常驻占用——它的签发功能与它的反代在架构上互斥。绕不过去,最终定成双轨制:命令行工具签发,签完把证书与密钥导入面板托管,两边各取所长。教训:集成工具的自动化是“最常见的路径”的自动化,架构稍有偏差就失效,手工通道永远要留。
两阶段上线的标准流程
新域名上线,标准流程是两个阶段。第一阶段只部署八十端口的验证应答目录,其余一概不放——这个阶段的存在意义是让签发机构的验证请求有东西可读。第二阶段签发完成、证书就位后,再切换到完整配置:八十跳转加密,四四三带完整业务。两阶段之间裸奔窗口以分钟计。为什么这么谨慎?因为主站声明过包含子域名的强制加密策略,老访客的浏览器会对新子域强制走加密——证书没就位就开放解析,等于对一部分用户直接关门。这个顺序不是洁癖,是策略的必然推论。
HSTS:一条不许撤的红线
全站强制加密的 HSTS 头里,如果声明了“包含子域名”甚至进了浏览器的预载名单,意味着全浏览器层面强制 HTTPS,而撤出预载名单以年为单位——这是单向门。我们的纪律是: preload 状态永不移除;新子域上线必须先备好有效证书再开放解析,因为老访客的浏览器会强制走 HTTPS,裸奔期的站点对他们直接不可达。
实践中有过真实场景:新站上线时采用两阶段——先只开 HTTP 验证通道把证书签出来,再切完整配置,把“裸奔窗口”压缩到分钟级。这个顺序看起来绕,实际是 HSTS 纪律的必然推论。
一点延伸
证书体系还有一个容易被忽略的维度:面板工具的自动签发不一定可用。我们遇到过面板自带的签发功能因端口被占而全线失败的场景,最后回到命令行工具手工签、导入面板托管的双轨制。工具越集成,越要保留一条手工通道。
证书运维的全部要义,是承认一件事:它的故障模式是“到某天突然全坏”,而那一天离今天很远,远到人脑一定忘。所以所有环节——签发、续期、部署、验证、台账——都必须设计成“不依赖任何人的记性”。