使用mongo-java-driver使用x509证书对MongoDB v2.6进行身份验证时遇到问题

时间:2014-04-10 17:56:55

标签: java mongodb ssl groovy x509

我很难使用x509证书连接到mongo v2.6,以便从Java / Groovy进行身份验证。我用ssl构建了mongo并觉得我已经正确配置了它。

我们的项目有两个连接到Mongo的应用程序 - 一个用NodeJS编写,另一个用Java / Groovy编写。 NodeJS项目成功地使用X509证书和查询进行身份验证。另外,我可以通过指定ssl并在命令行上提供PEM文件来shell到mongo。但是,我无法使用Java Mongo驱动程序连接到mongo。我非常感谢一些帮助,这是我迄今采取的步骤:

使用SCONS构建MongoDB 2.6以使用ssl运行:

我从mongodb github页面下载了2.6版本的MongoDB

然后,使用scons构建它以包含ssl

scons --64 --dd --ssl all
scons --ssl --prefix=/opt/mongo  install

为Mongo ::

生成密钥

我生成了以下密钥/证书

openssl req -new -newkey rsa:1024 -nodes -out myMongo.req -keyout myMongo.key -subj "/C=US/ST=myState/CN=myMongo/OU=myUnit/L=myLocation" -days 36500
openssl x509 -CA myCA.pem -CAkey myCa.key -CAserial myCa.srl -req -in myMongo.req -out myMongo.pem -days 36500

这给了我以下文件:

  • myMongo.key(包含私钥)
  • myMongo.pem(包含证书)
  • myMongo.req(包含证书请求)(我不确定我是否需要这个,但尚未使用它)

根据mongo指令,我将密钥和证书连接成1个文件

cat myMongo.key myMongo.pem > combined.pem

遵循x509配置的mongo说明: http://docs.mongodb.org/manual/tutorial/configure-x509/

openssl x509 -in combined.pem -inform PEM -subject -nameopt RFC2253

给我的主题是:“C = US,ST = myState,CN = myMongo,OU = myUnit,L = myLocation” 然后我将该主题添加到数据库中的用户

db.getSiblingDB("$external").runCommand(
  {
    createUser: "C=US,ST=myState,CN=myMongo,OU=myUnit,L=myLocation",
    roles: [
             { role: 'readWrite', db: 'mydbName' },
             { role: 'userAdminAnyDatabase', db: 'admin' }
           ],
    writeConcern: { w: "majority" , wtimeout: 5000 }
  }
)

在我的mongod.conf文件中,我指定了以下选项:

sslMode = requireSSL
sslPEMKeyFile = /path/to/my/combined.pem
sslCAFile = /path/to/myCA.pem

此时,我可以启动

mongod --config /path/to/my/mongod.conf

启动后,我只能通过指定

来访问shell
mongo --ssl -- sslPEMKeyFile /path/to/my/combined.pem

从Java-Mongo-Driver版本2.12.0连接到MongoDB

我正在尝试按照java-mongo-driver github页面上给出的示例:

https://github.com/mongodb/mongo-java-driver/blob/master/src/examples/example/X509CredentialsExample.java

代码失败,我们将在下面提供一个例外,但是你会尝试通过仅以字符串格式提供DN而不是实际将证书附加到请求来尝试连接,这似乎很奇怪。难道这不能打破X509的全部目的吗?我们查看了Ruby示例并附加了一个pem文件。我的团队了解java密钥库和信任库,如果这就是我们应该做的事情,我会很高兴地发送pem文件。此外,在使用节点驱动程序时,我们绝对指定了PEM文件的位置。

最终结果是这样的。我们可以很好地实例化MongoClient,甚至可以使用db对象获取集合。当我们尝试以任何方式查询任何集合时,我们返回一个异常,其消息是“无法连接到任何服务器。”

MongoClientOptions.Builder允许我们添加这些信息似乎是合乎逻辑的,因为它似乎是在其他地方完成的。但是我们对这个类进行了反省,以防它在文档中丢失,并且就我们所知,那里没有任何与x509有关的内容。

感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

在您链接的示例中,请注意它只使用SSLSocketFactory.getDefault(),它依赖于JDK定义的系统属性来指定密钥库和信任库,例如

  • javax.net.ssl.keyStoreType = pkcs12
  • javax.net.ssl.keyStore = /路径/到/ PKC
  • javax.net.ssl.keyStorePassword =
  • javax.net.ssl.trustStoreType = JKS
  • javax.net.ssl.trustStore中= /路径/到/信任
  • javax.net.ssl.trustStorePassword中=

您必须将您的客户端证书添加到密钥库,并将MongoDB服务器的签名授权证书添加到信任库。