1

There is big German email hoster (web.de) whose mail servers are not able to send mails to my self-hosted Postfix server. I found similar reports, but the published solutions always were misconfigured TLSA records. However, I am sure that my TLSA record is fine.

How do I fix the problem such that my Postfix server receives mails from those servers correctly?

  • Postfix version: 3.8.5
  • OpenSSL version: 3.0.13-r2

My Postfix logs:

May 08 12:05:37 server postfix/smtpd[90259]: initializing the server-side TLS engine
May 08 12:05:37 server postfix/smtpd[90259]: connect from mout.web.de[212.227.15.4]
May 08 12:05:38 server postfix/smtpd[90259]: setting up TLS connection from mout.web.de[212.227.15.4]
May 08 12:05:38 server postfix/smtpd[90259]: mout.web.de[212.227.15.4]: TLS cipher list "aNULL:-aNULL:HIGH:MEDIUM:!SEED:!IDEA:!3DES:!RC2:!RC4:!RC5:!kDH:!kECDH:!aDSS:!MD5:+RC4:@STRENGTH"
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:before SSL initialization
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:before SSL initialization
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:SSLv3/TLS read client hello
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:SSLv3/TLS write server hello
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:SSLv3/TLS write change cipher spec
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:TLSv1.3 write encrypted extensions
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:SSLv3/TLS write certificate
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:TLSv1.3 write server certificate verify
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:SSLv3/TLS write finished
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:TLSv1.3 early data
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:TLSv1.3 early data
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:SSLv3/TLS read finished
May 08 12:05:38 server postfix/smtpd[90259]: mout.web.de[212.227.15.4]: Issuing session ticket, key expiration: 1715164537
May 08 12:05:38 server postfix/smtpd[90259]: SSL_accept:SSLv3/TLS write session ticket
May 08 12:05:38 server postfix/smtpd[90259]: Anonymous TLS connection established from mout.web.de[212.227.15.4]: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (prime256v1) server-signature RSA-PSS (2048 bits) server-digest SHA256
May 08 12:05:38 server postfix/smtpd[90259]: SSL3 alert read:fatal:insufficient security
May 08 12:05:38 server postfix/smtpd[90259]: warning: TLS library problem: error:0A00042F:SSL routines::tlsv1 alert insufficient security:../openssl-3.0.13/ssl/record/rec_layer_s3.c:1590:SSL alert number 71:
May 08 12:05:38 server postfix/smtpd[90259]: lost connection after STARTTLS from mout.web.de[212.227.15.4]
May 08 12:05:38 server postfix/smtpd[90259]: disconnect from mout.web.de[212.227.15.4] ehlo=1 starttls=1 commands=2
May

I am not sure which side is reporting "insufficient security". My own side, i.e. Postfix/TLS server? Or the remote side, i.e. the web.de mail server which is the TLS client?

My server provides two Letsencrypt certificates:

  • one EC certificate,
  • one RSA certificate.

The relevant TLS directives from my Postfix main.cf:

# TLS PARAMETERS
#

smtpd_tls_chain_files =
  /etc/letsencrypt/live/server.my-domain.tld:smtps-ec/privkey.pem,
  /etc/letsencrypt/live/server.my-domain.tld:smtps-ec/fullchain.pem,
  /etc/letsencrypt/live/server.my-domain.tld:smtps-rsa/privkey.pem,
  /etc/letsencrypt/live/server.my-domain.tld:smtps-rsa/fullchain.pem
smtpd_tls_CApath              = /etc/ssl/certs
# note: for port 587, smtpd_tls_security_level is overwritten to `encrypt` in master.cf
smtpd_tls_security_level      = may
smtpd_tls_received_header     = yes
smtpd_tls_auth_only           = yes
smtpd_tls_ciphers             = medium
smtpd_tls_protocols           = >=TLSv1.2
smtpd_tls_mandatory_ciphers   = high
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_loglevel            = 0

smtp_tls_CApath              = /etc/ssl/certs
smtp_tls_security_level      = may
smtp_tls_note_starttls_offer = yes
smtp_tls_ciphers             = medium
smtp_tls_protocols           = >=TLSv1.2
smtp_tls_mandatory_ciphers   = high
smtp_tls_mandatory_protocols = >=TLSv1.2
smtp_tls_loglevel            = 0

In both cases, the trust anchor is "ISRG Root X1". My TLSA record is

$ dig TLSA _25._tcp.server.my-domain.tld.
_25._tcp.server.my-domain.tld.   12340 IN   CNAME   letsencrypt._dane.my-domain.tld.
letsencrypt._dane.my-domain.tld. 13104 IN   TLSA    0 1 1 0B9FA5A59EED715C26C1020C711B4F6EC42D58B0015E14337A39DAD3 01C5AFC3

Running SSL Scan against my own Postfix server yields:

# sslscan --verbose --starttls-smtp server.my-domain.tld:25
Version: 2.1.2-static
OpenSSL 3.0.12 24 Oct 2023

Some servers will fail to response to SSLv3 ciphers over STARTTLS
If your scan hangs, try using the --tlsall option

Testing SSL server server.my-domain.tld on port 25 using SNI name server.my-domain.tld

  SSL/TLS Protocols:
SSLv2     disabled
SSLv3     disabled
TLSv1.0   disabled
TLSv1.1   disabled
TLSv1.2   enabled
TLSv1.3   enabled

  TLS Fallback SCSV:
OpenSSL OpenSSL 3.0.12 24 Oct 2023 looks like version 0.9.8m or later; I will try SSL_OP to enable renegotiation
OpenSSL OpenSSL 3.0.12 24 Oct 2023 looks like version 0.9.8m or later; I will try SSL_OP to enable renegotiation
Server supports TLS Fallback SCSV

  TLS renegotiation:
OpenSSL OpenSSL 3.0.12 24 Oct 2023 looks like version 0.9.8m or later; I will try SSL_OP to enable renegotiation
use_unsafe_renegotiation_op
Session renegotiation not supported

  TLS Compression:
OpenSSL OpenSSL 3.0.12 24 Oct 2023 looks like version 0.9.8m or later; I will try SSL_OP to enable renegotiation
Compression disabled

  Heartbleed:
TLSv1.3 not vulnerable to heartbleed
TLSv1.2 not vulnerable to heartbleed

  Supported Server Cipher(s):
SSL_connect() returned: 1
Preferred TLSv1.3  128 bits  TLS_AES_128_GCM_SHA256        Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.3  256 bits  TLS_AES_256_GCM_SHA384        Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.3  256 bits  TLS_CHACHA20_POLY1305_SHA256  Curve 25519 DHE 253
SSL_connect() returned: -1
SSL_get_current_cipher() returned NULL; this indicates that the server did not choose a cipher from our list (TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256)
SSL_connect() returned: 1
Preferred TLSv1.2  256 bits  ECDHE-ECDSA-AES256-GCM-SHA384 Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-GCM-SHA384     DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-CHACHA20-POLY1305 Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-RSA-CHACHA20-POLY1305   Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-CHACHA20-POLY1305     DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-CCM8       Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-CCM        Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-CCM8           DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-CCM            DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-ARIA256-GCM-SHA384 Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ARIA256-GCM-SHA384      Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-ARIA256-GCM-SHA384    DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ADH-AES256-GCM-SHA384         DHE 3072 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-GCM-SHA256 Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-GCM-SHA256     DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-CCM8       Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-CCM        Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-CCM8           DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-CCM            DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-ARIA128-GCM-SHA256 Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ARIA128-GCM-SHA256      Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-ARIA128-GCM-SHA256    DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ADH-AES128-GCM-SHA256         DHE 1024 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-SHA384     Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA384       Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-SHA256         DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-CAMELLIA256-SHA384 Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-RSA-CAMELLIA256-SHA384  Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-CAMELLIA256-SHA256    DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ADH-AES256-SHA256             DHE 3072 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ADH-CAMELLIA256-SHA256        DHE 3072 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-SHA256     Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA256       Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-SHA256         DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-CAMELLIA128-SHA256 Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-RSA-CAMELLIA128-SHA256  Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-CAMELLIA128-SHA256    DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ADH-AES128-SHA256             DHE 1024 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ADH-CAMELLIA128-SHA256        DHE 1024 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-SHA        Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA          Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-SHA            DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  DHE-RSA-CAMELLIA256-SHA       DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  AECDH-AES256-SHA              Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ADH-AES256-SHA                DHE 3072 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ADH-CAMELLIA256-SHA           DHE 3072 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-SHA        Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA          Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-SHA            DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  DHE-RSA-CAMELLIA128-SHA       DHE 2048 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  AECDH-AES128-SHA              Curve 25519 DHE 253
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ADH-AES128-SHA                DHE 1024 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ADH-CAMELLIA128-SHA           DHE 1024 bits
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  AES256-GCM-SHA384            
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  AES256-CCM8                  
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  AES256-CCM                   
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  ARIA256-GCM-SHA384           
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  AES128-GCM-SHA256            
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  AES128-CCM8                  
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  AES128-CCM                   
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  ARIA128-GCM-SHA256           
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  AES256-SHA256                
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  CAMELLIA256-SHA256           
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  AES128-SHA256                
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  CAMELLIA128-SHA256           
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  AES256-SHA                   
SSL_connect() returned: 1
Accepted  TLSv1.2  256 bits  CAMELLIA256-SHA              
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  AES128-SHA                   
SSL_connect() returned: 1
Accepted  TLSv1.2  128 bits  CAMELLIA128-SHA              
SSL_connect() returned: -1
SSL_get_current_cipher() returned NULL; this indicates that the server did not choose a cipher from our list (ALL:COMPLEMENTOFALL:!ECDHE-ECDSA-AES256-GCM-SHA384:!ECDHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES256-GCM-SHA384:!ECDHE-ECDSA-CHACHA20-POLY1305:!ECDHE-RSA-CHACHA20-POLY1305:!DHE-RSA-CHACHA20-POLY1305:!ECDHE-ECDSA-AES256-CCM8:!ECDHE-ECDSA-AES256-CCM:!DHE-RSA-AES256-CCM8:!DHE-RSA-AES256-CCM:!ECDHE-ECDSA-ARIA256-GCM-SHA384:!ECDHE-ARIA256-GCM-SHA384:!DHE-RSA-ARIA256-GCM-SHA384:!ADH-AES256-GCM-SHA384:!ECDHE-ECDSA-AES128-GCM-SHA256:!ECDHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES128-GCM-SHA256:!ECDHE-ECDSA-AES128-CCM8:!ECDHE-ECDSA-AES128-CCM:!DHE-RSA-AES128-CCM8:!DHE-RSA-AES128-CCM:!ECDHE-ECDSA-ARIA128-GCM-SHA256:!ECDHE-ARIA128-GCM-SHA256:!DHE-RSA-ARIA128-GCM-SHA256:!ADH-AES128-GCM-SHA256:!ECDHE-ECDSA-AES256-SHA384:!ECDHE-RSA-AES256-SHA384:!DHE-RSA-AES256-SHA256:!ECDHE-ECDSA-CAMELLIA256-SHA384:!ECDHE-RSA-CAMELLIA256-SHA384:!DHE-RSA-CAMELLIA256-SHA256:!ADH-AES256-SHA256:!ADH-CAMELLIA256-SHA256:!ECDHE-ECDSA-AES128-SHA256:!ECDHE-RSA-AES128-SHA256:!DHE-RSA-AES128-SHA256:!ECDHE-ECDSA-CAMELLIA128-SHA256:!ECDHE-RSA-CAMELLIA128-SHA256:!DHE-RSA-CAMELLIA128-SHA256:!ADH-AES128-SHA256:!ADH-CAMELLIA128-SHA256:!ECDHE-ECDSA-AES256-SHA:!ECDHE-RSA-AES256-SHA:!DHE-RSA-AES256-SHA:!DHE-RSA-CAMELLIA256-SHA:!AECDH-AES256-SHA:!ADH-AES256-SHA:!ADH-CAMELLIA256-SHA:!ECDHE-ECDSA-AES128-SHA:!ECDHE-RSA-AES128-SHA:!DHE-RSA-AES128-SHA:!DHE-RSA-CAMELLIA128-SHA:!AECDH-AES128-SHA:!ADH-AES128-SHA:!ADH-CAMELLIA128-SHA:!AES256-GCM-SHA384:!AES256-CCM8:!AES256-CCM:!ARIA256-GCM-SHA384:!AES128-GCM-SHA256:!AES128-CCM8:!AES128-CCM:!ARIA128-GCM-SHA256:!AES256-SHA256:!CAMELLIA256-SHA256:!AES128-SHA256:!CAMELLIA128-SHA256:!AES256-SHA:!CAMELLIA256-SHA:!AES128-SHA:!CAMELLIA128-SHA)

  Server Key Exchange Group(s):
TLSv1.3  128 bits  secp256r1 (NIST P-256)
TLSv1.3  192 bits  secp384r1 (NIST P-384)
TLSv1.3  260 bits  secp521r1 (NIST P-521)
TLSv1.3  128 bits  x25519
TLSv1.3  224 bits  x448
TLSv1.3  112 bits  ffdhe2048
TLSv1.3  128 bits  ffdhe3072
TLSv1.2  128 bits  secp256r1 (NIST P-256)
TLSv1.2  192 bits  secp384r1 (NIST P-384)
TLSv1.2  260 bits  secp521r1 (NIST P-521)
TLSv1.2  128 bits  x25519
TLSv1.2  224 bits  x448

  SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
ECC Curve Name:      secp384r1
ECC Key Strength:    192

Subject:  server.my-domain.tld
Altnames: DNS:server.my-domain.tld
Issuer:   R3

Not valid before: Mar 11 19:44:07 2024 GMT
Not valid after:  Jun  9 19:44:06 2024 GMT

Any ideas why the web.de mail server do not send mails to my Postfix server?

1
  • Your system is receiving the alert, so it is the peer (web.de) that is dissatisfied with something, but I don't know (or have access to) that system so I can't directly help. PS: your server has two certs, EC(DSA) and RSA, with matching privatekeys, but it provides only one on a given connection. Although as you say all LE certs currently anchor in X1. Unless maybe you have kept and still send LE's now-obsolete 'compatibility' chain with the bridge to DST X3 and that confuses the peer -- but then I would expect to see 45 cert expired, 46 cert unknown, or 48 unknown CA. Good luck. Commented May 9 at 4:19

1 Answer 1

1

I found the solution. It seems that web.de (and gmx.de) only supports TLSA certificate usage 2 (DANE-TA) and 3 (DANE-EE), see RFC 6698, sec. 2.1.1. Hence, the TLSA record must be

letsencrypt._dane.my-domain.tld.  <TTL>  IN  TLSA  2 <selector> <match> <value>

or

letsencrypt._dane.my-domain.tld.  <TTL>  IN  TLSA  3 <selector> <match> <value>

RFC 7672, sec. 3.1.1 states the DANE for MTA-to-MTA communication should not use TLSA certificate usage 0 (PKIX-TA) and 1 (PKIX-EE) as it might happen that the referred TA is not trusted (or known) to the remote MTA. Strangely, web.de has installed Letsencrypt "ISRG Root X1" and trusts it as a TA, because web.de is able to establish a TLS connection when I disable TLSA completely. Hence, it seems that web.de explicitly forbids certificate usage 0 or 1.

Due to its longer validity compared to end-entity certificates, I decided to declare Letsencrypt's intermediate certificate "R3" as DANE-TA and added the TLSA record

letsencrypt._dane.my-domain.tld.  <TTL>  IN  TLSA  2 1 1 8D02536C887482BC34FF54E41D2BA659BF85B341A0A20AFADB5813DCFBCF286D

in addition to the already existing TLSA record

letsencrypt._dane.my-domain.tld.  <TTL>  IN  TLSA  0 1 1 0B9FA5A59EED715C26C1020C711B4F6EC42D58B0015E14337A39DAD301C5AFC3

Notes:

  • Having multiple TLSA records is fine. If at least one TLSA record matches and is valid, the relying party accepts.
  • If one uses certificate usage 2 (DANE-TA), then the subscriber must send the certificate which is the DANA-TA along the certification path. As in my case that certificate is also a PKIX intermediate, Postfix sends it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .