我很难使用x509证书连接到mongo v2.6,以便从Java / Groovy进行身份验证.我用ssl构建了mongo并觉得我已经正确配置了它.
我们的项目有两个连接到Mongo的应用程序 – 一个用NodeJS编写,另一个用Java / Groovy编写. NodeJS项目成功地使用X509证书和查询进行身份验证.另外,我可以通过指定ssl并在命令行上提供PEM文件来shell到mongo.但是,我无法使用Java Mongo驱动程序连接到mongo.我非常感谢一些帮助,以下是我迄今采取的步骤:
构建MongoDB 2.6以使用SCONS与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页面上给出的示例:
代码失败,我们将在下面提供一个例外,但是你会尝试通过仅以字符串格式提供DN而不是实际将证书附加到请求来尝试连接,这似乎很奇怪.难道这不能打破X509的全部目的吗?我们查看了Ruby示例并附加了一个pem文件.我的团队了解java密钥库和信任库,如果这就是我们应该做的事情,我会很高兴地发送pem文件.此外,在使用节点驱动程序时,我们绝对指定PEM文件的位置.
最终结果是这样的.我们可以很好地实例化MongoClient,甚至可以使用db对象获取集合.当我们尝试以任何方式查询任何集合时,我们返回一个异常,其消息是“无法连接到任何服务器”.
似乎合乎逻辑的是MongoClientOptions.Builder允许我们添加这些信息,因为它似乎是在其他地方完成的.但是我们对该类进行了反省,以防万一文档中缺少它,并且就我们所知,那里没有任何与x509相关的内容.
我感谢您的帮助.
解决方法:
在您链接到的示例中,请注意它只是使用SSLSocketFactory.getDefault(),它依赖于JDK定义的系统属性来指定密钥库和信任库,例如
> javax.net.ssl.keyStoreType = pkcs12
> javax.net.ssl.keyStore = / path / to / pkc
> javax.net.ssl.keyStorePassword =
> javax.net.ssl.trustStoreType = jks
> javax.net.ssl.trustStore = / path / to / truststore
> javax.net.ssl.trustStorePassword =
您必须将客户端证书添加到密钥库,并将MongoDB服务器的签名机构证书添加到信任库.