来源:互联网 | 时间:2026-05-10 21:31:11
MongoDB副本集TLS加密配置核心要点为MongoDB副本集配置TLS加密,看似标准流程,实则细节繁多。若关键环节处理不当,排查问题将耗费大量时间。其核心可归结为两点:证书必须“正确”,配置必须“完整”。长期稳定更新的攒劲资源:>>>点
为MongoDB副本集配置TLS加密,看似标准流程,实则细节繁多。若关键环节处理不当,排查问题将耗费大量时间。其核心可归结为两点:证书必须“正确”,配置必须“完整”。

长期稳定更新的攒劲资源: >>>点此立即查看<<<
结论先行:证书需使用OpenSSL生成并包含完整的SAN信息;同时,mongod配置中与net.tls相关的字段缺一不可,否则服务可能静默失败或直接拒绝TLS连接。
副本集环境比单机复杂。一个节点可能拥有多个访问入口,例如正式域名node1.example.com、内网IP192.168.1.10以及本机回环地址127.0.0.1。若证书的“使用者可选名称”未涵盖所有这些地址,客户端连接时将报错SSL peer certificate validation failed。
常见误区在于:诸如mkcert或Let‘s Encrypt自动签发的证书,通常仅包含申请时指定的单一域名,难以覆盖所有IP地址。因此,手动使用OpenSSL生成附带完整SAN扩展的证书是更稳妥的选择。
具体操作关键在于,在生成证书签名请求时,必须显式添加SAN信息。对于OpenSSL 1.1.1及以上版本,可直接使用-addext参数:
openssl req -new -key node1.key -out node1.csr -addext “subjectAltName = DNS:node1.example.com,IP:192.168.1.10,IP:127.0.0.1”
若版本较低或希望更清晰管理,可创建sans.cnf配置文件,并在生成CSR时通过-extfile sans.cnf -extensions req_ext引入。
签发证书时也需谨慎,务必确认证书包含keyUsage = digitalSignature, keyEncipherment及extendedKeyUsage = serverAuth等关键扩展项。生成后,可使用以下命令验证SAN是否生效:
openssl x509 -in node1.pem -text -noout | grep -A1 “Subject Alternative Name”
许多人误以为在配置中写入net.tls.mode: requireTLS即可,但这仅是开启了“开关”。真正使TLS生效的是另外两项关键配置,缺一不可。若遗漏,日志中可能无明确错误,但连接要么被拒绝,要么会悄然降级为不安全通信。
net.tls.certificateKeyFile:此文件须为PEM格式,且内含的私钥不得有密码保护。若私钥被加密,mongod启动时将直接报错Failed to load certificate file: bad password,因其不会在启动时交互式询问密码。net.tls.CAFile:即使仅计划进行服务端认证,也强烈建议填写此字段,指向自建CA的根证书ca.crt。这是因为如mongosh等新版驱动默认会尝试验证服务端证书的颁发者。若未提供CA文件,验证将失败。net.tls.allowConnectionsWithoutCertificates:此参数控制是否允许客户端无证书连接。通常设为true即可。若设为false,则开启强制双向认证,此时副本集内部成员间的通信也会被要求提供客户端证书——除非额外配置了net.tls.clusterFile。此乃常见误区。为所有节点配置requireTLS后,节点间并不会自动使用TLS通信。副本集内部的心跳检测与oplog同步,默认仍使用明文通道。
若未专门为集群内部通信配置TLS,从节点可能持续卡在STARTUP2状态,日志中反复出现no SSL certificate provided或connection refused,而主节点却显示正常。
解决此问题需配置net.tls.clusterFile:
certificateKeyFile,但MongoDB官方建议隔离内部与外部通信证书以提升安全性。600,否则mongod会因权限问题拒绝读取,导致启动失败。clusterFile证书必须由同一CA签发,否则集群内部无法完成相互认证。$external数据库中创建相应用户。服务端配置妥当后,客户端亦需注意。mongosh或各语言驱动不会自动探测服务端是否启用TLS。若使用普通连接字符串,驱动将默认使用TCP连接,结果往往是连接瞬间建立又断开,报错信息模糊。
正确做法是在连接时显式指定TLS参数:
mongosh --tls --tlsCAFile /path/to/ca.crt “mongodb://node1.example.com:27017/replicaSet=rs0”MongoClient(‘mongodb://node1.example.com:27017/’, { tls: true, tlsCAFile: ‘/path/to/ca.crt’ })MongoClient(‘mongodb://node1.example.com:27017/’, tls=True, tlsCAFile=‘/path/to/ca.crt’)需注意版本差异:旧版驱动可能使用ssl=True参数名,新版已统一为tls=True。参数名错误可能导致连接看似成功,但数据仍在明文传输。
最后,一个极易忽视的要点是系统时间。务必确保副本集所有节点系统时间同步,误差最好控制在数秒内,绝对不可超过5分钟。否则,TLS握手时会因证书有效期验证失败而中断,错误信息可能仅为笼统的SSL handshake failed,增加排查难度。