Percona Server for MongoDB X.509 证书轮换:在不中断服务的情况下完成续期

2026-08-31 41 预计阅读时间: 1 分钟
来源: percona.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

X.509 证书过期的影响不只是客户端无法建立新的 TLS 连接。如果 Percona Server for MongoDB 使用 X.509 进行副本集或分片集群内部认证,过期证书还会阻止成员之间相互认证,最终影响集群通信。

比较稳妥的做法是进行一次同 CA 续期:继续使用现有 CA,为服务器、集群成员和客户端分别签发新的叶子证书,然后按照滚动方式逐个替换并重启实例。这样可以把服务影响限制在单个节点的切换窗口内。

先明确证书角色和兼容边界

MongoDB 环境中通常至少有三类证书:

  • 服务器证书:用于客户端到 MongoDB 节点的 TLS 连接。
  • 成员证书:用于副本集成员或分片集群节点之间的 TLS 连接和 X.509 内部认证。
  • 客户端证书:用于启用 X.509 认证的应用、运维工具或其他客户端。

同 CA 续期的关键是保持信任链不变。新证书应由当前生产 CA 签发,并满足现有连接方式要求。签发时需要特别检查:

  • Not BeforeNot After 时间,避免新证书尚未生效或有效期过短。
  • subjectAltName 中包含客户端实际使用的 DNS 名称或 IP 地址。
  • Extended Key Usage 与用途匹配,服务器证书和客户端证书不要混用。
  • 成员之间用于认证的身份字段仍符合当前 MongoDB 配置和授权规则。
  • 私钥权限足够严格,MongoDB 运行用户可以读取,但普通用户不能读取。

可以这样检查现有证书和新证书。下面的文件名只是示例,实际路径应替换为环境中的证书路径:

#!/usr/bin/env bash
set -euo pipefail

CERT="/etc/mongodb/tls/mongodb-server.pem"
CA="/etc/mongodb/tls/ca.crt"

openssl x509 -in "$CERT" -noout \
  -subject -issuer -dates -serial -ext subjectAltName -ext extendedKeyUsage

openssl verify -CAfile "$CA" "$CERT"

如果部署使用的是包含证书和私钥的 PEM 文件,应该另外确认 PEM 内容完整,并检查私钥是否与证书匹配:

openssl x509 -in /etc/mongodb/tls/mongodb-server.pem -noout -pubkey \
  | openssl pkey -pubin -outform pem > /tmp/cert.pub

openssl pkey -in /etc/mongodb/tls/mongodb-server.pem -pubout \
  > /tmp/key.pub

diff -u /tmp/cert.pub /tmp/key.pub
rm -f /tmp/cert.pub /tmp/key.pub

采用滚动轮换,而不是同时重启

副本集应保留足够的健康成员,使剩余节点能够继续提供读写服务。常见的轮换顺序如下:

  1. 在所有节点上准备新证书,但暂时不要覆盖正在使用的文件。
  2. 先轮换一个从节点。
  3. 等待该节点重新加入副本集,并确认复制状态正常。
  4. 依次处理其他从节点。
  5. 在主节点上执行受控切换,让一个健康从节点成为新的主节点。
  6. 轮换原主节点,并确认它重新追上复制进度。
  7. 轮换客户端证书,并验证应用连接。

开始前应记录集群状态:

mongosh --host mongo-a.example.com --tls \
  --tlsCAFile /etc/mongodb/tls/ca.crt \
  --tlsCertificateKeyFile /etc/mongodb/tls/admin-client.pem \
  --authenticationDatabase '$external' \
  --authenticationMechanism MONGODB-X509 \
  --eval 'rs.status().members.map(m => ({name:m.name, stateStr:m.stateStr, health:m.health, optime:m.optimeDate}))'

对从节点进行替换时,可以先把新文件放到临时路径,再用原子方式切换。假设 Percona Server 使用 systemd 管理,示例流程如下:

set -euo pipefail

NODE="mongo-b.example.com"
REMOTE_CERT="/etc/mongodb/tls/mongodb-server.pem"
NEW_CERT="/var/tmp/mongodb-server-2025.pem"

scp "$NEW_CERT" "$NODE:/var/tmp/mongodb-server.pem.new"
ssh "$NODE" "sudo chown mongodb:mongodb /var/tmp/mongodb-server.pem.new && \
  sudo chmod 0600 /var/tmp/mongodb-server.pem.new && \
  sudo mv /var/tmp/mongodb-server.pem.new $REMOTE_CERT && \
  sudo systemctl restart mongod"

重启后不要只看 systemd 的进程状态,还要从 MongoDB 角度确认节点已经恢复:

mongosh --host mongo-b.example.com --tls \
  --tlsCAFile /etc/mongodb/tls/ca.crt \
  --tlsCertificateKeyFile /etc/mongodb/tls/admin-client.pem \
  --authenticationDatabase '$external' \
  --authenticationMechanism MONGODB-X509 \
  --eval 'db.adminCommand({hello: 1})'

对于副本集,进一步检查 rs.status() 中该成员的 healthstateStr 和复制延迟。对于分片集群,除了各分片副本集,还要覆盖 config server 副本集和 mongos。mongos 是否需要重启取决于其 TLS 配置和证书使用方式;应按实际部署逐个验证,而不是默认同时处理所有路由进程。

主节点切换要有明确的回滚点

轮换主节点前,先确保至少有一个健康从节点,并确认应用具备自动发现和重连能力。可以在维护窗口内执行受控 stepdown:

mongosh --host mongo-a.example.com --tls \
  --tlsCAFile /etc/mongodb/tls/ca.crt \
  --tlsCertificateKeyFile /etc/mongodb/tls/admin-client.pem \
  --authenticationDatabase '$external' \
  --authenticationMechanism MONGODB-X509 \
  --eval 'db.adminCommand({replSetStepDown: 60, secondaryCatchUpPeriodSecs: 30})'

这个命令会触发主节点让位,实际超时时间和选举行为取决于副本集配置、节点健康状况以及客户端驱动的重试能力。执行前应确认:

  • 应用连接字符串包含副本集名称,而不是固定指向单个主机。
  • 驱动启用了合理的连接超时、选择超时和重试策略。
  • 监控系统能够区分正常选举和异常故障。
  • 新主节点已经使用有效证书并能与其他成员完成内部认证。

如果新节点无法启动或无法重新加入,不要继续轮换下一个节点。保留旧证书文件和配置备份,先恢复当前节点,再分析证书链、SAN、私钥权限、MongoDB TLS 配置和系统时间。

客户端证书不要与服务端证书一起仓促切换

服务器和成员证书验证通过后,再轮换客户端证书。可以先在一台非生产客户端或单个应用实例上验证:

mongosh "mongodb://mongo-a.example.com,mongo-b.example.com,mongo-c.example.com/?replicaSet=rs0" \
  --tls \
  --tlsCAFile /etc/mongodb/tls/ca.crt \
  --tlsCertificateKeyFile /etc/mongodb/tls/app-client.pem \
  --authenticationDatabase '$external' \
  --authenticationMechanism MONGODB-X509 \
  --eval 'db.runCommand({connectionStatus: 1})'

验证成功后,再按应用实例逐步替换客户端 PEM 文件并滚动重启。旧客户端证书可以保留到所有应用完成切换,但是否允许新旧证书并存,取决于 MongoDB 的授权规则、证书主题映射和应用部署方式。不要假设“同一个 CA 签发”就一定意味着旧证书和新证书拥有完全相同的认证身份。

一份可执行的轮换清单

  • 在测试环境使用同一 CA 流程演练。
  • 盘点所有 MongoDB、config server、mongos、备份工具和客户端证书。
  • 确认新证书的 SAN、用途、有效期和证书链。
  • 检查所有节点的系统时间和 NTP 状态。
  • 先轮换从节点,逐个等待健康状态恢复。
  • 通过受控 stepdown 轮换主节点。
  • 分别验证客户端 TLS 和成员间 X.509 认证。
  • 保留旧证书和回滚方案,但设置明确的清理时间。
  • 在证书到期前配置监控和告警,避免下一次轮换变成故障恢复。

同 CA 续期降低了信任链变化带来的风险,但并不意味着可以跳过验证。真正决定中断时间的,是证书预检查、节点级滚动操作、应用重连能力,以及每一步之后是否确认集群已经恢复健康。


相关推荐