[DOCS-4436] Add a section to the docs showing how to create a keystore Created: 27/Nov/14  Updated: 30/Oct/23  Resolved: 27/Dec/18

Status: Closed
Project: Documentation
Component/s: manual
Affects Version/s: None
Fix Version/s: Server_Docs_20231030

Type: Improvement Priority: Minor - P4
Reporter: James O'Leary Assignee: Ravind Kumar (Inactive)
Resolution: Done Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to DOCS-10488 SSL/TLS x.509 certificate creation gu... Closed
Participants:
Days since reply: 5 years, 6 weeks, 6 days ago
Story Points: 2.5

 Description   

We should update the documentation to include a section on generating a PEM file and adding it to a keystore in the enterprise section of the documentation



 Comments   
Comment by Ravind Kumar (Inactive) [ 27/Dec/18 ]

The new Appendix section should sufficiently cover this request.

Comment by Ricardo Lorenzo [ 28/Nov/14 ]
1) Generate a X.509 CA cert and key

$ openssl genrsa -out mongodb-ca.key 4096
$ openssl req -new -x509 -days 1826 -key mongodb-ca.key -out mongodb-ca.crt

Optionally you can create a subordinate CA to sign the server certificates if you don't want to use the root CA certificate.

$ openssl genrsa -out mongodb-ia.key 4096
$ openssl req -new -key mongodb-ia.key -out mongodb-ia.csr
$ openssl x509 -req -days 730 -in ia.csr -CA mongodb-ca.crt -CAkey mongodb-ca.key -set_serial 01 -out mongodb-ia.crt

2) Create a PEM from the cert and key for mongo server

$ openssl genrsa -out mongodb-server1.key 4096
$ openssl req -new -key mongodb-server1.key -out mongodb-server1.csr

Then you can sign the server certificate request using your CA.

$ openssl x509 -req -days 365 -in mongodb-server1.csr -CA mongodb-ia.crt -CAkey mongodb-ia.key -CAcreateserial -out mongodb-server1.crt

Now you must add the certificate and the key (PEM format) into a single file:

$ cat mongodb-server1.key mongodb-server1.crt > /PATH/TO/mongodb-server-1.pem

3a) Verify and test your server certificate

$ openssl verify -verbose -CAfile mongodb-ca.crt  mongodb-server1.crt

Note: You will have to do steps 2) and 3a) for each server.
Note: The CN (Common Name) should match the hostname used to connect to each server to be in compliance with RFC6125. Wildcard certificates have specific matching rules that you need to consider.
Note: If you need to generate many keys, you should consider creating an OpenSSL conf file and using -config mongodb-ssl.cnf.

3b) Ensure that mongod has been started in SSL mode

For Example:

$ mongod --sslMode [requireSSL|allowSSL|preferSSL] --sslPEMKeyFile /PATH/TO/mongodb-server1.crt

4) Test that the mongodb shell can access the server in SSL mode

$ mongo --ssl
MongoDB shell version: 2.6.5
connecting to: test
>
bye
$ mongo
MongoDB shell version: 2.6.5
connecting to: test
2014-11-27T22:02:07.554+0900 DBClientCursor::init call() failed
2014-11-27T22:02:07.558+0900 Error: DBClientBase::findN: transport error: 127.0.0.1:27017 ns: admin.$cmd query: { whatsmyuri: 1 } at src/mongo/shell/mongo.js:146
exception: connect failed

Note: Depending on the SSL mode selected, you cannot connect if you do not use --ssl with the mongo shell.

5) Generate a Java™ key store (JKS) file using the JDK keytool program

$ keytool -importcert -file /PATH/TO/mongodb-ca.crt -storepass PASSWORD -alias server.mongodb.com -keystore /PATH/TO/mongodb.keystore

Note: /PATH/TO for the cert and the keystore may be different, you can decide where they go.
Note: Use whatever value you wish for PASSWORD, you will need it in the next step.

6) Start JVM with required System Properties for SSL

java -cp .:mongo-java-driver-2.12.4.jar  \ 
-Djavax.net.ssl.trustStore=/PATH/TO/mongodb.keystore \
-Djavax.net.ssl.keyStore=/PATH/TO/mongodb.keystore\
-Djavax.net.ssl.keyStorePassword=PASSWORD \
-Djavax.net.ssl.trustStorePassword=PASSWORD JavaProgramThatUsesMongoDriver HOSTNAME

Note: HOSTNAME should match the CN (Common Name) as described in point (3b.
Note: HOSTNAME should probably be the FQDN for the host.
Note: this approach will leave the USERNAME/ PASSWORD visible through ps | /proc/pid/cmdline. In a real system, you should load these properties in a way that does not leak this information to the system

Test the keys and connectivity with the following simple java class

JavaProgramThatUsesMongoDriver.java

import com.mongodb.*;
 
import java.util.List;
import java.util.Set;
 
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
 
import static java.util.concurrent.TimeUnit.SECONDS;
 
class JavaProgramThatUsesMongoDriver{
    public static void main(String [] args)
    {
        try {
            String cname;
            if(args.length < 1) {
                System.out.println("Please provide a hostname");
                return;
            } else {
                cname = args[0];
            }
            MongoClientOptions o = new MongoClientOptions.Builder()
                .socketFactory(SSLSocketFactory.getDefault())
                .build();
 
            System.out.println("attempting to connect to " + cname);
            MongoClient mc = new MongoClient(cname, o);
            DB db = mc.getDB( "mydb" );
            DBCollection coll = db.getCollection("testCollection");
            BasicDBObject doc = new BasicDBObject("name", "MongoDB")
                .append("type", "database")
                .append("count", 1)
                .append("info", new BasicDBObject("x", 203).append("y", 102));
            coll.insert(doc);
             
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

Generated at Thu Feb 08 07:47:59 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.