Skip to main content

Setting up SSL in MongoDB

Prerequisites:

  1. Mac or Linux operating system

  2. MongoDB database node (mongod binary) version 4.0 or higher

  3. openssl utility installed in the MongoDB host and available in the path

  4. JRE installed and the path variables properly set

Example configuration files for setting up SSL in MongoDB

The following example configuration files make setting up the certificates easier by having many of the certificate attribute values prepopulated for Certificate Authority (CA), MongoDB server, and MongoDB client. Change the values of the attributes to reflect your MongoDB environment. The configuration files must differ by at least one attribute value of the SSL certificate like Common Name, Organization Name, etc.

For certificate authority (openssl-test-ca.cnf):

# NOT FOR PRODUCTION USE. OpenSSL configuration file for testing.

# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
default_bits = 4096
default_keyfile = myTestCertificateKey.pem    ## The default private key file name.
default_md = sha256                           ## Use SHA-256 for Signatures
distinguished_name = req_dn
req_extensions = v3_req
x509_extensions = v3_ca # The extentions to add to the self signed cert

[ v3_req ]
subjectKeyIdentifier  = hash
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate for TESTING only.  NOT FOR PRODUCTION USE."
extendedKeyUsage  = serverAuth, clientAuth

[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default = IN
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = KA
stateOrProvinceName_max = 64

localityName = Locality Name (eg, city)
localityName_default = BLR
localityName_max = 64

organizationName = Organization Name (eg, company)
organizationName_default = STRIIM
organizationName_max = 64

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = ADAPTERS
organizationalUnitName_max = 64

commonName = CA
commonName_max = 64

[ v3_ca ]
# Extensions for a typical CA

subjectKeyIdentifier=hash
basicConstraints = critical,CA:true
authorityKeyIdentifier=keyid:always,issuer:always

For server (openssl-test-server.cnf):

# NOT FOR PRODUCTION USE. OpenSSL configuration file for testing.

[ req ]
default_bits = 4096
default_keyfile = myTestClientCertificateKey.pem    ## The default private key file name.
default_md = sha256
distinguished_name = req_dn
req_extensions = v3_req


[ v3_req ]
subjectKeyIdentifier  = hash
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate for TESTING only.  NOT FOR PRODUCTION USE."
extendedKeyUsage  = serverAuth, clientAuth


[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default = IN
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = KA
stateOrProvinceName_max = 64

localityName = Locality Name (eg, city)
localityName_default = BLR
localityName_max = 64

organizationName = Organization Name (eg, company)
organizationName_default = STRIIM
organizationName_max = 64

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = MONGO
organizationalUnitName_max = 64
commonName = AJAY
commonName_max = 64

For client (openssl-test-client.cnf):

# NOT FOR PRODUCTION USE. OpenSSL configuration file for testing.

[ req ]
default_bits = 4096
default_keyfile = myTestServerCertificateKey.pem    ## The default private key file name.
default_md = sha256
distinguished_name = req_dn
req_extensions = v3_req

[ v3_req ]
subjectKeyIdentifier  = hash
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate for TESTING only.  NOT FOR PRODUCTION USE."
extendedKeyUsage  = serverAuth, clientAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = localhost
DNS.2 = dockerhost
IP.1 = 127.0.0.1
IP.2 = ::1

[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default = IN
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = KA
stateOrProvinceName_max = 64

localityName = Locality Name (eg, city)
localityName_default = BLR
localityName_max = 64

organizationName = Organization Name (eg, company)
organizationName_default = STRIIM
organizationName_max = 64

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = NOSQL
organizationalUnitName_max = 64

commonName = MONGOSERVER
commonName_max = 64

Setting up the Certificate Authority (CA)

The following openssl commands create a private key for the CA and then create a x509 certificate using the key.

openssl genrsa -out mongodb-test-ca.key 4096
openssl req -new -x509 -days 1826 -nodes -key mongodb-test-ca.key -out test-ca.pem -config openssl-test-ca.cnf 

Creating server certificate(s)

For a single server, perform the following operations using openssl commands:

  1. Create a key for the server.

  2. Create a certificate signing request using the key and the certificate values to be signed by the CA.

  3. Use the CA’s certificate and key to sign the signing request. This operation will create a certificate for the server.

  4. Create the server pem file with its certificate and key.

openssl genrsa -out mongodb-test-server.key 4096
openssl req -new -key mongodb-test-server.key -out mongodb-test-server.csr
  -config openssl-test-server.cnf
openssl x509 -sha256 -req -days 365 -in mongodb-test-server.csr -CA test-ca.pem
  -CAkey mongodb-test-ca.key -CAcreateserial -out mongodb-test-server.crt 
  -extfile openssl-test-server.cnf -extensions v3_req
cat mongodb-test-server.crt mongodb-test-server.key > test-server.pem

For multiple servers:

  1. If there are multiple MongoDB nodes, in case of a replica set, each node must have its own certificate.

  2. If there are n nodes, then create n copies of openssl-test-server.cnf file. For simplicity, name them as openssl-test-server<n>.cnf with <n> denoting the chronological number of the server node.

  3. Rename at least one attribute (like Organization Name and Common Name) each of these files so that they are unique.

  4. Perform the following commands n times, once for each MongoDB instance.

openssl genrsa -out mongodb-test-server<n>.key 4096
openssl req -new -key mongodb-test-server<n>.key -out mongodb-test-server<n>.csr
  -config openssl-test-server<n>.cnf
openssl x509 -sha256 -req -days 365 -in mongodb-test-server<n>.csr -CA test-ca.pem
  -CAkey mongodb-test-ca.key -CAcreateserial -out mongodb-test-server<n>.crt 
  -extfile openssl-test-server<n>.cnf -extensions v3_req
cat mongodb-test-server<n>.crt mongodb-test-server<n>.key > test-server<n>.pem

Create a client certificate

Perform the following operations using openssl commands

  1. Create a key for the client

  2. Create a certificate signing request using the key and the certificate values to be signed by the CA.

  3. Use the CA’s certificate and key to sign the signing request. This operation will create a certificate for the server.

  4. Create the client pem file with its certificate and key.

openssl genrsa -out mongodb-test-client.key 4096
openssl req -new -key mongodb-test-client.key -out mongodb-test-client.csr
  -config openssl-test-client.cnf
openssl x509 -sha256 -req -days 365 -in mongodb-test-client.csr -CA test-ca.pem
  -CAkey mongodb-test-ca.key -CAcreateserial -out mongodb-test-client.crt
  -extfile openssl-test-client.cnf -extensions v3_req
cat mongodb-test-client.crt mongodb-test-client.key > test-client.pem

Move the certificate files

  1. Create a directory inside the MongoDB installation directory of each server node to place the certificate files.

    cd mongodb-macos-x86_64-4.4.14
    mkdir ssl
  2. Copy the CA .pem file and server-specific .pem files from the current directory to under a directory the MongoDB installation directory.

    cp test-ca.pem ~/mongodb-macos-x86_64-4.4.14/ssl/ca.pem
    cp test-servern.pem ~/mongodb-macos-x86_64-4.4.14/ssl/server<n>.pem

Starting MongoDB with SSL

The certificates of the server and CA are required to start the mongod process. Change to the MongDB program directory and enter the following command:

./bin/mongod --dbpath ~/data/db --sslCAFile ssl/ca.pem
  --sslPEMKeyFile ssl/server.pem --sslMode requireSSL 
  --sslDisabledProtocols "TLS1_0,TLS1_1" 
  --sslAllowConnectionsWithoutCertificates --sslAllowInvalidHostname

Change the protocol version and other parameters as required. More on parameters can be found at- Docs Home / Management / Security / Network & Configuration Hardening / TLS/SSL / Configure MongoDB Instances for TLS/SSL on Self-Managed Deployments..

  • Connecting from Mongo shell The following command can be used to connect from a Mongo shell using ssl.

To connect from a Mongo shell using SSL:

./bin/mongo --ssl --sslPEMKeyFile ssl/client.pem --sslCAFile ssl/ca.pem

Ideally the pem file of the client or server should be presented while running Mongo shell, but if the server was started with sslAllowConnectionsWithoutCertificates parameter, the handshake will work even if sslPEMKeyFile is not provided.