简体   繁体   English

SSL Python3 上 Pymongo 的握手问题

[英]SSL Handshake issue with Pymongo on Python3

Trying to connect to Azure CosmosDB mongo server results into an SSL handshake error.尝试连接到 Azure CosmosDB mongo 服务器会导致 SSL 握手错误。

I am using Python3 and Pymongo to connect to my Azure CosmosDB.我正在使用Python3Pymongo连接到我的 Azure CosmosDB。 The connection works fine if I run the code with Python27 but causes the below error when using Python3:如果我使用 Python27 运行代码,则连接工作正常,但在使用 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://KEY123@backend.documents.azure.com: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:Python3上运行它会导致以下错误:

pymongo.errors.ServerSelectionTimeoutError: SSL handshake failed: backendstore.documents.azure.com:10255: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749) 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 :当我使用 Python27 运行相同的代码时,这是我成功的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')数据库服务器状态: { "_t": "OKMongoResponse", "ok": 1 } Collection(Database(MongoClient(host=['backend.documents.azure.com:10255'], document_class=dict, tz_aware =True, ssl=True, replicaset='globaldb'), u'result_DB'), u'file_result')

Solved the problem with this change:通过此更改解决了问题:

client = pymongo.MongoClient(uri, ssl_cert_reqs=ssl.CERT_NONE)

On Windows you can do like this在 Windows 你可以这样做

pip install certifi pip 安装证书

Then use it in code:然后在代码中使用它:

import certifi
ca = certifi.where()

client = pymongo.MongoClient(
"mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/xyzdb?retryWrites=true&w=majority", tlsCAFile=ca)

The section Troubleshooting TLS Errors of the PyMongo offical document `TLS/SSL and PyMongo introduces the issue as below. PyMongo 官方文档“TLS/SSL 和 PyMongo 的Troubleshooting TLS Errors ”部分介绍了以下问题。

TLS errors often fall into two categories, certificate verification failure or protocol version mismatch. TLS 错误通常分为两类,证书验证失败或协议版本不匹配。 An error message similar to the following means that OpenSSL was not able to verify the server's certificate:类似于以下的错误消息意味着 OpenSSL 无法验证服务器的证书:

[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.这通常是因为 OpenSSL 无权访问系统的根证书或证书已过期。 Linux users should ensure that they have the latest root certificate updates installed from their Linux vendor. Linux 用户应确保从其 Linux 供应商处安装了最新的根证书更新。 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:使用从 python.org 下载的 Python 3.6.0 或更新版本的 macOS 用户可能必须运行 python 随附的脚本来安装根证书:

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.旧 PyPy 和 PyPy3 便携版本的用户可能必须设置一个环境变量来告诉 OpenSSL 在哪里可以找到根证书。 This is easily done using the certifi module from pypi:使用 pypi 的certifi 模块很容易做到这一点:

 $ 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.您可以尝试按照上面的描述来解决您的问题,这似乎适用于 Linux 和 Mac 用户。 On Windows, I can not reproduce your issue in Python 3.7 and 3.6 .在 Windows 上,我无法在 Python 3.73.6中重现您的问题。 If you have any concern, please feel free to let me know.如果您有任何疑虑,请随时告诉我。

Faced the same issue when trying to connect mongodb from Digital Ocean, Solved by using this function with params in MongoClient:尝试从 Digital Ocean 连接 mongodb 时遇到同样的问题,通过在 MongoClient 中使用此 function 和参数解决:

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")

On Mac Mojave 10.14.6, I used (PyMongo 3.10 and python 3.7), to solve:在 Mac Mojave 10.14.6 上,我使用(PyMongo 3.10 和 python 3.7)来解决:

flask pymongo pymongo.errors.ServerSelectionTimeoutError [SSL: CERTIFICATE_VERIFY_FAILED] 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)如果您使用其他 python 版本,只需更改版本号(在我的情况下,我有 Python 3.7)

cluster = MongoClient(
    "url",
    ssl=True,
    ssl_cert_reqs=ssl.CERT_NONE,
)

On mac Monterey, I used pymongo 3.12.1 and virtual environment在 mac Monterey 上,我使用了 pymongo 3.12.1 和虚拟环境

To solve, use要解决,请使用

ssl_cert_reqs=CERT_NONE

with mongodb url与 mongodb url

Update to the answer provided by @abhinav singh (as of 1/2022):更新@abhinav singh 提供的答案(截至 2022 年 1 月):

client = pymongo.MongoClient(uri, tls=True, tlsAllowInvalidCertificates=True)

Reference: https://pymongo.readthedocs.io/en/stable/examples/tls.html?#certificate-verification-policy参考: https://pymongo.readthedocs.io/en/stable/examples/tls.html?#certificate-verification-policy

By default pymongo relies on the operating system's root certificates.默认情况下 pymongo 依赖于操作系统的根证书。

It could be that Atlas itself updated its certificates or it could be that something on your OS changed.可能是 Atlas 本身更新了其证书,也可能是您的操作系统上的某些内容发生了变化。 “certificate verify failed” often occurs because OpenSSL does not have access to the system's root certificates or the certificates are out of date.由于 OpenSSL 无权访问系统的根证书或证书已过期,因此经常出现“证书验证失败”。 For how to troubleshoot see TLS/SSL and PyMongo — PyMongo 3.12.0 documentation 107.有关如何排除故障,请参阅 TLS/SSL 和 PyMongo — PyMongo 3.12.0 文档 107。

pls Try:请尝试:

 client = pymongo.MongoClient(connection, tlsCAFile=certifi.where())

and dont forget to install certifi并且不要忘记安装证书

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM