jonhoo / rust-imap

IMAP client library for Rust
Apache License 2.0
477 stars 80 forks source link

Connection Lost + Slow IMAP Connection #259

Closed Divide-By-0 closed 1 year ago

Divide-By-0 commented 1 year ago

On my EC2 server, Rust IMAP takes about 3 minutes to initially connect to imap.gmail.com, but the SMTP connection happens instantly. Also, it frequently drops connection after maybe 5-10 more minutes with "Connection Lost". Any idea what might be causing this?

It stalls on the second line with port 993.

let tls = native_tls::TlsConnector::builder().build()?;
let client = imap::connect((domain_name, port), domain_name, &tls)?;

The specific library line it hangs on is

match TcpStream::connect(addr) {
jonhoo commented 1 year ago

That's truly bizarre — that's just a normal TCP connect with nothing special about it. This feels like some kind of configuration error for your network or firewall. Maybe DNS lookup is slow? Does it work if you try to connect using the IP directly?

Divide-By-0 commented 1 year ago

Hmm yeah I'm not sure. It works perfectly on my local laptop. On the ec2 server, nslookup imap.gmail.com completes immediately, openssl s_client -connect imap.gmail.com:993 hangs, and traceroute -p 993 imap.gmail.com seems to go slowly and hit the hop max. ip route seems fine.

$ nslookup imap.gmail.com
Server:     127.0.0.53
Address:    127.0.0.53#53

Non-authoritative answer:
Name:   imap.gmail.com
Address: 142.250.101.108
Name:   imap.gmail.com
Address: 142.250.101.109
Name:   imap.gmail.com
Address: 2607:f8b0:4023:c0b::6d
Name:   imap.gmail.com
Address: 2607:f8b0:4023:c0b::6c
$ traceroute -p 993 imap.gmail.com
traceroute to imap.gmail.com (142.250.101.108), 30 hops max, 60 byte packets
 1  * * *
 2  240.0.176.3 (240.0.176.3)  0.229 ms  0.221 ms *
 3  240.0.176.23 (240.0.176.23)  0.220 ms  0.212 ms *
 4  * 242.2.45.97 (242.2.45.97)  0.423 ms 242.2.44.193 (242.2.44.193)  0.519 ms
 5  52.93.47.89 (52.93.47.89)  2.611 ms 241.0.6.130 (241.0.6.130)  0.191 ms 241.0.6.128 (241.0.6.128)  0.399 ms
 6  52.93.237.248 (52.93.237.248)  2.632 ms 240.0.176.26 (240.0.176.26)  0.192 ms 54.240.242.66 (54.240.242.66)  1.713 ms
 7  242.2.45.97 (242.2.45.97)  0.420 ms 242.2.45.193 (242.2.45.193)  0.358 ms 15.230.28.68 (15.230.28.68)  2.360 ms
 8  52.93.237.211 (52.93.237.211)  1.464 ms 52.93.47.83 (52.93.47.83)  2.018 ms 74.125.118.78 (74.125.118.78)  1.811 ms
 9  * * *
10  * 15.230.28.16 (15.230.28.16)  1.438 ms *
11  * 74.125.51.220 (74.125.51.220)  3.735 ms 72.14.203.108 (72.14.203.108)  3.422 ms
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *
$ ip route
default via 172.31.0.1 dev ens5 proto dhcp src 172.31.7.227 metric 100 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 
172.31.0.0/20 dev ens5 proto kernel scope link src 172.31.7.227 metric 100 
172.31.0.1 dev ens5 proto dhcp scope link src 172.31.7.227 metric 100 
172.31.0.2 dev ens5 proto dhcp scope link src 172.31.7.227 metric 100 

The iptables seem open enough

$ sudo iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ufw-before-logging-input  all  --  anywhere             anywhere            
ufw-before-input  all  --  anywhere             anywhere            
ufw-after-input  all  --  anywhere             anywhere            
ufw-after-logging-input  all  --  anywhere             anywhere            
ufw-reject-input  all  --  anywhere             anywhere            
ufw-track-input  all  --  anywhere             anywhere            

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ufw-before-logging-forward  all  --  anywhere             anywhere            
ufw-before-forward  all  --  anywhere             anywhere            
ufw-after-forward  all  --  anywhere             anywhere            
ufw-after-logging-forward  all  --  anywhere             anywhere            
ufw-reject-forward  all  --  anywhere             anywhere            
ufw-track-forward  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ufw-before-logging-output  all  --  anywhere             anywhere            
ufw-before-output  all  --  anywhere             anywhere            
ufw-after-output  all  --  anywhere             anywhere            
ufw-after-logging-output  all  --  anywhere             anywhere            
ufw-reject-output  all  --  anywhere             anywhere            
ufw-track-output  all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imaps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imap2
...
Divide-By-0 commented 1 year ago

Waiting for the openssl connection gives me this:

$ openssl s_client -connect imap.gmail.com:993
CONNECTED(00000003)
depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1
verify return:1
depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
verify return:1
depth=0 CN = imap.gmail.com
verify return:1
---
Certificate chain
 0 s:CN = imap.gmail.com
   i:C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: RSA-SHA256
   v:NotBefore: Apr  3 08:23:54 2023 GMT; NotAfter: Jun 26 08:23:53 2023 GMT
 1 s:C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
   i:C = US, O = Google Trust Services LLC, CN = GTS Root R1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Aug 13 00:00:42 2020 GMT; NotAfter: Sep 30 00:00:42 2027 GMT
 2 s:C = US, O = Google Trust Services LLC, CN = GTS Root R1
   i:C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
   a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jun 19 00:00:42 2020 GMT; NotAfter: Jan 28 00:00:42 2028 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=CN = imap.gmail.com
issuer=C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 4292 bytes and written 396 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 9E7EBDE7DCBE92D7A995E3B619F512260FA6D66CE57986E3837B55F6633A6792
    Session-ID-ctx: 
    Resumption PSK: A1B98CB7AB0649AF38AAD9F17405E895BB29DF1A116383AF6F575514179904EE80882DEC4FBDF19401C181DFCF2DFC5A
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 172800 (seconds)
    TLS session ticket:
    0000 - 02 56 7e 61 b9 5a
...
    Start Time: 1682294873
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
* OK Gimap ready for requests from 54.<redacted> z5mb35023069oct
jonhoo commented 1 year ago

The fact that openssl s_client also hangs suggests this isn't actually a problem with the imap crate. Unfortunately I also don't have much of an idea of what else it can be, sorry!