SSL Handshake issue with Pymongo on Python3
PyMongo and TLS / SSL
PyMongo supports connexion via TLS / SSL with MongoDB. This Guide covers the PyMongo-supported configuration options. See the documentation for configuring MongoDB on the server.
Addictions
PyMongo may require third party dependencies for connexions using TLS / SSL, as determined by your Python version. With PyMongo 3.3 +, the following pip command allows you to instal PyMongo 3.3 + and any TLS / SSL related dependencies:
$ python -m pip install pymongo[tls]
SSL Handshake issue with Pymongo on Python3
An attempt to connect to the Azure CosmosDB mongo server results in a handshake error in SSL.
I use Python3 and Pymongo to connect to my Azure CosmosDB. If I run the code with Python27, the connexion works fine but causes the following error when using Python3:
Basic settings
In many cases connecting to MongoDB over TLS / SSL requires nothing but passing ssl = True to MongoClient as a keyword argument:
>>> = pymongo.MongoClient(‘example.com’, ssl=True)
Or pass ssl = true through the URI:
>> Customer = pymongo.MongoClient(‘mongodb:/example.com/?ssl=true’)
This configures PyMongo to connect to the server using TLS, check the server certificate and verify that that certificate lists the host to which you are attempting to connect.
Policy on Certificate Verification
By default, when TLS is enabled PyMongo is configured to require a server certificate. This can be configured using the Option ssl cert reqs. To disable this requirement pass ssl. CERT NONE as a parameter for keywords:
> > > SSL import
>>> = pymongo.MongoClient(‘example.com’),
… ssl = Real,
… ssl cert reqs = ssl. CERT NONE))
In the URI, or:
> > > uri = ‘example.com/mongodb:/? Ssl = verdad&ssl cert reqs = CERT NONE
> > Customer = pymongo. MongoClient(uri)
Specify a CA-file
In some cases you may want to configure a specific set of CA certificates to use PyMongo. This is the case most often with the use of “self-signed” server certificates. The option ssl ca certs takes a path towards a CA file. It can be passed as an argument with keyword:
>>> = pymongo.MongoClient(‘example.com’),
… ssl = Real,
… ssl ca certs=’/route / ca.pem)
In the URI, or:
> > > uri = ‘example.com/mongodb:/? Ssl = true&ssl ca certs=/run to / ca.pem
> > Customer = pymongo. MongoClient(uri)
Specifying a list of revocation certificates
Python 2.7.9 + (pypy 2.5.1 +) and 3.4 + support the lists for the revocation of certificates. The option ssl crlfile takes a path towards a CRL file. It can be passed as an argument with keyword:
>>> = pymongo.MongoClient(‘example.com’),
… ssl = Real,
… ssl crlfile=’/route / to / crl.pem)
In the URI, or:
> > > uri = ‘example.com/mongodb:/? Ssl = true&ssl crlfile=/route / crl.pem
> > Customer = pymongo. MongoClient(uri)
Customer Certificates
PyMongo can be configured with the option ssl certfile to present the client certificate:
>>> = pymongo.MongoClient(‘example.com’),
… ssl = Real,
… ssl certfile=’/path / to.pem)
Use ssl keyfile option when the private key for the client certificate is stored in a separate file:
>>> = pymongo.MongoClient(‘example.com’),
… ssl = Real,
… ssl certfile=’/path/to/client.pem’,
… ssl keyfile=’/path.pem)
Python 2.7.9 + (pypy 2.5.1 +) and 3.3 + support for decrypting encrypted private keys using a password or passphrase. Use the option ssl pem passphrase to:
>>> = pymongo.MongoClient(‘example.com’),
… ssl = Real,
… ssl certfile=’/route / client.pem,
… ssl keyfile=’/path / task.pem,
… passphrase=<passphrase >)
You can also pass those options as part of the MongoDB URI.
Fixing the TLS Errors
TLS errors often fall into two categories: failure to verify certificates or mismatch to protocol versions. A similar error message means that OpenSSL was not in a position to verify the server certificate:
[SSL: CERTIFICATE VERIFY FAILED] certificate which failed to verify
This often happens because OpenSSL has no access to root certificates from the system, or the certificates are outdated. Linux users should make sure their Linux vendor has the latest root certificate updates installed. MacOS users using Python 3.6.0 or newer downloaded from python.org may need to run a python-included script to instal Root Certificates:
Open “/Apps / Python < YOUR PYTHON VERSION>/Certificates.command instal”
Users of older portable versions of PyPy may need to set a variable environment to tell OpenSSL where to find the root certificates. This can be done easily using pypi’s certifi module:
$pypy -m pip certify instal
$SSL CERT FILE=$(pypy -c “importation certificate; print(certifi.where))”)
An error message similar to the following message means that a new enough TLS protocol to connect to the server does not support the OpenSSL version used by Python:
[SSL: TLSV1 ALERT PROTOCOL VERSION] Version of the tlsv1 alert protocol
Industry best practises recommend that older TLS protocols be disabled in some MongoDB deployments, and some regulations require that. Some deployments may disable TLS 1.0, others may disable TLS 1.0 and TLS 1.1. See the earlier warning in this document for troubleshooting steps and solutions.
Leave a Reply