根本原因是客户端默认拒绝信任自建ca且服务端未覆盖所有通信路径:mongosh或驱动连接需显式指定--tlscafile或tlscafile参数,副本集内部通信必须配置net.tls.clusterfile,且证书须满足o/ou一致、含san、私钥不加密等严格要求。

根本原因不是证书本身无效,而是客户端默认拒绝信任自建CA,且服务端配置未覆盖所有通信路径。
mongosh 或驱动连接失败:缺 --tlsCAFile 或连接字符串里没传 tlsCAFile
即使你用 OpenSSL 生成了自签名证书并配好了 net.tls.certificateKeyFile 和 net.tls.CAFile,mongosh 默认仍会校验服务端证书是否由可信 CA 签发。自建 CA 不在系统信任链里,必须显式指定:
- 命令行用
mongosh --tls --tlsCAFile /path/to/ca.crt --host example.com:27017 - 连接字符串加参数:
mongodb://example.com:27017/?tls=true&tlsCAFile=%2Fpath%2Fto%2Fca.crt(注意 URL 编码) - PyMongo 必须传
tlsCAFile参数,仅设tls=True不够;Java 驱动同理,需sslContext或tlsCAFile显式加载 CA - 如果漏掉这个,错误通常是:
unable to verify the first certificate或certificate signed by unknown authority
副本集内部通信卡在 STARTUP2:没配 net.tls.clusterFile
这是最容易被忽略的致命点。开启 requireTLS 后,节点间心跳、oplog 拉取默认仍走明文——除非你单独提供集群专用证书:
-
net.tls.clusterFile必须指向一个独立的 PEM 文件(不能复用certificateKeyFile),且该文件里的证书 Subject 必须匹配所有成员的host配置(或 SAN 列表) - 所有副本集成员都得配这个字段,哪怕只启用了单向 TLS
- 不配的话,从节点日志反复出现
no SSL certificate provided或connection refused,但主节点状态仍是PRIMARY,看起来“正常”,实则同步已中断 - 验证方法:在主节点执行
rs.status(),看members[n].stateStr是否稳定为SECONDARY,以及health是否为 1
证书内容不满足 MongoDB 成员身份校验要求
MongoDB 副本集启用 TLS 后,不仅加密,还用 X.509 证书做节点身份认证。它会严格比对证书中的组织字段:
- 所有成员证书必须有相同的
O(Organization)、OU(Organizational Unit),若写了多个OU,顺序和值必须完全一致 - 证书必须包含
subjectAltName(SAN),且至少覆盖该节点的 hostname 或 IP(MongoDB 4.2+ 支持 IP 匹配) - 私钥不能加密:PEM 文件里不能有
DEK-Info行,否则 mongod 启动报Failed to load certificate file: bad password - 用
openssl x509 -in cert.pem -text -noout检查字段,别只看能不能 openssl s_client 连上
真正麻烦的从来不是生成证书,而是让 MongoDB 同时满足「对外可连」「对内可通」「对驱动可信」这三件事——每条路径的证书、CA、校验开关都得单独对齐,漏一个就静默失败。











