Mongodb – Issues with self signed certificates, SSL and MongoDB

mongodbreplicationssl

Note: As specified in my comment I've figured out a solution to this issue regarding a single client/mongo connection. The next step is to figure out a solution for a replica set involving this fix.

So I've been looking into adding SSL into my MongoDB replica set recently and ended up rebuilding Mongo 2.7.8-pre using SCONS. It built fine and I was able to test the newer version of mongo.exe, mongod.exe and mongos.exe with the "allowSSL" mode without generating any certificates.

I was looking around at different tutorials on generating server and client side SSL certs with a root CA and came across this site:
http://acs.lbl.gov/~boverhof/openssl_certs.html

If you don't want to navigate to the page it basically:

  1. Creates a CA
  2. Creates a server key/cert pair
  3. Creates a client key/cert pair

After generating everything I concatenated the keys and certificates into a server.pem and client.pem file because from the docs it seems like Mongo needs both in a .pem file in order for it to work properly.

This left me with:

ca.pem file with the root certificate
server.pem file with the server cert/key (subject – …O = company1, OU = dept1…)
client.pem file with the client cert/key (subject – …O = company1, OU = dept2…)

I was able to restart my services fine using ca.pem and server.pem. However, when I went to connect to the nodes using the client with the following command:

mongo --ssl --sslPEMKeyFile "C:\MongoDB\ssl\client.pem" --sslCAFile "C:\MongoDB\ssl\ca.pem"

It gives me this error:

E NETWORK  SSL peer certificate validation failed:self signed certificate

I've tried to add the client cert to the root CA that I generated because it was suggested that this is my issue but it does not resolve the problem. I tried adding the subject from the client certificate as a new user to the database as suggested for x509 authentication but this also does not resolve the issue.

I would appreciate any help or suggestions as to why my certificates are failing trust because I think at the moment I'm just being road-blocked by a lack of understanding.

Thanks!

Best Answer

The answer to my question comes from an article I found this afternoon and I completely understand what I was doing wrong before. http://demarcsek92.blogspot.com/2014/05/mongodb-ssl-setup.html

I'll explain a little more because of the suggestion from Markus.

Originally I was generating client and server key/certification pairs from a root CA that I had created. I was concatenating (adding) the other certificates that I was making to the root CA and using this as the input for --sslCAFile. The issue I was creating was using my server.pem key/cert for each node and then trying to pass the client.pem file to the server for validation which I found out throws the generic "Self signed certificate" error. Apparently it happens whenever invalid certs/keys are passed to the server to create a connection.

(I'm going to gloss over how to make the server/client key/cert as it is in the article and I would like people to go there for more explanation as it is this gentleman's solution and not my own.)

Create server.key and server.crt
Use "type server.key server.crt > server.pem" (for Windows)

Create client.key and client.crt
Use "type client.key client.crt > client.pem"

For the server the setup will be:
--sslPEMKeyFile = server.pem
--sslCAFile = client.pem

For the client the setup will be:
--sslPEMKeyFile = client.pem
--sslCAFile = server.pem

This solution, as is, works for a single node and single client connection. I was able to trace the line with Wireshark and see that Mongo had stopped identifying itself and that when I drilled down into the packets using the Follow TCP Stream option the only information it was exposing was part of the subject used in creating my certificates (ok behavior).

Find "Client Hello" transmission from Mongo by: Right-clicking on one of tranmission messages > Decode as... > Transport tab > SSL

On the "Client Hello" transmission from Mongo: Right-click the packet > Follow TCP Stream > You should see the packet encrypted

NEXT STEP: My next step is to figure out how to setup SSL certificates for a 3 node replica set. I'm still trying to wrap my head around creating certificates for each node and how they can all be linked so it will allow for each to trust each other and a client connection.

(I'm going to look into the Stack Exchange rules but I was just thinking about chaining to the next topic with a link in this one)