ScaleGrid supports SSL configuration for MongoDB and can be easily set up, as outlined in our MongoDB SSL post. It also discusses MongoDB’s needs, pros, and cons with TLS/SSL.
ScaleGrid currently uses self-signed certificates for SSL when creating nodes for a new cluster. Since Node.js applications over the MongoDB Node.js driver or Mongoose are very popular choices on our platform, we created this post to share a step-by-step workaround plan for the most commonly faced issues in using MongoDB SSL with self-signed certificates in Node.js. This discussion pertains to the MongoDB Node.js version 2.0 and Mongoose version 4.0.3.
At ScaleGrid, we also provide the option of purchasing your SSL certificates and configuring them on the MongoDB server. Please email support@scalegrid.io to learn more about this opportunity.
Adding CA Certificate File
To improve the security of your SSL connection, you can specify the CA to validate the MongoDB server SSL certificate. Node.js has a default list of well-known “root” CAs it consults if a CA is not specified during the connection creation time. However, since we’re talking about self-signed certificates, we must specify a CA certificate file for verification. You may copy the CA certificate file that was used for self-signing into the client machine and then use the sslCA
option to point to the path of this file, thus enabling server verification as well.
Mongoose
For Standalone Clusters:
var fs = require('fs'); var mongoose = require('mongoose'); var certFileBuf = fs.readFileSync(<path to CA cert file>); var mongoUrl = 'mongodb://admin:blahblah@test0.servers.example.com:27017/admin?ssl=true'; var options = { server: { sslCA: certFileBuf } }; mongoose.connect(mongoUrl, options); ...
For Replica Set Clusters:
var fs = require('fs'); var mongoose = require('mongoose'); var certFileBuf = fs.readFileSync(<path to CA cert file>); var mongoUrl = 'mongodb://admin:blahblah@test0.servers.example.com:27017,test1.servers.example.com.com:27017/admin?replicaSet=RS-rstestNode-0&ssl=true'; var options = { replset: { sslCA: certFileBuf } } mongoose.connect(mongoUrl, options); ...
MongoDB Native Driver (and wrappers around it, like Mongoskin)
For Standalone Clusters:
var certFileBuf = fs.readFileSync(<path to CA cert file>); var mongoUrl = 'mongodb://admin:blahblah@test0.servers.example.com:27017/admin?ssl=true'; var options = { server: { sslCA: certFileBuf} }; var MongoClient = require('mongodb').MongoClient , assert = require('assert'); MongoClient.connect(mongoUrl, options, function(err, db) { assert.equal(null, err); console.log("Connected correctly to server"); db.close(); });
For Replica Set Clusters:
The option parameter for replica sets is replSet:
var options = { replSet: { sslCA: certFileBuf } }; var MongoClient = require('mongodb').MongoClient , assert = require('assert'); MongoClient.connect(mongoUrl, options, function(err, db) { assert.equal(null, err); console.log("Connected correctly to server"); db.close(); });
Disabling SSL Certificate Verification
You can disable SSL Certificate Verification altogether as well. This is perhaps easiest to do and most certain to work for you; however, it’s not the recommended way to go. The MongoDB driver provides server-level and replica set-level SSL options (sslValidate
, sslCA
, sslCert
, sslKey
, sslPass
) to configure SSL connections. All the options are described in detail in the documentation.
In the case of self-signed certificates, the most useful option is the sslValidate
. This can be set to
false
in case of errors like: DEPTH_ZERO_SELF_SIGNED_CERT
(self-signed certificate). This disables SSL certificate verification, but the connection still remains encrypted.
Mongoose lets you pass parameters down to the driver in its connect call. For example:
Replica Set Clusters:
sslValidate
needs to be set to false
at the ReplicaSet option so:
var mongoose = require('mongoose'); var mongoUrl = 'mongodb://admin:blahblah@test0.servers.example.com:27017,test1.servers.example.com.com:27017/admin?replicaSet=RS-rstestNode-0&ssl=true'; var options = { replset: {sslValidate: false} } mongoose.connect(mongoUrl, options); ...
For MongoDB Native Driver:
var options = { replSet: { sslValidate: false } }; var MongoClient = require('mongodb').MongoClient , assert = require('assert'); MongoClient.connect(mongoUrl, options, function(err, db) { assert.equal(null, err); console.log("Connected correctly to server"); db.close(); });
Disabling Hostname Verification
Instead of completely disabling SSL validation, one can disable hostname verification if hostnames are a problem.
Hostname verification is currently configurable as part of the CA certificate verification. It’s always recommended that this verification be turned on.
However, it might lead to verification failures even if there’s the slightest mismatch in the hostname, as in the CA certificate versus the client attempting to connect. Thus, most TLS/SSL servers provide a way to turn it off. For example. the Java MongoDB driver 3.0 allows a way to disable hostname verification via the sslInvalidHostNameAllowed
property.
For MongoDB Native Driver 2.0 and above, a boolean option parameter checkServerIdentity (default true) is provided to disable hostname verification. It’s available both at the individual server and replica set levels.
Read Also:
Setting Up MongoDB SSL Encryption
MongoDB® SSL with Self-Signed Certificates in C#
MongoDB Rollback: How to Minimize Data Loss