Help, let'sencrypt does not work for Mail

I nailed it down now.

You say in

The behavior that causes this incompatibility was fixed over 4 years ago with the release of OpenSSL 1.1.0.

That is wrong. It was not fixed.

Or, more specifically, it was fixed only for the simple case of one-sided authentication (like it happens usually in web servers), but not for the case of mutual authentication (like it commonly happens with smtp).

You can reproduce this with openssl s_client. Do the following:

  1. Have a mailserver running with Let'sEncrypt certificate installed. This certificate can be obtained with --preferred-chain "ISRG Root X1" so it does not contain the offending intermediate.

  2. Get yourself another (or the same) Let'sEncrypt certificate, this time with the complete default fullchain. And get yourself the two root ca certs in question.

It should look like this then:

# ls -l
total 45
drwxr-xr-x  2 root  wheel     6 Apr 29 17:44 CADIR
-rw-r--r--  1 root  wheel  5973 Apr 29 16:08 cacert.pem
-rw-r--r--  1 root  wheel  2224 Apr 29 18:01 host.cert
-rw-------  1 root  wheel  3272 Apr 29 17:50 host.key
# ls -l CADIR/
total 13
lrwxr-xr-x  1 root  wheel    18 Apr 29 17:18 2e5ac55d.0 -> DST_Root_CA_X3.pem
lrwxr-xr-x  1 root  wheel    16 Apr 29 17:18 4042bcee.0 -> ISRG_Root_X1.pem
-rw-r--r--  1 root  wheel  4665 Apr 29 17:14 DST_Root_CA_X3.pem
-rw-r--r--  1 root  wheel  7461 Apr 29 17:14 ISRG_Root_X1.pem
  1. run the s_client in mutual authentication mode:

# openssl s_client -connect flowm.daemon.contact:25 -starttls smtp -CAfile cacert.pem -chainCAfile cacert.pem -key host.key -cert host.cert -CApath CADIR -chainCApath CADIR

This does now nicely verify on the server. But on the client (where the openssl s_client is running) it looks like this:

depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:1
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
notAfter=Sep 30 14:01:15 2021 GMT
verify return:1
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
notAfter=Sep 30 18:14:03 2024 GMT
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
notAfter=Sep 15 16:00:00 2025 GMT
verify return:1
depth=0 CN = moon.daemon.contact
notAfter=Jun 20 05:04:23 2022 GMT
verify return:1
[etc.etc.]

SSL handshake has read 5744 bytes and written 6530 bytes
Verification error: certificate has expired
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 4096 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 10 (certificate has expired)
---
250 HELP
---
Post-Handshake New Session Ticket arrived:
[etc. etc.]

    Start Time: 1651248347
    Timeout   : 7200 (sec)
    Verify return code: 10 (certificate has expired)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
[etc. etc.]

    Start Time: 1651248347
    Timeout   : 7200 (sec)
    Verify return code: 10 (certificate has expired)
    Extended master secret: no
    Max Early Data: 0
---