Self-signed SSL connection using PyMongo

被刻印的时光 ゝ 提交于 2019-11-30 00:52:24

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:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!