OpenShift中基于pem、cer生成JKS密钥库连接MongoDB报错咨询
问题根因
报错核心原因是Java程序无法验证MongoDB服务端的SSL证书信任链,你的操作存在两处核心错误:
- 直接将PKCS12格式文件冒充JKS格式使用:虽然JDK 8+支持PKCS12作为密钥库格式,但你未正确配置证书内容,且未设置匹配的密钥库密码,Java无法正常读取
- *混淆了keystore和truststore的作用:keystore用于存储客户端身份证书(仅MongoDB开启双向SSL认证时需要),truststore用于存储你信任的服务端CA根证书,你当前的truststore中未导入MongoDB的根证书,Java校验服务端证书时找不到信任链直接抛出异常
正确操作步骤
步骤1:生成合法keystore(仅双向SSL认证需要,单向认证可跳过)
如果你的MongoDB要求客户端提交身份证书,执行以下命令将server.pem导出为标准JKS格式的keystore,导出过程中按提示设置密钥库密码,注意记录后续要用到:
# 先将客户端证书+私钥导出为PKCS12格式 openssl pkcs12 -export -in C:\server.pem -out C:\client.p12 -name "mongodb-client" -CAfile C:\certificate.cer -caname "mongodb-ca" # 再转换为JKS格式,兼容性更强 keytool -importkeystore -srckeystore C:\client.p12 -srcstoretype pkcs12 -destkeystore C:\keystore.jks -deststoretype jks
步骤2:生成合法truststore(单向/双向认证都必须执行)
将你手里的certificate.cer(MongoDB服务端CA根证书)导入到truststore中,让Java程序信任该证书:
keytool -import -file C:\certificate.cer -alias "mongodb-ca" -keystore C:\truststore.jks
执行过程中输入自定义的truststore密码,提示是否信任证书时输入yes回车确认。
步骤3:在OpenShift中创建Secret
oc create secret generic mongodb-ssl-secret --from-file=keystore.jks=C:\keystore.jks --from-file=truststore.jks=C:\truststore.jks
步骤4:配置Deployment挂载Secret并传入Java参数
- 在Deployment配置中新增volume挂载,将secret挂载到容器内的固定路径,比如
/opt/ssl,设置挂载权限为0644保证Java进程可读 - 给Java程序传入SSL系统参数,可配置在JAVA_OPTS环境变量中:
# 必选参数 -Djavax.net.ssl.trustStore=/opt/ssl/truststore.jks -Djavax.net.ssl.trustStorePassword=你设置的truststore密码 # 双向认证额外加以下两个参数 -Djavax.net.ssl.keyStore=/opt/ssl/keystore.jks -Djavax.net.ssl.keyStorePassword=你设置的keystore密码
- 检查MongoDB连接字符串,必须加上
ssl=true参数,示例:mongodb://账号:密码@mongodb服务地址:27017/数据库名?ssl=true
如果测试环境MongoDB证书域名和访问地址不匹配,可临时加参数&sslInvalidHostNameAllowed=true绕过校验,生产环境建议修正证书
快速排查验证方法
- 本地校验keystore/truststore内容是否正确:
keytool -list -keystore 密钥库文件路径 -v,确认truststore中存在别名为mongodb-ca的证书条目,keystore中存在客户端证书条目 - 容器启动后exec进入容器,检查
/opt/ssl路径下的密钥库文件是否存在、大小是否正常
内容的提问来源于stack exchange,提问作者Rose
相关产品推荐
相关产品推荐

