必须用openssl自签证书且每个节点证书含完整san(dns+ip),否则副本集无法握手;不配net.tls.clusterfile,从节点卡startup2,主节点状态正常但实际分裂;证书缺san、私钥加密、cafile或clusterfile配置错误均导致静默失败。

必须用 OpenSSL 自签证书,且每个节点的证书要带完整 SAN(DNS + IP),否则副本集成员根本无法握手;net.tls.clusterFile 不配,从节点就卡在 STARTUP2,主节点状态看起来正常但实际已分裂。
证书必须含完整 subjectAltName,不能只靠 CN
mongod 启动时不会报错,但客户端连不上、副本集同步失败,日志里反复出现 SSL peer certificate validation failed 或 connection refused。根本原因是证书没包含所有访问路径的 DNS 名和 IP 地址。
- 生成 CSR 时必须显式加
-addext "subjectAltName = DNS:node1.example.com,IP:192.168.1.10,IP:127.0.0.1"(OpenSSL 1.1.1+) - 用
openssl x509 -in server.pem -text -noout | grep -A1 "Subject Alternative Name"确认字段存在且内容完整 -
mkcert或 Let’s Encrypt 直接生成的证书基本不可用——前者默认无 SAN,后者通常不覆盖内网 IP - 证书私钥不能加密:文件里不能有
DEK-Info行,否则启动报Failed to load certificate file: bad password
net.tls 配置缺一不可,mode 只是开关
net.tls.mode: requireTLS 只是启用 TLS 的总闸,真正起效靠另外三个字段。漏掉任一个,mongod 启动可能静默成功,但 TLS 连接实际被拒。
-
net.tls.certificateKeyFile:必须是 PEM 格式,且文件里同时含证书和私钥(顺序无所谓,但不能只放证书) -
net.tls.CAFile:即使只做单向认证(服务端验证),也必须填自建 CA 的ca.crt;否则mongosh和 4.2+ 驱动默认校验失败 -
net.tls.allowConnectionsWithoutCertificates:设为true才允许 mongosh、Compass 等不带客户端证书的连接;设false就强制双向认证,但没配clusterFile会导致副本集内部通信中断
副本集成员间通信必须单独配 clusterFile
这是最容易被忽略的一环。即使所有节点都开了 requireTLS,心跳、oplog 拉取、选举投票默认仍走明文。不配 net.tls.clusterFile,从节点会一直卡在 STARTUP2,rs.status() 显示 HEALTH: 0,但主节点状态仍是 PRIMARY,极具迷惑性。
-
net.tls.clusterFile必须指向一个独立 PEM 文件,内容是该节点自己的私钥 + 证书(可复用certificateKeyFile,但官方建议隔离) -
net.tls.clusterCAFile必须和net.tls.CAFile指向同一个ca.crt - 所有节点的
clusterFile都得配,哪怕只有两个节点——少一个,集群就无法形成有效拓扑
客户端连接必须显式声明 tls 选项
客户端不会自动探测服务端是否启用了 TLS。不加参数就按普通 TCP 连,结果不是连不上,就是连上几秒后断开,错误通常是 connection ended 或 SSL handshake failed。
- 命令行:
mongosh --tls --tlsCAFile /path/to/ca.pem "mongodb://node1.example.com:27017/?replicaSet=rs0" - Node.js(Mongoose):
mongoose.connect(uri, { tls: true, tlsCAFile: '/path/to/ca.pem' });注意旧版驱动用ssl: true,混用会静默失效 - Python(PyMongo):
MongoClient('mongodb://node1.example.com:27017/', tls=True, tlsCAFile='/path/to/ca.pem') - 如果证书 SAN 不全,临时调试可加
--tlsAllowInvalidHostnames,但上线前必须修复证书,不能留这个开关
最麻烦的点不在配置项本身,而在于:证书 SAN 缺一个地址、clusterFile 漏配一个节点、或者 CAFile 路径写错权限不对(必须是 600),都会导致看似启动成功,实则集群无法收敛——这种问题查日志很难一眼定位,得逐节点确认证书内容、配置字段、文件权限三者是否全部对齐。











