Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arturogutierrez/d55787ba723111271b93 to your computer and use it in GitHub Desktop.
Save arturogutierrez/d55787ba723111271b93 to your computer and use it in GitHub Desktop.
MongoDB 3.2.x SSL with Letsencrypt

#MongoDB 3.2.x SSL with Letsencrypt Letsencrypt is an initative which aims to increase the use of encryption for websites. It basically allows people to apply for free certificates provided that they prove the they control the requested domain. We will look at the what is needed to secure your MongoDB installation. For more details on setting up a MongoDB server see MongoDB 3.2.x.

##Set the hostname We sould to set the hostname to match the name of the certificate we are going to optain.

sudo hostname mongo0.example.com

Then update the hostname file to set the server name permanently.

sudo nano /etc/hostname

Set the hostname in the file to:

mongo0.example.com

##Modify the hosts file Modify the hosts file. If you are using a replica set then, obviously on mongo1 the 127.0.0.1 will point at localhost mongo1.example.com. For more information on setting up a replica set see Setting up a Replica Set on AWS EC2.

sudo nano /etc/hosts

127.0.0.1           localhost mongo0.example.com
52.51.12.62         mongo0.example.com

##Setup the DNS entry The hosts file entry is fine for local name resolution but to obtain a SSL certificate from Letsencrypt it will need to be able to resolve the name externally. So you will need to create a DNS entry (A or AAAA) to point at your server.

##Ports To optain the SSL certificate you will need to ensure that your server is accessable over port 80 and 443 as Letsencrypt will use this to connect to confirm that you control the domain.

##Getting the SSL certificate for your server.

###Installation To install the client, clone the repostiory from github.

git clone https://github.com/letsencrypt/letsencrypt.git
cd letsencrypt

###Request the Certificate

./letsencrypt-auto certonly -a manual --rsa-key-size 4096 -d mongo0.example.com

###Verify Domain Ownership The request will generate a similar response like:

Make sure your web server displays the following content at                                                                                                                    
http://mongo0.example.com/.well-known/acme-challenge/A-xjoIljw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU before continuing:

A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU.eefJYv1muREVb9TpEb3qjr9AQsM8IurTn-Svykj0wN0

If you don't have HTTP server configured, you can run the following
command on the target server (as root):

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU.eefJYv1muREVb9TpEb3qjr9AQsM8IurTn-Svykj0wN0 > .well-known/acme-challenge/A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()" 
Press ENTER to continue

Note: Do not click ENTER as it will try to find the verification file and we have not set it up yet.

###Setting up the Verification File Since the mongo server is unlikely to have a web server like Apache or Nginx you should use the do the following to create the verification file and spin up a temporary web server.

In a new terminal session:

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU.eefJYv1muREVb9TpEb3qjr9AQsM8IurTn-Svykj0wN0 > .well-known/acme-challenge/A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()" 

Once this temporary server is running you can go back to the original terminal server session and click RETURN. It will then look for the file at the location specified (http://mongo0.example.com/.well-known/acme-challenge/A-xjoIljw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU).

The correct response will look like:

IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to support@example.com.
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/mongo0.example.com/fullchain.pem. Your
   cert will expire on 2016-06-08. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

For more details on renewing certificates Letsencrypt

##Preparing the Letsencrypt cert for use with MongoDB Letsencrypt will create the following certs:

  • cert.pem
  • chain.pem
  • fullchain.pem
  • privkey.pem

The first thing is to combine the privkey and cert into a single file mongodb.pem.

cd /etc/letsencrypt/live/mongo0.example.com
cat privkey.pem cert.pem > mongodb.pem

The next thing is to download the CA authority files from the letsencrypt.org web site:

wget https://letsencrypt.org/certs/isrgrootx1.pem">isrgrootx1.pem
wget https://letsencrypt.org/certs/letsencryptauthorityx1.pem

and combine them into a single file letsencryptchain.pem

cat letsencryptauthorityx1.pem isrgrootx1.pem > letsencryptchain.pem

#Setup the Certs folder

mkdir /home/certs
cp mongodb.pem /home/certs
cp letsencryptchain.pem /home/certs
chown -R mongodb:mongodb /home/certs
chmod 777 letsencryptchain.pem
chmod 777 mongodb

##Configure MongoDB Edit the mongod.conf:

sudo nano /etc/mongod.conf

Specify the SSL locations. You may to specify a PEMKeyPassword if you got the cert from an different source than letsencrypt.

# network interfaces
net:
  port: 27017
  ssl:
     mode: requireSSL
     PEMKeyFile: /home/certs/mongodb.pem
     PEMKeyPassword:
     CAFile:     /home/certs/letsencryptchain.pem

Restart MongoDB to make sure it is using the new settings:

sudo service mongod restart

Check that is is running:

tail -20  /var/log/mongodb/mongod.log

Try to connect. This should fail as it is now using a SSL connection is now required.

mongo

MongoDB shell version: 3.2.3
connecting to: test
2016-03-08T11:04:26.853+0000 E QUERY    [thread1] Error: network error while attempting to run command 'isMaster' on host '127.0.0.1:27017'  :
connect@src/mongo/shell/mongo.js:224:14
@(connect):1:6

exception: connect failed

Then log into the shell using ssl:

mongo --ssl -sslCAFile /certs/letsencryptchain.pem --host mongo0.example.com --sslPEMKeyFile /certs/mongodb.pem

From inside the shell you can check that ssl is running:

db.serverStatus().security
{
        "SSLServerSubjectName" : "CN=mongo0.example.com",
        "SSLServerHasCertificateAuthority" : true,
        "SSLServerCertificateExpirationDate" : ISODate("2016-07-06T12:09:00Z")
}

Mongo requires the certs to be combined.

@ccjon
Copy link

ccjon commented Nov 27, 2016

Helpful ....thanks. In the event others land here for help, I would suggest changing modes to 644 at most.. Also last line in "setup certs folder" should prob include mongbd.pem instead of just mongodb.

Also an errant double-quote in "The next thing is to download the CA authority files from the letsencrypt.org web site:" section

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment