MONGO_STRING='mongodb://user:password@host_1:27017,host_2:27017,host_3:27017/?authSource=admin&replicaSet=xxxx' ATLAS_STRING='mongodb://user:password@host_atlas:1024,host_atlas:1025,host_atlas:1026/?authSource=admin&replicaSet=xxxx&ssl=true'I can connect successfully on the shell with both:
> mongo "$MONGO_STRING" # OK.1 (I'm in and I can operate on db & collections)
> mongo "$ATLAS_STRING" # OK.2 ( " " ...)
Just a few differences between the 2 strings though:
1. For MONGO: there are 3 distinct hosts listening on the same port (default 27017) and no ssl
2. For ATLAS: there is only 1 hostname, different ports and ssl on.
The single host name actually maps 3 distinct hosts, as I can see if I nslookup it
host_atlas canonical name = ..........
Name: host_1
Address: 10.65.4.239
Name: host_2
Address: 10.65.76.221
Name: host_3
Address: 10.65.154.200
I can connect also with a small Perl script which uses MongoDB
#file: test.Mongo.pl use strict; use warnings; use MongoDB; # also loads MongoDB::MongoClient use Data::Dumper; my $connect_string=$ARGV[0]; my $client = MongoDB::MongoClient->new({'host' => $connect_string}); my $doc = $client->get_database('mydb')->get_collection('mycoll')- +>find_one(); $client->disconnect; print Dumper $doc;
> perl test.Mongo.pl "$MONGO_STRING" # OK.3
> perl test.Mongo.pl "$ATLAS_STRING" # OK.4
I then try to use Mango, the driver under Mojolicious with the following script:
#file: test.Mango.pl use strict; use warnings; use Mango; use feature 'state'; use Data::Dumper; my $connect_string=$ARGV[0]; sub mango { state $m = Mango->new($connect_string)} my $doc = mango->db('mydb')->collection('mycoll')->find_one(); print Dumper $doc;
> perl test.Mango.pl "$MONGO_STRING" # OK.5
> perl test.Mango.pl "$ATLAS_STRING" # ERROR: Premature connection close at /var/..../local/lib/perl5/Mango/Cursor/Query.pm line 112.
So I have one wrong scenario out of 6. The scenario with ssl=true via Mojolicious, internally managed via IO::Socket::SSL.
Running the last 2 cases with> perl test.Mango.pl "$MONGO_STRING" #OK.5 -- Emit connect in Mojo::IOLoop::Client (1) -- Emit write in Mojo::IOLoop::Stream (0) -- Emit drain in Mojo::IOLoop::Stream (0) -- Emit read in Mojo::IOLoop::Stream (1) -- Emit write in Mojo::IOLoop::Stream (0) -- Emit drain in Mojo::IOLoop::Stream (0) -- Emit read in Mojo::IOLoop::Stream (1) -- Emit write in Mojo::IOLoop::Stream (0) -- Emit drain in Mojo::IOLoop::Stream (0) -- Emit read in Mojo::IOLoop::Stream (1) -- Emit write in Mojo::IOLoop::Stream (0) -- Emit drain in Mojo::IOLoop::Stream (0) -- Emit read in Mojo::IOLoop::Stream (1) -- Emit connection in Mango (0) -- Emit finish in Mojo::IOLoop::Delay (1) -- Emit write in Mojo::IOLoop::Stream (0) -- Emit drain in Mojo::IOLoop::Stream (0) -- Emit read in Mojo::IOLoop::Stream (1) $VAR1 = { '_id' => bless( { 'oid' => '_L+.\'' }, 'Mango::BSON::ObjectID' ), ..... };
Debugging I have this point> perl test.Mango.pl "$ATLAS_STRING" # ERROR: Premature connec +tion close at /var/..../local/lib/perl5/Mango/Cursor/Query.pm line 11 +2. -- Emit connect in Mojo::IOLoop::Client (1) -- Emit write in Mojo::IOLoop::Stream (0) -- Emit drain in Mojo::IOLoop::Stream (0) -- Emit close in Mojo::IOLoop::Stream (2) Premature connection close at /var/..../local/lib/perl5/Mango/Cursor/ +Query.pm line 112.
Mojo::IOLoop::Stream::_read(/var/..../local/lib/perl5/Mojo/IOLoop/Stre +am.pm:103): 103: return if $! == EAGAIN || $! == EINTR || $! == EWOULDBLOCK; DB<8> x $! 0 'Connection reset by peer'
Any advice about what might inhibit the last scenario to keep the connection alive is very welcome.
Here some info about the server certificate in case they might be useful:
> echo | openssl s_client -servername host_atlas -connect host_atlas:1024 2>/dev/null
CONNECTED(00000006)
---
Certificate chain
0 s:CN = *.xxxx.mongodb.net
i:C = US, O = Let's Encrypt, CN = R3
1 s:C = US, O = Let's Encrypt, CN = R3
i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
---
Server certificate
-----BEGIN CERTIFICATE-----
EwJSMzAeFw0yMjAyMDYwNTE0MTdaFw0yMjA1MDcwNTE0MTZaMB4xHDAaBgNVBAMM
.....
YAgPUAnXVevMMyoFDuMs4kBwyLVDKwJKSl==
-----END CERTIFICATE-----
subject=CN = *.xxxx.mongodb.net
issuer=C = US, O = Let's Encrypt, CN = R3
---
Acceptable client certificate CA names
CN = 51275a38f58fe700ac6c85a8, OU = Atlas, O = MongoDB Inc
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4031 bytes and written 472 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 6AA99AF2921EB04DCED95A84108D4C019081F49A7BB4174B901EF6BBBDB64E54
Session-ID-ctx:
Master-Key: 57EF1F3C....64DC81D
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 55 59 6f 27 90 00 ee 98-25 75 ef c6 46 a3 b1 ab UYo'....%u..F...
....
00b0 - 8d 9b cd 1b 35 bf f2 22-77 70 0c ee 01 36 a3 b0 ....5.."wp...6..
Start Time: 1646263624
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
---
Thank you.
my %extra; $extra{replica_set_name} = 'xxxx'; $extra{tls} = 1; #Note, it's "tls" (not "ssl" like it would be +in the connection string) sub mango { state $m = Mango->new($connect_string, %extra);}
In reply to Mojolicious connection to Atlas ssl cluster fails: "Premature connection close" by jjmoka
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |