TLS/SSL和PyMongo

PyMongo支持通过TLS/SSL连接到MongoDB。本指南介绍了PyMongo支持的配置选项。看到了吗 the server documentation 配置MongoDB。

依赖关系

对于使用TLS/SSL的连接,PyMongo可能需要由Python版本决定的第三方依赖项。在PyMongo 3.3+中,可以使用以下pip命令安装PyMongo 3.3+和任何与TLS/SSL相关的依赖项:

$ python -m pip install pymongo[tls]

从pymongo3.11开始安装 PyOpenSSLrequestsservice_identity 对于Python版本早于2.7.9的用户。PyOpenSSL支持这些旧Python版本的SNI,允许应用程序连接到Altas免费和共享层实例。

早期版本的PyMongo要求您手动安装下面列出的依赖项。

Python 2.x版

这个 ipaddress 所有平台都需要模块。

使用CPython<2.7.9或PyPy<2.5.1时:

警告

行业最佳实践建议使用TLS 1.1或更高版本,有些法规要求使用TLS 1.1或更高版本。虽然PyMongo不需要对应用程序进行任何更改就可以使用最新的协议,但是某些操作系统或版本可能无法提供足够新的OpenSSL版本来支持它们。

超过10.13(High Sierra)的macOS用户需要从 python.orghomebrewmacports 或其他类似来源。

Linux或其他非macOS Unix的用户可以检查他们的OpenSSL版本,如下所示:

$ openssl version

如果版本号小于1.0.1,则TLS 1.1或更高版本的支持不可用。请与您的操作系统供应商联系以获得解决方案或升级到更新的发行版。

您可以通过安装 requests 模块并执行以下命令:

python -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

您应该看到“TLS 1.X”,其中X大于等于1。

您可以在此处阅读有关TLS版本及其安全含义的更多信息:

https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Only_Support_Strong_Protocols

基本配置

在许多情况下,通过TLS/SSL连接到MongoDB只需要传递 ssl=True 作为的关键字参数 MongoClient ::

>>> client = pymongo.MongoClient('example.com', ssl=True)

或通过 ssl=true 在URI中:

>>> client = pymongo.MongoClient('mongodb://example.com/?ssl=true')

这会将PyMongo配置为使用TLS连接到服务器,验证服务器的证书,并验证您尝试连接的主机是否列在该证书中。

证书验证策略

默认情况下,PyMongo配置为在启用TLS时需要来自服务器的证书。可以使用 ssl_cert_reqs 选项。要禁用此要求通行证 ssl.CERT_NONE 作为关键字参数:

>>> import ssl
>>> client = pymongo.MongoClient('example.com',
...                              ssl=True,
...                              ssl_cert_reqs=ssl.CERT_NONE)

或者,在URI中:

>>> uri = 'mongodb://example.com/?ssl=true&ssl_cert_reqs=CERT_NONE'
>>> client = pymongo.MongoClient(uri)

指定CA文件

在某些情况下可能需要配置Pyo证书集。当您充当自己的证书颁发机构而不是使用由知名机构签名的服务器证书时,通常会出现这种情况。这个 ssl_ca_certs 选项接受CA文件的路径。它可以作为关键字参数传递:

>>> client = pymongo.MongoClient('example.com',
...                              ssl=True,
...                              ssl_ca_certs='/path/to/ca.pem')

或者,在URI中:

>>> uri = 'mongodb://example.com/?ssl=true&ssl_ca_certs=/path/to/ca.pem'
>>> client = pymongo.MongoClient(uri)

指定证书吊销列表

Python2.7.9+(Pypy2.5.1+)和3.4+支持证书撤销列表。这个 ssl_crlfile 选项接受指向CRL文件的路径。它可以作为关键字参数传递:

>>> client = pymongo.MongoClient('example.com',
...                              ssl=True,
...                              ssl_crlfile='/path/to/crl.pem')

或者,在URI中:

>>> uri = 'mongodb://example.com/?ssl=true&ssl_crlfile=/path/to/crl.pem'
>>> client = pymongo.MongoClient(uri)

注解

证书吊销列表和 OCSP 不能一起使用。

客户端证书

PyMongo可以配置为使用 ssl_certfile 选项:

>>> client = pymongo.MongoClient('example.com',
...                              ssl=True,
...                              ssl_certfile='/path/to/client.pem')

如果客户端证书的私钥存储在单独的文件中,请使用 ssl_keyfile 选项:

>>> client = pymongo.MongoClient('example.com',
...                              ssl=True,
...                              ssl_certfile='/path/to/client.pem',
...                              ssl_keyfile='/path/to/key.pem')

Python2.7.9+(Pypy2.5.1+)和3.3+支持提供密码或密码来解密加密的私钥。使用 ssl_pem_passphrase 选项:

>>> client = pymongo.MongoClient('example.com',
...                              ssl=True,
...                              ssl_certfile='/path/to/client.pem',
...                              ssl_keyfile='/path/to/key.pem',
...                              ssl_pem_passphrase=<passphrase>)

这些选项也可以作为MongoDB URI的一部分传递。

OCSP

从PyMongo 3.11开始,如果PyMongo安装了“ocsp”附加文件:

python -m pip install pymongo[ocsp]

通过以下方式启用证书吊销检查 OCSP (Online Certification Status Protocol) . MongoDB 4.4版+ staples OCSP responses PyMongo将验证的TLS握手,如果装订的OCSP响应无效或指示对等证书已吊销,则TLS握手失败。

当连接到4.4以上版本的服务器时,或者当4.4+版本的MongoDB没有固定OCSP响应时,如果对等证书指定了OCSP端点,PyMongo将尝试直接连接到OCSP端点。只有在这种情况下,如果响应指示证书被吊销,TLS握手才会失败。无效或格式错误的响应将被忽略,这将使可用性优于最大安全性。

TLS错误故障排除

TLS错误通常分为三类-证书验证失败、协议版本不匹配或证书吊销检查失败。类似于以下内容的错误消息表示OpenSSL无法验证服务器的证书:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

这通常是因为OpenSSL不能访问系统的根证书,或者证书已经过期。Linux用户应该确保他们从Linux供应商那里安装了最新的根证书更新。macOS用户使用Python 3.6.0或更高版本下载python.org网站 may have to run a script included with python 要安装根证书:

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

旧的PyPy便携版本的用户可能必须 set an environment variable 告诉OpenSSL在哪里可以找到根证书。使用 certifi module 来自pypi::

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

与以下消息类似的错误消息表示Python使用的OpenSSL版本不支持足够新的TLS协议来连接到服务器:

[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version

行业最佳实践建议在某些MongoDB部署中禁用较旧的TLS协议,有些法规要求这样做。某些部署可能禁用TLS 1.0,其他部署可能禁用TLS 1.0和TLS 1.1。有关故障排除步骤和解决方案,请参阅本文档前面的警告。

与以下消息类似的错误消息表示证书吊销检查失败:

[('SSL routines', 'tls_process_initial_server_flight', 'invalid status response')]

OCSP 了解更多详细信息。