Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSL Handshake issue with Pymongo on Python3

Trying to connect to Azure CosmosDB mongo server results into an SSL handshake error.

I am using Python3 and Pymongo to connect to my Azure CosmosDB. The connection works fine if I run the code with Python27 but causes the below error when using Python3:

import pymongo
from pymongo import MongoClient
import json
import sys

def check_server_status(client, data):
   '''check the server status of the connected endpoint'''
   db = client.result_DB
   server_status = db.command('serverStatus')
   print('Database server status:')
   print(json.dumps(server_status, sort_keys=False, indent=2, separators=(',', ': ')))
   coll = db.file_result
   print (coll)
   coll.insert_one(data)

def main():
    uri = "mongodb://[email protected]:10255/?ssl=true&replicaSet=globaldb"
    client = pymongo.MongoClient(uri)
    emp_rec1 = {
        "name":"Mr.Geek",
        "eid":24,
        "location":"delhi"
        }
    check_server_status(client, emp_rec1)

if __name__ == "__main__":
    main()

Running this on Python3 results into below error:

pymongo.errors.ServerSelectionTimeoutError: SSL handshake failed: backendstore.documents.azure.com:10255: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)

Here is my successful output when I run the same code with Python27:

Database server status: { "_t": "OKMongoResponse", "ok": 1 } Collection(Database(MongoClient(host=['backend.documents.azure.com:10255'], document_class=dict, tz_aware=False, connect=True, ssl=True, replicaset='globaldb'), u'result_DB'), u'file_result')

like image 845
abhinav singh Avatar asked Feb 01 '19 18:02

abhinav singh


5 Answers

Solved the problem with this change:

client = pymongo.MongoClient(uri, ssl_cert_reqs=ssl.CERT_NONE)
like image 61
abhinav singh Avatar answered Oct 20 '22 23:10

abhinav singh


On Windows you can do like this

pip install certifi

Then use it in code:

import certifi
ca = certifi.where()

client = pymongo.MongoClient(
"mongodb+srv://username:[email protected]/xyzdb?retryWrites=true&w=majority", tlsCAFile=ca)
like image 32
Ankit Parmar Avatar answered Oct 20 '22 22:10

Ankit Parmar


The section Troubleshooting TLS Errors of the PyMongo offical document `TLS/SSL and PyMongo introduces the issue as below.

TLS errors often fall into two categories, certificate verification failure or protocol version mismatch. An error message similar to the following means that OpenSSL was not able to verify the server’s certificate:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

This often occurs because OpenSSL does not have access to the system’s root certificates or the certificates are out of date. Linux users should ensure that they have the latest root certificate updates installed from their Linux vendor. macOS users using Python 3.6.0 or newer downloaded from python.org may have to run a script included with python to install root certificates:

open "/Applications/Python <YOUR PYTHON VERSION>/Install Certificates.command"

Users of older PyPy and PyPy3 portable versions may have to set an environment variable to tell OpenSSL where to find root certificates. This is easily done using the certifi module from pypi:

$ pypy -m pip install certifi
$ export SSL_CERT_FILE=$(pypy -c "import certifi; print(certifi.where())")

You can try to follow the description above to fix your issue, which seems to be for Linux and Mac Users. On Windows, I can not reproduce your issue in Python 3.7 and 3.6. If you have any concern, please feel free to let me know.

like image 44
Peter Pan Avatar answered Oct 20 '22 22:10

Peter Pan


Faced the same issue when trying to connect mongodb from Digital Ocean, Solved by using this function with params in MongoClient:

def get_client(host,port,username,password,db):
      return MongoClient('mongodb://{}:{}/'.format(host,port),
                         username=username,
                         password=password,
                         authSource=db,
                         ssl=True,ssl_cert_reqs=ssl.CERT_NONE)

client = get_client("host-ip","port","username","password","db-name")
like image 31
Aayush Bajaj Avatar answered Oct 21 '22 00:10

Aayush Bajaj


On Mac Mojave 10.14.6 , I used (PyMongo 3.10 and python 3.7), to solve:

flask pymongo pymongo.errors.ServerSelectionTimeoutError [SSL: CERTIFICATE_VERIFY_FAILED]

Execute in terminal:

sudo /Applications/Python\ 3.7/Install\ Certificates.command

If you use other python version, only change versión number (In my case, i have Python 3.7)

like image 4
Kevin Subieta Avatar answered Oct 21 '22 00:10

Kevin Subieta