Configure MongoDB (and a client) for SSL/TLS
MongoDB supports encrypted data transport (communication between your application and the database engine) but requires some configuration on both the client and the server in order to set things up correctly.
Below, I'll be discussing generating your own SSL certificate and configuring the server to load this certificate on startup, as well as how to configure your application to connect to the server.
This information can be applied to a MongoDB instance on any OS, and the C# client (version 2.4.3 at time of writing) running on Windows, or any OS with C# Core running Mono.
NOTE: We're creating a self-signed certificate here for development purposes, but ultimately you would want to use a valid CA signed certificate (especially in production environments). Otherwise, validating your servers certificate on the client side either needs to be bypassed (as in the example below), or you would need to export and install your local CA certificate onto each client machine as a trusted/intermediate third-party CA... not ideal.
So, the following steps are going to be required:
- Create a self-signed certificate with OpenSSL for development;
- Configure the mongod server;
- Configure the client;
Create a self-signed certificate with OpenSSL
NOTE: As previously noted, Self-Signing certificates is not recommended for production environments. This step is only for development environments.
As pointed out by Johan Eyrich, if you use self-signed certificates, you would need to bypass the verification step allowing for a possible man-in-the-middle attack on the CA. So, and I know this is bleedingly obvious, but, don't do this in production.
Make sure you have OpenSSL installed. If you're on Windows, you can find links to download the latest version of the OpenSSL binaries here: https://wiki.openssl.org/index.php/Binaries.
For other platforms, you can build it yourself: https://www.openssl.org/source/ (build and installation instructions can be found here: https://wiki.openssl.org/index.php/Compilation_and_Installation)
Enter the following commands into your favourite terminal / command prompt...
openssl genrsa -des3 -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=db-server-name'
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
When prompted, enter a password for the certificate. (You will need this in the next step).
Mongo needs a .pem
file. This is essentially a container format (text file) that contains the certificate and the private key in the same file. You can generate this in bash with the following command...
cat server.crt server.key > cert.pem
** If you're running Windows and don't have bash installed, you can simply create an empty text file in your favourite editor (vscode, Sublime Text, Notepad++ etc.), paste in the contents of server.crt
then the contents of server.key
and save the new file as cert.pem
.
Now, just copy the cert.pem
file to your mongo server's bin
directory.
Update the MongoDB Config file with SSL details
Open your MongoDB configuration file (you'll have normally set this up during mongo installation) and add the net
section if it doesn't already exist.
Reminder: this is a YAML file, so indent with spaces (not tabs)!
net:
bindIp: localhost
ssl:
mode: requireSSL
PEMKeyFile: /[path-to-mongo]/cert.pem
PEMKeyPassword: <certificate password created in previous step>
allowInvalidCertificates: true
allowInvalidHostnames: true
Start mongod
Once you've configured mongo to load the certificate, you can re-start mongod.
If you've somehow broken the config file, any issues encountered will be written to the log file (as specified in the config prior to the broken section) or, output to the console if you run it manually via the command line.
You can quickly check client connectivity by running the mongo
(client) executable. (Make sure you ONLY specify the parameters which instruct it to ignore the self-signed certificate in a DEV/DEMO environment.)
In production:
mongo --ssl
If you need to test your DEV environment with a self-signed certificate, use:
# DEV ENVIRONMENT ONLY
mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates
Any errors should be output to the console (and the mongod log file as specified).
Configure your client connection
Configuring the client connection to handle SSL with a self-signed certificate is fairly straightforward, you just need to instantiate an SSL settings instance.
In our demo, we also need to bypass validation on the self-signed development certificate...
C#:
public void getClientSettings()
{
var url = new MongoUrl("mongodb://myUsername:myPassword@server1");
var clientSettings = MongoClientSettings.FromUrl(url)
{
UseSsl = true,
SslSettings = new SslSettings()
{
CheckCertificateRevocation = true // *1
},
VerifySslCertificate = true // *1
};
return clientSettings;
}
/**
* NOTE: *1 - if you are using self-signed certificates for testing
* you will need to set the CA verification and revocation checks to false,
* otherwise your certificates will appear to be invalid in any testing
* you are performing. Never do this in production of course.
*/
php:
<?php
$client = new MongoDB\Client("mongodb://myUsername:myPassword@server1/?ssl=true");
// Alternatively, the authentication credentials and URI parameters
// may be specified in the constructor's $uriOptions parameter...
$client = new MongoDB\Client('mongodb://server1', [
'username' => 'myUsername',
'password' => 'myPassword',
'ssl' => true,
'authSource' => 'admin'
]);
?>