启动mongod必须显式配置TLS参数,如--tlsMode=requireTLS和--tlsCertificateKeyFile;客户端连接需同步启用tls选项并指定CA文件;副本集与分片集群中每个节点(含mongos、config server等)均须独立配置,且证书需含完整SAN、权限为600。

启动mongod时必须指定TLS配置参数
不加任何TLS参数的mongod默认走明文通信,哪怕客户端开了SSL也没用。关键不是“客户端能不能连”,而是服务端有没有开启TLS监听。
-
--tlsMode=requireTLS是硬性开关,设为preferTLS会允许非加密连接,生产环境别这么干 -
--tlsCertificateKeyFile必须指向一个PEM文件,且该文件要同时包含证书和私钥(不能分开);常见错误是只放了证书没塞私钥,启动直接报Failed to load PEM certificate -
--tlsCAFile在启用客户端证书校验(--tlsAllowConnectionsWithoutCertificates设为false)时才需要,否则可省略 - 如果用的是MongoDB 4.2+,推荐用
--tlsMode=requireTLS --tlsCertificateKeyFile=/path/to/fullchain.pem这组最小可行配置
mongo shell或mongosh连接时要显式声明ssl选项
客户端不会自动探测服务端是否启用了TLS,不加参数就按普通TCP连,连上也立刻被断开,错误信息通常是 connection ended 或 SSL handshake failed。
- 命令行连:用
mongosh --tls --tlsCAFile /path/to/ca.pem "mongodb://localhost:27017/";如果服务端证书是自签且没加进系统CA,--tlsCAFile就不能少 - Node.js驱动中,
mongoose.connect()的options里得写{ tls: true, tlsCAFile: '/path/to/ca.pem' },漏掉tls: true就是裸连 - Python PyMongo同理:
MongoClient('mongodb://localhost:27017/', tls=True, tlsCAFile='/path/to/ca.pem');注意ssl参数名在旧版驱动里叫ssl,4.x+统一为tls,混用会静默失效
自签名证书最容易卡在主机名验证失败
mongod默认启用 --tlsAllowInvalidHostnames 关闭主机名检查,但客户端(尤其是mongosh和新驱动)默认严格校验CN或SAN。连不上十有八九是这个原因。
- 生成证书时,用
openssl req -subj "/CN=localhost"不够,必须加-addext "subjectAltName = DNS:localhost,IP:127.0.0.1"(OpenSSL 1.1.1+) - 或者连的时候绕过:mongosh加
--tlsAllowInvalidHostnames,Node.js驱动加tlsAllowInvalidHostnames: true;但这只是开发临时方案,上线前务必用正确SAN的证书 - 检查证书内容:用
openssl x509 -in fullchain.pem -text -noout | grep -A1 "Subject Alternative Name"确认字段存在且覆盖所有访问域名/IP
副本集和分片集群的TLS配置不能只改primary节点
每个 mongod 实例(包括仲裁节点、config server、mongos)都必须独立配置TLS参数,漏掉任何一个,整个集群就会出现部分连接加密、部分明文的混合状态,触发安全告警甚至拒绝同步。
- 副本集所有成员的
mongod.conf都要加上net.tls.mode: requireTLS和对应证书路径,且证书私钥权限必须是600,否则启动失败报Permission denied - mongos 启动时也要加同样TLS参数,否则它和shard之间是明文——这是最常被忽略的一环
- 连接字符串里的多个host必须全部走TLS,例如
"mongodb://node1:27017,node2:27017/?tls=true&tlsCAFile=ca.pem",少写一个地址,那个节点就退化成非加密链路

















