Step 1: Get MongoDB 3.0
The first thing you need to know is that SSL is only supported with MongoDB 3.0 and later. Ubuntu does not have 3.0 in the default repositories, so here is how you get it:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list sudo apt-get update sudo apt-get install -y mongodb-org=3.0.7 mongodb-org-server=3.0.7 mongodb-org-shell=3.0.7 mongodb-org-mongos=3.0.7 mongodb-org-tools=3.0.7
3.0.7 is the latest stable version at the moment, but feel free to substitute 3.0.7 with your favorite release.
Step 2: Obtain the private key, certificate and PEM files.
PEM contains a public key certificate and its associated private key. These files can be obtained using IRL dollars from the Authroity certificate or generated using OpenSSL, for example:
openssl req -newkey rsa:2048 -new -x509 -days 3650 -nodes -out mongodb-cert.crt -keyout mongodb-cert.key cat mongodb-cert.key mongodb-cert.crt > mongodb.pem
mongodb.pem will be used as the PEM file, mongodb-cert.key will be the private key file, and mongodb-cert.crt will be the certificate file, which can also be used as the CA file. YOU NEED ALL THREE THESE.
Step 3: Configure MongoD
We will assume that you have copied these files to your / etc / ssl / folder where they belong. Now we open our MongoDB configuration file:
sudo vi /etc/mongod.conf
and change the "# network interfaces" section as follows:
# network interfaces net: port: 27017
PLEASE NOTE: we are commenting on bindIp. THIS ALLOWS EXTERNAL CONNECTIONS to access your Mongo database. We assume that this is your ultimate goal (why should you encrypt traffic on localhost?), But you should only do it AFTER SET AUTHORIZATION RULES for your MongoDB server.
CAFile is also commented out as it is optional. I will explain how to set up certification authority trust at the end of this post.
As always, you must reload MongoDB before the configuration file changes take effect:
sudo service mongod restart
SHOULD YOU MAKE YOUR SERVER? You are on your own, but there is probably a problem with your certificate files. You can check startup errors manually by doing mongod manually:
sudo mongod --config /etc/mongod.conf
Step 4: Check Server Settings
Before moving on to Node settings, make sure that the server setup works correctly by connecting to the mongo command-line client:
mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates
If the domain name of your certificate is not 127.0.0.1 or localhost, you must specify the -sslAllowInvalidHostnames flag. Without this, you will probably get this error:
E NETWORK The server certificate does not match the host name 127.0.0.1 E QUERY Error: socket exception [CONNECT_ERROR] for at connect (src/mongo/shell/mongo.js:179:14) at (connect):1:6 at src/mongo/shell/mongo.js:179 exception: connect failed
Step 5) Configure Node.JS / Mongoose
If you are using the node-mongodb-native package in your Node application, stop immediately and start using Mongoose. It is not that difficult. However, mongoose.connect () has almost the same API as mongodb.connect (), so replace it accordingly.
var fs = require('fs') , mongoose = require('mongoose') , mongoUri = "mongodb://127.0.0.1:27017?ssl=true" , mongoOpt = { "server": { "sslValidate": false, "sslKey": fs.readFileSync('/etc/ssl/mongodb.pem'), "sslCert": fs.readFileSync('/etc/ssl/mongodb-cert.crt') } } ; mongoose.connect(mongoUri, mongoOpt);
Step 6) [Optional] Verify your certificates through a Certificate Authority
To verify your SSL certificates, you need to obtain a CA file (or package) from your certificate authority. This will be very similar to your certificate file, but will often contain several certificates (in what form you need to trust to make sure the certificate is valid). If you use a self-signed certificate, you can use your mongodb-cert.crt file as a CA file.
You also need to make sure that the host name of the MongoDB server matches the name used to create the certificate.
Step 6.3) Update mongod configuration
sudo vi /etc/mongod.conf
and change the "# network interfaces" section as follows:
# network interfaces net: port: 27017
Step 6.4) Check server settings
mongo --ssl --sslAllowInvalidHostnames --sslCAFile /etc/ssl/mongodb-ca.crt --sslPEMKeyFile /etc/ssl/mongodb.pem
Mongo Clients can also go through the CA file to make sure they are talking to the correct server. This is done with the -sslCAFile option
Mongo Servers configured with CAFile require that clients have a valid certificate and private key for the server. In the mongo shell client, this is done by passing in the -sslPEMKeyFile parameter.
Without the PEM file (which contains the server certificate) you can see this error:
I NETWORK DBClientCursor::init call() failed E QUERY Error: DBClientBase::findN: transport error: 127.0.0.1:27017 ns: admin.$cmd query: { whatsmyuri: 1 } at connect (src/mongo/shell/mongo.js:179:14) at (connect):1:6 at src/mongo/shell/mongo.js:179 exception: connect failed
The server can be configured to accept requests from clients without a PEM file by enabling net.ssl.weakCertificateValidation, but you will weaken your security without real gain.
Step 6.5) Configure Node.JS / Mongoose
There are a couple gotchas here, so naked with me.
First, you MUST have node-Mongodb-native 2.0 or newer. If you are using Mongoose, then you need Mongoose 4.0 or later. Previous versions of Mongoose used node-Mongodb-native 1. *, which does not support certificate certification in any capacity.
Secondly, there are no sslAllowInvalidHostnames or a similar option available in node-Mongodb-native. This is not something that node-Mongodb-native developers can fix (I would have done so far) because the native TLS library is available in Node 0.10. * Does not offer this. Node 4. * and 5. * have the option checkServerIdentity, which gives hope, but moving from the original Node branch to the branch after the io.js merge may cause a little headache for the time being.
So try this:
var fs = require('fs') , mongoose = require('mongoose') , mongoUri = "mongodb://127.0.0.1:27017?ssl=true" , mongoOpt = { "server": { "sslKey": fs.readFileSync('/etc/ssl/mongodb.pem'), "sslCert": fs.readFileSync('/etc/ssl/mongodb-cert.crt'), "sslCa": fs.readFileSync('/etc/ssl/mongodb-ca.crt') } } ;
If you get host / IP name mismatch errors, either correct your certificate or deny all this hard work by disabling sslValidate:
var fs = require('fs') , mongoose = require('mongoose') , mongoUri = "mongodb://127.0.0.1:27017?ssl=true" , mongoOpt = { "server": { "sslValidate": false, "sslKey": fs.readFileSync('/etc/ssl/mongodb.pem'), "sslCert": fs.readFileSync('/etc/ssl/mongodb-cert.crt'), "sslCa": fs.readFileSync('/etc/ssl/mongodb-ca.crt') } } ;
Source: http://www.bainweb.com/2015/11/connecting-to-mongodb-over-tlsssl-with.html