twisted / txmongo

asynchronous python driver for mongo
https://txmongo.readthedocs.io
Apache License 2.0
338 stars 102 forks source link

"no SNI name sent" when connecting to a Mongo Atlas M0 Cluster #236

Open AdrienDS opened 6 years ago

AdrienDS commented 6 years ago

I am trying to connect to an Atlas M0 (Free Tier) Cluster with txmongo.

Following the instructions here: https://github.com/twisted/txmongo/issues/203 I created the connection pool with: db = yield ConnectionPool(url, ssl_context_factory=ssl.ClientContextFactory())

But I get the following error in the logs when trying to start my app:

2018-08-10 16:14:43-0400 [MongoProtocol (TLSMemoryBIOProtocol),client] 'TxMongo: Unknown error'
2018-08-10 16:14:44-0400 [MongoProtocol (TLSMemoryBIOProtocol),client] 'TxMongo: Unknown error'
2018-08-10 16:14:44-0400 [MongoProtocol (TLSMemoryBIOProtocol),client] 'TxMongo: Unknown error'
2018-08-10 16:14:44-0400 [MongoProtocol (TLSMemoryBIOProtocol),client] <twisted.internet.tcp.Connector object at 0x114b6ec18> will retry in 2 seconds

Here is more info about actual error (as seen in txmongo/connection.py l105):

config = {'ok': 0, 'errmsg': 'no SNI name sent, make sure using a MongoDB 3.4+ driver/shell.', 'code': 8000, 'codeName': 'AtlasError'}

Do you know how I can solve this ?

Thank you for your time.

Config:

MacOS 10.13.6
MongoDB shell version v3.6.6
Python 3.6.4
pymongo==3.7.1
txmongo==18.2.0
Twisted==18.7.0
AdrienDS commented 6 years ago

It happens only with shared clusters: we tried on an m2 cluster (shared as well) and had the same issue. https://docs.atlas.mongodb.com/reference/free-shared-limitations/

However after upgrading to a dedicated cluster (M10) the connection works fine.

I still think it would be great to have a fix for this to be able to connect to Mongo Atlas shared clusters.

IlyaSkriblovsky commented 6 years ago

Unfortunately I have no setup at hand on which I would be able to try, but I believe that you can specify server name like this:

from twisted.internet import ssl
ConnectionPool(url, ssl_context_factory=ssl.optionsForClientTLS('your.atlas.server.name'))
AdrienDS commented 6 years ago

@IlyaSkriblovsky Thanks, that solved the issue ! (ssl.optionsForClientTLS('your-atlas-server-name.mongodb.net')

I still think it might be good to handle this error to show more information to the user:

Gowee commented 3 years ago

Specifying the hostname via ssl.optionsForClientTLS manually does the trick. In my case, the cluster name is cluster0.foobar.mongodb.net, which resolves to cluster0-shard-00-00.foobar.mongodb.net, cluster0-shard-00-01.foobar.mongodb.net, and so on. I just pick one of them.

But I suppose it does not work all the time.

For a shared cluster (SNI required) with multiple nodes like Atlas, the hostnames of those nodes are given in the SRV record as well as updated from the ismaster query result. These hostnames are different and, technically, dynamic. I guess the reason why picking any one of them as the SNI does the trick is that Atlas accepts any identifiable subdomain on any nodes in the TLS layer for convenience (like Domain fronting), which should not be relied upon.

So I think it is still meaningful to let txmongo handles SNI itself instead.