Skip to content

Instantly share code, notes, and snippets.

@j0e1in
Last active April 10, 2024 13:16
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save j0e1in/7621b23bc3ef8f942f66e2d8ac2aa2cf to your computer and use it in GitHub Desktop.
Save j0e1in/7621b23bc3ef8f942f66e2d8ac2aa2cf to your computer and use it in GitHub Desktop.
Setup mongodb TSL/SSL with letsencrypt.

Setup Mongo 3.6 TSL/SSL with Letsencrypt

Install certbot

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot

Get Letsencrypt certificate

sudo certbot certonly --standalone -d [domain]

Letsencrypt will create the following certs under /etc/letsencrypt/live/[domain]:

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

Prepare certs for mongodb

cd /etc/letsencrypt/live/[domain]
cat privkey.pem fullchain.pem > /etc/ssl/mongod.pem

Download IdenTrust DST Root CA X3 from https://www.identrust.com/certificates/trustid/root-download-x3.html

Copy the cert to /etc/ssl/ca.crt and wrap it with -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----.

Generate ca.pem

printf "\n" >> ca.crt
cat /etc/letsencrypt/live/[domain]/chain.pem >> /etc/ssl/ca.crt
openssl x509 -in /etc/ssl/ca.crt -out /etc/ssl/ca.pem -outform PEM
openssl verify -CAfile /etc/ssl/ca.pem /etc/ssl/mongod.pem
> mongod.pem: OK (you should see this)

Set permission

chmod 600 /etc/ssl/ca.pem
chmod 600 /etc/ssl/mongod.pem
chown -R mongodb:mongodb /etc/ssl/ca.pem
chown -R mongodb:mongodb /etc/ssl/mongod.pem

Edit mongod.conf

net:
  port: 27017
  bindIp: 0.0.0.0
  ssl:
    mode: requireSSL # 'disabled', 'allowSSL', 'preferSSL', 'requireSSL'
    PEMKeyFile: /etc/ssl/mongod.pem
    CAFile: /etc/ssl/ca.pem
    allowConnectionsWithoutCertificates: false

Connect to mongodb with SSL

mongo [domain]/[db] -u username -p password --ssl --sslPEMKeyFile /etc/ssl/mongod.pem --sslCAFile /etc/ssl/ca.pem

Renew certificates

(Before expiry date, 90 days)

sudo certbot renew
@nalbyuites
Copy link

Please be aware that the "IdenTrust DST Root CA X3" root expiring on 9/30/2021 has been replaced with the "IdenTrust Commercial Root CA 1" self-signed root which is also trusted by the major browsers and root stores since 1/16/2014. You may download the IdenTrust Commercial Root CA 1 at this link: Root Certificate Download.

@GrantGochnauer
Copy link

GrantGochnauer commented Aug 12, 2023

I have been trying to get this to work but I'm not sure which file I'm supported to grab from the comment linked above. I have tried both "DST Root CA X3 Cross-Signing with IdenTrust Commercial CA 1 Chain Details" and "DST Root CA X3-IdenTrust Commercial CA 1 Chain Download". but when I try to verify the cert, I get the following error:

[root@prd04 letsencrypt]# openssl verify -CAfile cab.pem letsencrypt.pem letsencrypt.pem: CN = prd04 error 20 at 0 depth lookup:unable to get local issuer certificate

I have also tried to use the p7b file and convert to pem but I can't seem to get that to work either. A few of my attempts have resulted in Mongo trying to connect to the other nodes with a Handshake "short read" error.

I have also tried using these CA pem files directly from Let's Encrypt: https://letsencrypt.org/certificates/. I should also note that this is running on CentOS7.

Any ideas @nalbyuites or @j0e1in? Thanks

@mervinhemaraju
Copy link

@GrantGochnauer have you been able to find a fix ? I am hitting the same issue

@GrantGochnauer
Copy link

@GrantGochnauer have you been able to find a fix ? I am hitting the same issue

I was not able to get it to work on Mongo 3.6 - I think it's just too old to accept let's encrypt certs. What I tried was:

# Download Root Cert:
wget https://letsencrypt.org/certs/isrgrootx1.pem

# Download Intermediate Cert:
wget https://letsencrypt.org/certs/lets-encrypt-r3.pem

# Concat intermediate CAs
cat isrgrootx1.pem lets-encrypt-r3.pem > ca.pem

# Verify
openssl verify -CAfile ca.pem letsencrypt.pem

sudo certbot renew --dry-run -v

My post hook for letsencrypt:

#!/bin/bash

# Set the source and destination paths
src_path="/etc/letsencrypt/live/myserver.net"
dst_path="/etc/letsencrypt"

# Copy the certificates
cat "${src_path}/privkey.pem" "${src_path}/fullchain.pem" > "${dst_path}/letsencrypt.pem"

# Set appropriate permissions on the destination files (optional)
chmod 644 "${dst_path}/letsencrypt.pem"

We've moved to another database system so we never had the need to come back and solve this. This does work with MongoDB 4.2+

@mervinhemaraju
Copy link

Awesome work @GrantGochnauer. It's working.

Did you automate the renewal of the root certificate ?

Or you do it manually ?

@GrantGochnauer
Copy link

That worked for you? Awesome! I did not automate the renewal of the root cert. I don't remember when it expires but I think it was a number of years in the future.

@mervinhemaraju
Copy link

Yes it did thanks!
I cam automate that but when the certificate expires will they upload a new one to the link above?

Sorry my knowledge on certificates is very limited

@GrantGochnauer
Copy link

Based on the commands above, it just does the dry run. You need to actually have the certbot install the scheduled process.

There are lots of options you can see in the docs but a simple example:

sudo certbot renew --deploy-hook "/etc/letsencrypt/copy_certs.sh"

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