IMAP, SMTP failing because of bad certificate

Issue #691 new
Greg created an issue

I’m sorry for the duplicate issue, feel free to close this in favor of Haraka Lets Encrypt Fullchain.pem, I just think this issue deserves a clearer title and description because of its severity.

The problem is that all of a sudden the Let’s Encrypt certificate being sent back by Poste no longer contains the intermediate Let’s Encrypt certificate along with it. This is causing various client software to fail, including sending email via msmtp, and receiving email via laravel-imap.

The following shows the problem:

-> % openssl s_client -connect mail.website.com:443
CONNECTED(00000005)
depth=0 CN = mail.website.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = mail.website.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/CN=mail.website.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
Server certificate
-----BEGIN CERTIFICATE-----
    [NOTE: ___certificate removed__]
-----END CERTIFICATE-----
subject=/CN=mail.website.com
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Server Temp Key: ECDH, X25519, 253 bits
---
SSL handshake has read 2551 bytes and written 293 bytes
---
New, TLSv1/SSLv3, 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: XXX
    Session-ID-ctx: 
    Master-Key: XXX
    TLS session ticket lifetime hint: 600 (seconds)
    TLS session ticket:
    0000 - bf 72 59 09 8d 55 c7 3b-04 f3 ac 42 ce 50 e4 d6   .rY..U.;...B.P..
    0010 - 8f d8 1d d0 43 d9 88 19-8b 04 ed 1e 34 75 59 9f   ....C.......4uY.
    0020 - 57 c5 11 a9 80 25 c6 2b-fe de a7 7a 75 a2 72 84   W....%.+...zu.r.
    0030 - 99 64 d4 18 58 f4 77 5e-c7 35 6d 1c 34 89 09 58   .d..X.w^.5m.4..X
    0040 - 18 be 41 b4 e3 95 1a 78-b6 15 29 30 26 f4 ec 30   ..A....x..)0&..0
    0050 - ba cc 7b 4a ff 29 ec 87-cf 3a b8 ad 6e ba 69 71   ..{J.)...:..n.iq
    0060 - 7b 3f be fa 0e 9a 77 4d-fc 18 9f 6c 6b d2 ac 81   {?....wM...lk...
    0070 - 23 d9 b9 92 32 16 8b a6-d9 9b 32 dd b7 79 ba c4   #...2.....2..y..
    0080 - 02 c7 dd 8c a1 d9 10 e5-ed af 08 b4 8d 0e 61 72   ..............ar
    0090 - 3c 3c f9 46 2c 50 3e 44-5f 9c 10 ea 27 aa 60 04   <<.F,P>D_...'.`.
    00a0 - 5c 92 fd a7 ec f5 1b fa-9d 4f b1 af 1b 3f 0e 23   \........O...?.#

    Start Time: 1569733035
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
closed

This is what the output of openssl s_client should look like when Let’s Encrypt is properly sending the Intermediate Certificate:

-> % openssl s_client -connect example.org:443         
CONNECTED(00000005)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = blog.example.org
verify return:1
---
Certificate chain
 0 s:/CN=blog.example.org
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
  [ NOTE: certificate removed ]
-----END CERTIFICATE-----
subject=/CN=blog.example.org
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Server Temp Key: DH, 2048 bits
---
SSL handshake has read 4178 bytes and written 518 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-GCM-SHA256
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES128-GCM-SHA256
    Session-ID: XXX
    Session-ID-ctx: 
    Master-Key: XXX
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 7d e6 08 5c 5e fc 05 48-50 0b c1 a8 5d 73 98 35   }..\^..HP...]s.5
    0010 - 90 e0 1c 42 73 f7 1a b6-ea 8c 3a ce 53 1a 29 14   ...Bs.....:.S.).
    0020 - c7 60 59 2a fb 27 75 13-de 84 58 53 2d 73 4d 03   .`Y*.'u...XS-sM.
    0030 - 81 85 c1 dc 62 e6 91 a1-a5 be 91 35 f9 92 25 63   ....b......5..%c
    0040 - 15 c1 67 27 de db 94 6a-3d 9a 98 98 bf f5 0d 88   ..g'...j=.......
    0050 - 39 be 1f 59 1f 59 a2 e7-87 72 1f 2c e4 84 f8 81   9..Y.Y...r.,....
    0060 - 02 73 30 12 ce 3f fd 94-5f 58 3e 9d d9 63 e3 2f   .s0..?.._X>..c./
    0070 - 34 46 3f 32 e2 ad b3 27-96 9f 9d 0b 7d cf 90 29   4F?2...'....}..)
    0080 - 42 1c 0c 16 f7 cf 9e 7d-54 ba 10 33 49 77 f2 a0   B......}T..3Iw..
    0090 - b7 c4 39 b8 9e 22 cb a8-2e 22 e7 42 49 58 7e 93   ..9.."...".BIX~.
    00a0 - bc db ec ee 8e ef dd c6-a3 af b5 c2 e1 f1 77 9f   ..............w.

    Start Time: 1569732364
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
closed

Comments (8)

  1. Greg reporter

    As a workaround/fix, I decided to implement copying in the certificate from my primary let’s encrypt container.

    I disabled Poste’s Let’s Encrypt stuff in the UI, and now simply use docker cp to copy in the 3 files:

    nginx:/etc/letsencrypt/live/<domain>/chain.pem -> vol/poste/_override/data/ssl/ca.crt
    nginx:/etc/letsencrypt/live/<domain>/cert.pem -> vol/poste/_override/data/ssl/server.crt
    nginx:/etc/letsencrypt/live/<domain>/privkey.pem -> vol/poste/_override/data/ssl/server.key
    

    I make sure to do a few other things:

    1. Set HTTPS=OFF to disable HTTPS in poste
    2. proxy_pass from my nginx container to port 80 in the poste container, in a setup similar but not identical to this
    3. Make sure to restart the poste container each time the renewed certificates are copied over

    Obviously this doesn’t fix the underlying bug, but it works as a complicated workaround that also has the benefit of giving me more control over SSL certificate provenance.

  2. SB

    Thank you both for the fixes, however for anyone else there is already an update which resolves this issue.

  3. yannikh

    There is? I just updated the image like an hour ago and when I try to update again…:

    $ docker pull analogic/poste.io                         
    Using default tag: latest
    latest: Pulling from analogic/poste.io
    Digest: sha256:287e4641f2e8733617c0c37ae08840dd2c83f40abf40cd77d430912784c96458
    Status: Image is up to date for analogic/poste.io:latest
    

    And the issue was still present right after the update. Is there a certain job one needs to await after the update? Like the next LE-Renewal?

  4. SB

    You need to go into settings and re-issue the certificate for it to fix.

    System Settings, TLS Certificate, Change Certificate Settings / Save Changes

  5. scippio

    @SB thanks… new version working. le:renew command not… but when I agree invalid certificate and log in into admin and click save in TLS certificates… it generated new with fullchain etc… a it’s ok now.

  6. Log in to comment