必须用x.509的场景是集群节点跨网络边界(如config server、shard、mongos分属不同网段),因其支持证书绑定角色、满足最小权限原则;keyfile仅适用于单机多实例本地测试或完全隔离的离线开发环境。

keyFile 和 X.509 不是“选哪个更方便”的问题,而是“在什么场景下必须用哪个”的问题。生产环境只应使用 X.509,keyFile 仅限封闭内网快速验证。
什么时候必须用 X.509?
只要集群节点跨网络边界(比如 config server 在 A 网段、shard 在 B 网段、mongos 在 C 网段),就必须用 X.509。它支持证书绑定角色(例如限制某证书只能作为 shard 成员,不能冒充 config server),满足最小权限原则。
常见误判场景:
- 以为“所有机器都在 VPC 内”就算安全 —— 实际上 VPC 内部横向移动风险依然存在,
keyFile泄露即全集群沦陷 - 用自签名 CA 但没校验证书有效期或
subject字段 —— 导致连接时静默失败,日志只报SSL handshake failed,不提示时间偏移或 DN 冲突 - 混用:部分 mongod 启用了
X.509,部分还留着keyFile—— 集群无法完成初始化,rs.status()卡在STARTUP2
keyFile 唯一可用的场景
keyFile 只适合单机多实例本地测试(比如用 docker-compose 跑一个伪分片),或完全隔离的离线开发环境。
实际部署中极易踩坑:
-
keyFile文件权限必须是600,且所有节点内容逐字节一致 —— 多一个空格、换行符或 BOM 就报Failed to load key file: Invalid key file format - 没有证书生命周期管理能力,密钥轮换需停机全量替换,无法灰度
- 不提供审计线索:无法区分“谁连进来”,只能确认“是不是集群成员”
升级路径不是“替换”,而是“滚动切换”
已有 keyFile 集群不能直接删掉 keyFile 改配 X.509,必须走滚动升级:
- 先在所有节点配置里加
security.clusterAuthMode: sendKeyFile和net.tls.clusterFile,保留旧密钥文件,同时启用证书路径 - 重启节点时,它会继续发
keyFile,但也能收并验证其他节点的X.509证书 - 等全部节点都支持双模式后,再把
clusterAuthMode改成x509,最后清理keyFile配置
跳过中间态直接切,会导致部分节点拒绝加入集群,错误日志里只有模糊的 Unable to reach primary,查不到认证层原因。
客户端连接 X.509 时最容易漏的三件事
服务端配好了 X.509,客户端连不上,大概率卡在这三点:
- 没在连接 URI 里显式指定
authMechanism=MONGODB-X509—— 默认用 SCRAM,根本不会走证书流程 -
tlsCertificateKeyFile指向的是客户端证书+私钥合并的 PEM,不是单独的 crt 或 key 文件 - 没提前在
$external数据库里创建用户:db.getSiblingDB("$external").createUser({user: "CN=client,OU=app,O=org",roles: [{role:"readWrite",db:"mydb"}]}),证书 subject 必须一字不差匹配
证书 subject 的 O、OU、DC 字段还必须和服务器证书不同,否则会被拒绝 —— 这个检查默认开启,不能靠参数关,只能靠生成时错开。











