pymongo returns 尝试连接到本地 Mongo 实例时出现 SSL 错误

pymongo returns an SSL error when trying to connect to local Mongo instance

我正在编写一个小应用程序,它将 JSON 文件写入 Mongo 集合,然后根据给定的输入检索它们。我将 Mongo 设置存储为 Pydantic 模型,如下所示 settings.py:

from typing import Optional
from pydantic import BaseSettings

__all__ = ["mongo_settings"]


class MongoSettings(BaseSettings):
    host: str = "mongodb://127.0.0.1"
    port: int = 27017
    minPoolSize: int = 10
    maxPoolSize: int = 10
    username: str = None
    password: str = None
    authSource: Optional[str] = ""
    tls: bool = True
    tlsAllowInvalidCertificates: bool = True

mongo_settings = MongoSettings()

这些在 Database class 中使用 returns a MongoClient:

from pymongo import MongoClient
from .settings import mongo_settings


class Database:
    client: MongoClient = None

    def get_database() -> MongoClient:
        client = MongoClient(**mongo_settings.dict())
        return client

我已经编写了一个(非常)基本的测试来检查我的应用程序是否可以连接到 Mongo 的本地 运行 实例:

from pymongo import MongoClient
from database.db import Database

def test_database_connection():

    mongo: MongoClient = Database.get_database()

    mongo.server_info()

但是,此操作失败并出现以下错误:

Traceback (most recent call last):
  File "/code/project-env/lib/python3.8/site-packages/pymongo/pool.py", line 909, in _configured_socket
    sock = ssl_context.wrap_socket(sock, server_hostname=host)
  File "/home/.pyenv/versions/3.8.2/lib/python3.8/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/home/.pyenv/versions/3.8.2/lib/python3.8/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/home/.pyenv/versions/3.8.2/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1108)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/code/project-env/lib/python3.8/site-packages/pymongo/mongo_client.py", line 1749, in _process_periodic_tasks
    self._topology.update_pool()
  File "/code/project-env/lib/python3.8/site-packages/pymongo/topology.py", line 438, in update_pool
    server._pool.remove_stale_sockets(pool_id)
  File "/code/project-env/lib/python3.8/site-packages/pymongo/pool.py", line 1060, in remove_stale_sockets
    sock_info = self.connect()
  File "/code/project-env/lib/python3.8/site-packages/pymongo/pool.py", line 1089, in connect
    sock = _configured_socket(self.address, self.opts)
  File "/code/project-env/lib/python3.8/site-packages/pymongo/pool.py", line 922, in _configured_socket
    _raise_connection_failure(address, exc, "SSL handshake failed: ")
  File "/code/project-env/lib/python3.8/site-packages/pymongo/pool.py", line 290, in _raise_connection_failure
    raise AutoReconnect(msg)
pymongo.errors.AutoReconnect: SSL handshake failed: 127.0.0.1:27017: EOF occurred in violation of protocol (_ssl.c:1108)

我试过 /etc/mongod.conf 文件看看是否能解决问题,net 块目前看起来像这样:

net:
  port: 27017
  ssl:
    mode: requireSSL
    CAFile: "~/.ssl/ca.pem"
    PEMKeyFile: "~/.ssl/server.pem"
    PEMKeyPassword: 'XXXXXXXXX'
    allowConnectionsWithoutCertificates: true

但这没有产生任何结果。我觉得我在这里遗漏了一些明显的东西,导致它无法正常工作,有人知道我做错了什么吗?

事实证明代码本身没有任何问题 - mongod.conf 文件中的波浪号快捷方式意味着证书没有被正确读取。将其换成绝对路径似乎已经解决了问题