Can't connect from JAVA to Mongo SSL Replica Set

4.4k views Asked by At

I'm trying to set up last version of MongoDB with SSL encryption, I was able to connect from mongo shell but I'm getting an error when I connect from a Java Client.

Works

mongo admin --host mongo1.xxxx.com --ssl --sslPEMKeyFile mongoClient.pem --sslCAFile mongoCA.crt

Doesn't work

public static void main(String args[]){
    System.setProperty("javax.net.ssl.trustStore","/home/gasparms/truststore.ts");
    System.setProperty("javax.net.ssl.trustStorePassword", "mypasswd");

    System.setProperty("javax.net.ssl.keyStore", "/home/gasparms/truststore.ts");
    System.setProperty("javax.net.ssl.keyStorePassword", "mypasswd");
    System.setProperty("javax.security.auth.useSubjectCredsOnly","false");

    MongoClientOptions options = MongoClientOptions.builder().sslEnabled(true)
    .build();

    MongoClient mongoClient = new MongoClient("mongo1.xxxx.com",options);
    System.out.println(mongoClient.getDatabaseNames());
}

I get this error from Mongo side:

2015-06-09T15:08:14.431Z I NETWORK [initandlisten] connection accepted from 192.168.33.1:38944 #585 (3 connections now open) 2015-06-09T15:08:14.445Z E NETWORK [conn585] no SSL certificate provided by peer; connection rejected 2015-06-09T15:08:14.445Z I NETWORK [conn585] end connection 192.168.33.1:38944 (2 connections now open) 2015-06-09T15:08:14.828Z I NETWORK [conn580] end connection 192.168.33.13:39240 (1 connection now open)

and in java client program

INFORMACIÓN: Exception in monitor thread while connecting to server mongo1.xxxx.com:27017 com.mongodb.MongoSocketReadException: Prematurely reached end of stream at com.mongodb.connection.SocketStream.read(SocketStream.java:88) at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:491) at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:221) at com.mongodb.connection.CommandHelper.receiveReply(CommandHelper.java:134) at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:121) at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32) at com.mongodb.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:83) at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:43) at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115) at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127) at java.lang.Thread.run(Thread.java:745)

Creation of Certificates

I have mongoCA.crt and mongoClient.pem that works with mongo shell. Then, I want to import .pem and .crt to a java keystore

openssl x509 -outform der -in certificate.pem -out certificate.der
keytool -import -alias MongoDB-Client -file certificate.der -keystore truststore.ts -noprompt -storepass "mypasswd"
keytool -import -alias "MongoDB-CA" -file mongoCA.crt -keystore truststore.ts -noprompt -storepass "mypasswd"

What I'm doing wrong?

1

There are 1 answers

0
Ed Tyrrill On

I had the same problem, and for me it turned out to be a problem with the way I created the keystore. I notice that you are using the same file, truststore.ts, for both the truststore and keystore. This can work, but I would suggest using separate files to avoid confusion.

I had already created .pem files for the root CA and for the mongo user, and was able to successfully use them to connect with the mongo shell. From those I created truststore.jks and keystore.jks.

First, to create truststore.jks I ran:

keytool -import -alias root -storepass mypass -keystore truststore.jks -file rootca.pem -noprompt

For keystore.jks you need both the public and private keys so first convert the PEM file to PKCS12 format, and then import to a JKS:

openssl pkcs12 -export -out myuser.pkcs12 -in myuser.pem -password pass:mypass
keytool -importkeystore -srckeystore myuser.pkcs12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS -deststorepass mypass -srcstorepass mypass