gpt4 book ai didi

python - 使用 PyMongo 和 x509 SSL 证书连接到 MongoDB 数据库时出现 ServerSelectionTimeoutError

转载 作者:可可西里 更新时间:2023-11-01 09:53:50 28 4
gpt4 key购买 nike

我正在尝试连接到另一台服务器上的 MongoDB 数据库。唯一的问题是连接到服务器需要专门版本的 Kerberos。为了克服这个问题,我使用 SSH 隧道为 Pymongo 打开一个本地端口以连接数据库,我们专门为这种情况设计了安全证书作为预防措施。我知道隧道运行正常,因为 Mongo Shell 和 Robo 3T 都能够连接到数据库并显示数据。但是,对于 PyMongo 版本 3.7.1,我收到以下错误:

ServerSelectionTimeoutError: hostname '127.0.0.1' doesn't match either of '<redacted server1>', '<redacted server1 wildcard domain>', '127.0.0.1'

证书是使用显式 <server name> 设置的以及*.server_domain.com在 x509 证书的 DNS 列表中,如果我们不得不将 MongoDB 移动到域中的另一个服务器位置。我们还添加了 127.0.0.1对于位于域之外的少数用户,他们需要使用 SSH 隧道来访问数据库。

使用 PyMongo,我们得到以下错误:

from pymongo import MongoClient
client = MongoClient('127.0.0.1', 27017, ssl_ca_certs='/Users/<user>/ssl_cert_location/mongodb.pem')
db = client['admin']
db.authenticate('<username>', '<password>')

---------------------------------------------------------------------------
ServerSelectionTimeoutError Traceback (most recent call last)
<ipython-input-26-ca905a055830> in <module>()
----> 1 db.authenticate('<username>', '<password>')

/Users/<user>/anaconda2/lib/python2.7/site-packages/pymongo/database.pyc in authenticate(self, name, password, source, mechanism, **kwargs)
1272 self.name,
1273 credentials,
-> 1274 connect=True)
1275
1276 return True

/Users/<user>/anaconda2/lib/python2.7/site-packages/pymongo/mongo_client.pyc in _cache_credentials(self, source, credentials, connect)
607 if connect:
608 server = self._get_topology().select_server(
--> 609 writable_preferred_server_selector)
610
611 # get_socket() logs out of the database if logged in with old

/Users/<user>/anaconda2/lib/python2.7/site-packages/pymongo/topology.pyc in select_server(self, selector, server_selection_timeout, address)
222 return random.choice(self.select_servers(selector,
223 server_selection_timeout,
--> 224 address))
225
226 def select_server_by_address(self, address,

/Users/<user>/anaconda2/lib/python2.7/site-packages/pymongo/topology.pyc in select_servers(self, selector, server_selection_timeout, address)
181 with self._lock:
182 server_descriptions = self._select_servers_loop(
--> 183 selector, server_timeout, address)
184
185 return [self.get_server_by_address(sd.address)

/Users/<user>/anaconda2/lib/python2.7/site-packages/pymongo/topology.pyc in _select_servers_loop(self, selector, timeout, address)
197 if timeout == 0 or now > end_time:
198 raise ServerSelectionTimeoutError(
--> 199 self._error_message(selector))
200
201 self._ensure_opened()

ServerSelectionTimeoutError: hostname '127.0.0.1' doesn't match either of '<redacted server1>', '<redacted server1 wildcard domain>', '127.0.0.1'

此错误最重要的部分是 hostname '127.0.0.1' doesn't match '127.0.0.1' .这对我来说毫无意义,因为它显然确实匹配,而且 Mongo Shell 和 Robo 3T 都对使用此 x509 SSL 证书连接到数据库没有任何疑虑。

对于域外的 Mongo shell,似乎没有问题:

$  pkinit -f <user>
<user> PIN: *****************

$ /usr/local/ossh/bin/ssh -4K -nNT -L 27017:127.0.0.1:<mongo_port> <user>@<server1>

$ ./mongo --host 127.0.0.1 --port 27017 --ssl --sslCAFile ~/ssl_cert_location/mongodb6.pem

MongoDB shell version v4.0.1
connecting to: mongodb://127.0.0.1:27017/
MongoDB server version: 3.6.5
WARNING: shell and server versions do not match
MongoDB Enterprise > use admin
switched to db admin

因此,隧道正常运行,MongoDB 的 SSL x509 证书没有任何问题。那么这就引出了为什么 Pymongo 无法处理给定的 x509 证书的问题?我没有在主机名列表中使用任何前导或尾随点,这似乎是所有线程在搜索此错误时所关注的。我明确给出了 x509 证书中列为备用 DNS 主机名之一的确切主机名。

我将不胜感激任何人能给我关于这个错误的任何帮助。提前致谢。

最佳答案

这是驱动程序的一些代码。您的证书已被解析并尝试从 subjectAltName 部分加载 DNS 名称 https://github.com/mongodb/mongo-python-driver/blob/749c1a2f0bde87a6e6d8df9366e4c90666efd189/pymongo/ssl_match_hostname.py#L103-L113

请注意,驱动程序会区分 subjectAltName 中的“DNS”和“IP 地址”键控条目。我想您已经在证书中添加了“127.0.0.1”作为 DNS hostanme,而驱动程序将字符串“127.0.0.1”视为 IP 地址因此没有匹配项。

这就是代码因令人困惑的错误而失败的原因。匹配失败不在于直接值(value)——它在于这样一个事实一个是 IP 地址,另一个是主机名。

混淆发生得稍早一些,其中一个变量 host_ip指定的主机名是否可以解析为一个IP地址或没有。 https://github.com/mongodb/mongo-python-driver/blob/749c1a2f0bde87a6e6d8df9366e4c90666efd189/pymongo/ssl_match_hostname.py#L98-L102在主机名“127.0.0.1”的情况下,我想它被正确解析并分配给了 host_ip variable

现在这个检查将失败 https://github.com/mongodb/mongo-python-driver/blob/749c1a2f0bde87a6e6d8df9366e4c90666efd189/pymongo/ssl_match_hostname.py#L107并且它不会匹配您证书的 DNS 主机名部分中的“127.0.0.1”。

修复

您的证书 subjectAltName字段应该看起来像这样:
subjectAltName = DNS:<server1>, DNS:<server2>, IP:127.0.0.1

关于python - 使用 PyMongo 和 x509 SSL 证书连接到 MongoDB 数据库时出现 ServerSelectionTimeoutError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51830805/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com