Setting up SSL in MongoDB
Prerequisites:
Mac or Linux operating system
MongoDB database node (mongod binary) version 4.0 or higher
openssl utility installed in the MongoDB host and available in the path
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:
Create a key for the server.
Create a certificate signing request using the key and the certificate values to be signed by the CA.
Use the CA’s certificate and key to sign the signing request. This operation will create a certificate for the server.
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:
If there are multiple MongoDB nodes, in case of a replica set, each node must have its own certificate.
If there are n nodes, then create n copies of
openssl-test-server.cnffile. For simplicity, name them asopenssl-test-server<n>.cnfwith<n>denoting the chronological number of the server node.Rename at least one attribute (like Organization Name and Common Name) each of these files so that they are unique.
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
Create a key for the client
Create a certificate signing request using the key and the certificate values to be signed by the CA.
Use the CA’s certificate and key to sign the signing request. This operation will create a certificate for the server.
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
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
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.