![](/img/trans.png)
[英]ServerSelectionTimeoutError when connecting to aws with pymongo
[英]ServerSelectionTimeoutError When connecting to MongoDB Database with PyMongo and x509 SSL Certificate
我正在尝试连接到另一台服务器上的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'
如果我们必须将MongoDB移动到域中的另一个服务器位置,则在x509证书的DNS列表中使用显式<server name>
和*.server_domain.com
证书。 我们还为位于域外的少数用户添加了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地址,因此没有匹配。
这就是代码因混淆错误而失败的原因。 匹配失败不是直接值 - 它是因为一个是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'不匹配你的证书。
您的cert的subjectAltName
字段应该看起来像这样:
subjectAltName = DNS:<server1>, DNS:<server2>, IP:127.0.0.1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.