Docker部署MongoDB 7副本集X509认证启动失败排查
问题
在Docker中使用MongoDB 7官方镜像搭建启用TLS集群认证的副本集,完成OpenSSL自签名证书配置后,启动首个副本集节点时抛出以下错误:
{"t":{"$date":"2023-12-13T14:39:18.314Z"},"s":"D1", "c":"ASSERT", "id":23074, "ctx":"main","msg":"User assertion","attr":{"error":"BadValue: need to enable TLS via the sslMode/tlsMode flag when using TLS configuration parameters","file":"src/mongo/util/net/ssl_options_server.cpp","line":228}} {"t":{"$date":"2023-12-13T14:39:18.314Z"},"s":"F", "c":"CONTROL", "id":20574, "ctx":"main","msg":"Error during global initialization","attr":{"error":{"code":2,"codeName":"BadValue","errmsg":"need to enable TLS via the sslMode/tlsMode flag when using TLS configuration parameters"}}}
错误核心提示“使用TLS配置参数时需通过sslMode/tlsMode启用TLS”,但已在mongod.conf中配置了tls模块(尝试过requireTLS、allowTLS、preferTLS等mode值),且在Docker启动命令中添加过--tls或--tlsMode requireTLS参数,均无法解决问题。
当前mongod.conf配置:
storage: dbPath: /var/lib/mongodb systemLog: verbosity: 3 destination: file logAppend: true path: /var/log/mongodb/mongod.log net: tls: clusterAuthX509: attributes: O=TestOrganisation, OU=TestDepartment, CN=MongoDbCluster mode: requireTLS allowInvalidCertificates: true certificateKeyFile: /etc/certs/server.pem CAFile: /etc/certs/server.crt clusterFile: /etc/certs/server.pem bindIp: 0.0.0.0,mongodb-cluster port: 27017 processManagement: timeZoneInfo: /usr/share/zoneinfo replication: replSetName: rs0 security: authorization: enabled clusterAuthMode: x509
证书生成命令:
openssl genrsa -out server.key 4096 openssl req -x509 -new -nodes -sha256 -days 1825 -config ca_req.conf -newkey rsa:4096 -keyout serverROOTCA.key -out server.crt openssl req -new -out server.csr -key server.key -config req_ext.conf -extensions v3_req openssl x509 -req -in server.csr -CA server.crt -CAkey serverROOTKey.key -CAcreateserial -out server.crt -days 730 -sha256 -extfile req_ext.conf -extensions v3_req
req_ext.conf配置:
[CA_default] copy_extensions = copy [req] distinguished_name = client_ca req_extensions = v3_req prompt = no [alt_names] DNS.1 = mongodb-cluster DNS.2 = replace_me_1 DNS.3 = replace_me_2 [client_ca] C = SC ST = SC L = SampleCity O = TestOrganisation OU = TestDepartment CN = MongoDbCluster [v3_req] subjectAltName = @alt_names keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = clientAuth, serverAuth
Docker启动命令:
docker run -d --restart always --name mongodb-cluster \ --network traefik \ -e MONGO_INITDB_ROOT_USERNAME=someuser \ -e MONGO_INITDB_ROOT_PASSWORD=somepassword \ -v $PWD/data:/var/lib/mongodb \ -v $PWD/log/mongod.log:/var/log/mongodb/mongod.log \ -v $PWD/conf/mongod.conf:/etc/mongod.conf \ -v $PWD/certs/server.crt:/etc/certs/server.crt \ -v $PWD/certs/server.pem:/etc/certs/server.pem \ -p SOMEPORT:27017 \ mongo:7 mongod -f /etc/mongod.conf
补充信息:根证书server.crt无相关扩展,server.pem包含Key Usage和Extended Key Usage。请问配置无法正常运行的原因是什么?
问题分析与解决
1. 配置文件格式错误导致TLS配置未被正确解析
mongod.conf中net.tls.clusterAuthX509.attributes的格式不符合MongoDB要求:你使用了字符串格式的属性列表,但MongoDB要求该字段是键值对对象。这个格式错误会导致整个TLS配置块解析失败,MongoDB无法识别已配置的tls.mode,进而触发“未启用TLS”的错误。
修正方法:
将属性配置改为键值对形式:
net: tls: clusterAuthX509: attributes: O: TestOrganisation OU: TestDepartment CN: MongoDbCluster mode: requireTLS # 其余TLS配置保持不变
2. 证书生成流程覆盖了根CA证书
证书生成命令中存在文件覆盖问题:
- 第一步生成根CA证书时,输出文件为
server.crt - 第三步用CSR签名服务器证书时,再次将输出指定为
server.crt,直接覆盖了根CA证书
这导致挂载到容器中的server.crt实际是服务器证书而非根CA证书,而MongoDB的CAFile需要根CA来验证证书链,同时也会干扰TLS配置的正常加载。
修正方法:
修改证书生成命令,区分根CA和服务器证书的文件名:
# 生成根CA私钥和证书 openssl genrsa -out rootCA.key 4096 openssl req -x509 -new -nodes -sha256 -days 1825 -config ca_req.conf -key rootCA.key -out rootCA.crt # 生成服务器私钥和CSR openssl genrsa -out server.key 4096 openssl req -new -out server.csr -key server.key -config req_ext.conf -extensions v3_req # 用根CA签名服务器证书 openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 730 -sha256 -extfile req_ext.conf -extensions v3_req # 合并服务器证书和私钥为pem文件 cat server.crt server.key > server.pem
同时更新mongod.conf中的CAFile路径为/etc/certs/rootCA.crt,并将新的rootCA.crt挂载到容器对应路径。
3. Docker日志挂载方式错误
你直接将本地单个日志文件挂载到容器的/var/log/mongodb/mongod.log,但容器启动时该路径可能是目录,或MongoDB进程无权限写入该文件,会导致日志初始化失败,间接影响服务启动。
修正方法:
改为挂载日志目录:
-v $PWD/log:/var/log/mongodb
4. 验证配置有效性
启动容器前,可通过以下命令检查配置文件是否能被正确解析:
docker run --rm mongo:7 mongod -f /etc/mongod.conf --printConfig
若输出中net.tls.mode显示为requireTLS,则说明配置解析正常。
内容的提问来源于stack exchange,提问作者exa.byte

