簡體   English   中英

ServerSelectionTimeoutError使用PyMongo和x509 SSL證書連接到MongoDB數據庫時

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM