I\'m trying to create a secure SSL connection to MongoDB using PyMongo. The goal is to use this configuration for a Mongo instance running on EC2 to which I can connect with
There are other ways of generating server/client pem with a Certificate Authority i.e. without involving file.srl
, but this answer is to follow up on the question.
Worth mentioning that most MongoDB v3.0+ distributions now include support for SSL, please be sure to choose a package that supports SSL. The example below is tested with MongoDB v3.2 on Ubuntu Linux 14.04 with PyMongo v3.2.1. Where a single machine generated the CA, server and client pem files for demonstration purposes.
Let's generate ca.pem
and privkey.pem
. The subject structure is /C=<Country Name>/ST=<State>/L=<Locality Name>/O=<Organisation Name>/emailAddress=<email>/CN=<Common Name>
.
mkdir ~/ssl
cd ~/ssl
openssl req -out ca.pem -new -x509 -days 3650 -subj "/C=AU/ST=NSW/O=Organisation/CN=root/emailAddress=user@domain.com"
Generate server .pem
file:
hostname # note down the value
echo "00" > file.srl # two random digits number
openssl genrsa -out server.key 2048
openssl req -key server.key -new -out server.req -subj "/C=AU/ST=NSW/O=Organisation/CN=server1/CN=<hostname value>/emailAddress=user@domain.com"
openssl x509 -req -in server.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out server.crt -days 3650
cat server.key server.crt > server.pem
openssl verify -CAfile ca.pem server.pem
Although you can use IP address as CN
value as well, it is not recommended. See RFC-6125.
Now let's generate client.pem
file:
openssl genrsa -out client.key 2048
openssl req -key client.key -new -out client.req -subj "/C=AU/ST=NSW/O=Organisation/CN=client1/emailAddress=user@domain.com"
openssl x509 -req -in client.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out client.crt -days 3650
cat client.key client.crt > client.pem
openssl verify -CAfile ca.pem client.pem
After generating the .pem
files, now you can run mongod. for example:
mongod --sslMode requireSSL --sslPEMKeyFile ~/server.pem --sslCAFile ~/ca.pem
You can test the connection using the mongo shell, for example:
mongo --ssl --sslPEMKeyFile ~/client.pem --sslCAFile ~/ca.pem --host <server hostname>
Once you can get connected successfully, you can try with PyMongo. For example:
import ssl
from pymongo import MongoClient
client = MongoClient(
'<server hostname>',
27017,
ssl=True,
ssl_certfile='~/client.pem',
ssl_cert_reqs=ssl.CERT_REQUIRED,
ssl_ca_certs='~/ca.pem'
)
Alternatively, you can also use mongod
flag --sslAllowInvalidHostnames to specify localhost
, etc.
For production use, your MongoDB deployment should use valid certificates generated and signed by a single certificate authority. If you use a self-signed certificate, although the communications channel will be encrypted, there will be no validation of server identity. Using a certificate signed by a trusted certificate authority will permit MongoDB drivers to verify the server’s identity. In general, avoid using self-signed certificates unless the network is trusted.
Other related links that you may find useful: