首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ServerSelectionTimeoutError与MongoDB数据库连接时使用PyMongo和x509 SSL证书

问ServerSelectionTimeoutError与MongoDB数据库连接时使用PyMongo和x509 SSL证书
EN

Stack Overflow用户
提问于 2018-08-13 21:27:01
回答 1查看 2.1K关注 0票数 3

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

代码语言:javascript
复制
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列表中的x509设置的。我们还为位于域之外的少数需要使用SSH隧道访问数据库的用户添加了127.0.0.1。

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

代码语言:javascript
复制
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'。这对我来说毫无意义,因为它显然是匹配的,使用此x509 SSL证书连接到数据库的Mongo和Robo3T都没有任何质量。

对于来自域外的Mongo外壳,似乎没有什么问题:

代码语言:javascript
复制
$  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证书方面没有任何问题。这就引出了为什么Pymongo不能处理给定的x509证书的问题?在主机名列表中,我没有使用任何前导点或尾随点,这似乎是所有线程在搜索此错误时所关注的内容。我显式地给出了确切的主机名,该主机名列为x509证书中的备选DNS主机名之一。

对于这个错误,我非常感谢任何人能给我的任何帮助。提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-11-10 00:41:23

这是司机的代码。您的证书将被解析,并尝试从subjectAltName节hostname.py#L103-L113加载DNS名称。

注意,驱动程序在subjectAltName中区分了'DNS‘和'IP地址’键控条目。我猜想您在证书中添加了'127.0.0.1‘作为DNS hostanme,而驱动程序将字符串'127.0.0.1’作为IP地址处理,因此没有匹配。

这就是为什么代码在出现令人困惑的错误时失败的原因。匹配失败不是在直接值上,而是一个是IP地址,另一个是主机名。

这种混淆发生在稍早的时候,在指定的主机名是否可以解析为IP地址时分配变量host_ip。hostname.py#L98-L102 --在主机名'127.0.0.1‘的情况下,我认为它被正确地解析并分配给host_ip variable

现在,此检查将失败hostname.py#L107,它将不匹配'127.0.0.1‘从您的证书主机名部分。

修正

您的cert的subjectAltName字段可能应该如下所示:

subjectAltName = DNS:<server1>, DNS:<server2>, IP:127.0.0.1

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51830805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档