Postfix issues with expired certificate on port 465

When sending a letter in Mozilla Thunderbird, I received a message that "mail.kr-labs.com.ua:465 does not have a valid certificate". But the certificate was updated with certbot:

sudo certbot certificates
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: mail.kr-labs.com.ua
    Serial Number: 351a8b4a473ad60fe5457f369ac13e34f3e
    Key Type: RSA
    Domains: mail.kr-labs.com.ua
    Expiry Date: 2025-05-14 16:36:46+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/mail.kr-labs.com.ua/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/mail.kr-labs.com.ua/privkey.pem

Certbot version: certbot 1.11.0

Also i ran this commands for analysis:

echo | openssl s_client -connect mail.kr-labs.com.ua:443 2>/dev/null | openssl x509 -noout -dates
notBefore=Feb 13 16:36:47 2025 GMT
notAfter=May 14 16:36:46 2025 GMT
echo | openssl s_client -connect mail.kr-labs.com.ua:465 2>/dev/null | openssl x509 -noout -dates
notBefore=Nov  5 05:51:30 2024 GMT
notAfter=Feb  3 05:51:29 2025 GMT

The same output about "expired certificate" displaying OpenSSL:

openssl s_client -connect mail.kr-labs.com.ua:465 -crlf -quiet
openssl s_client -connect mail.kr-labs.com.ua:465 -showcerts

Postfix on port 465 is stubbornly issuing the previous expired certificate, although /etc/postfix/main.cf contain locations of the certificates provided by LetsEncrypt. I am completely confused. Is this a bug, or is it an error on my servers side?

My os and web server: CentOS 7, OpenLiteSpeed 1.8.2

Postfix should pick up the new certificate even without reloading it, but did you try the postfix reload command already?

1 Like

In logs Postfix:

Feb 14 09:17:43 kr-labs postfix/anvil[993961]: warning: /etc/postfix/main.cf, line 104: overriding earlier entry: tls_server_sni_maps=hash:/etc/postfix/sni_map
....
Feb 14 09:14:18 kr-labs postfix/smtps/smtpd[993730]: warning: TLS library problem: error:14094415:SSL routines:ssl3_read_bytes:sslv3 alert certificate expired:s3_pkt.c:1493:SSL alert number 45:

Yes, of course, i already reloading and restarting postfix many times. But, maybe i dont do this immediately after certbot renew...

You'd be surprised how often this is the solution here on this Community. Please mention this kind of information in the future :slight_smile:

Can you show the postconf -n output? And relevant files such as /etc/postfix/sni_map?

1 Like

The problem is with SNI.... But why - I can't give an exact answer yet...

I just commented on the line #tls_server_sni_maps = hash:/etc/postfix/sni_map and OpenSSL saw a valid certificate:

openssl s_client -connect mail.kr-labs.com.ua:465 -servername mail.kr-labs.com.ua -showcerts
CONNECTED(00000003)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R11
verify return:1
depth=0 CN = mail.kr-labs.com.ua
verify return:1
---
Certificate chain
 0 s:CN = mail.kr-labs.com.ua
   i:C = US, O = Let's Encrypt, CN = R11
   a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
   v:NotBefore: Feb 13 16:36:47 2025 GMT; NotAfter: May 14 16:36:46 2025 GMT

Now I'm going to figure out where the configuration error was made in SNI. Although, up to a certain point, everything worked fine with the old configuration.

Complete SNI (Multiple TLS/SSL domain) POSTFIX Configuration

  1. check all certificates, that they will be valid:

sudo certbot certificates

also check ways, that will be valid too.

  1. check valid tls/ssl configuration for multiple domains:

nano /etc/postfix/main.cf

and add:

smtpd_tls_chain_files =
        /etc/letsencrypt/live/mail.primarydomain.com/privkey.pem,
        /etc/letsencrypt/live/mail.primarydomain.com/fullchain.pem
tls_server_sni_maps = hash:/etc/postfix/vmail_ssl.map
smtpd_use_tls = yes
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = TLSv1.2, TLSv1.3
smtpd_tls_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, RC4, 3DES
smtp_tls_security_level = encrypt
  1. need create SNI map file:

nano /etc/postfix/vmail_ssl.map

and add:

mail.primarydomain.com /etc/letsencrypt/live/mail.primarydomain.com/privkey.pem /etc/letsencrypt/live/mail.primarydomain.com/fullchain.pem
mail.secondarydomain.com /etc/letsencrypt/live/mail.secondarydomain.com/privkey.pem /etc/letsencrypt/live/mail.secondarydomain.com/fullchain.pem
  1. Postmap SNI:

postmap -F hash:/etc/postfix/vmail_ssl.map

if will be any errors - check main.cf.

  1. Restart Posrfix service:

systemctl restart postfix

  1. Test your TLS/SSL mail server connection via OpenSSL:
openssl s_client -connect mail.primarydomain.com:465 -showcerts
openssl s_client -connect mail.secondarydomain.com:465 -showcerts
  1. Open your mail client, for example Mozilla Thunderbird and sending mails.

PROFIT

All works perfectly. I liked puzzles.

Recommendation/Lesson: After every CERTBOT RENEW need check Postfix configuration, in particular the SNI map.

1 Like

Hm, thank you for the guide. Most helpful for future readers :slight_smile:

However, I still don't understand what went wrong with your Postfix configuration when Certbot renewed the cert(s). Did the SNI mapping differ than what was expected? Is a postmap -F required every time one renews a cert? Does any Postfix command be added to a --deploy-hook so it fixes Postfix every time a cert gets renewed? :thinking:

(I don't use the SNI mapping personal, so I don't have experience with it.)

2 Likes
  1. Main reason - some inaccuracies in Postfix configuration, in particular SNI configuration. Because, all problems disappeared after the SNI was correctly configured.

What i did?

Instead:

smtpd_tls_cert_file = 
smtpd_tls_key_file =

Added one:

smtpd_tls_chain_files =
        /etc/letsencrypt/live/mail.primarydomain.com/privkey.pem,
       /etc/letsencrypt/live/mail.primarydomain.com/fullchain.pem

Also destroed all old sni_maps files in /etc/postfix and created one new - vmail_ssl.map, put this in /etc/posftix/main.cf:

tls_server_sni_maps = hash:/etc/postfix/vmail_ssl.map

  1. Second reason - failure to comply with certain rules for updating SSL certificates in Postfix.
  • Before start CERTBOT RENEW i dont stopped Postfix service.
  • After CERTBOR RENEW i dont update SNI: postmap -F hash:/etc/postfix/vmail_ssl.map (!)
  • Dont restarting/reloading Postfix after CERTBOT RENEW certificates:
    systemctl reload postfix && systemctl restart postfix

And I think, yes a hook is needed here - for those who want automatic process. And I have to research this further.

Why did this happen only now? It is possible that no one has sent outgoing emails since February 5, when the old LE SSL expired.

Here I found a discussion of a similar problem - "Postfix doesn't get the new certificates": Multiple domains (w/ SSL Cert & DKIM for each) · Issue #283 · LukeSmithxyz/emailwiz · GitHub

One of the hooks that was used as a solution:

# Add deploy hook for certbot renewals to apply to Postfix 
# Create the reload-postfix.sh file
echo '#!/bin/bash' > /etc/letsencrypt/renewal-hooks/deploy/reload-postfix.sh
echo '' >> /etc/letsencrypt/renewal-hooks/deploy/reload-postfix.sh
# Add the desired commands
echo 'postmap -F /etc/postfix/vmail_ssl.map' >> /etc/letsencrypt/renewal-hooks/deploy/reload-postfix.sh
echo 'systemctl restart postfix && systemctl restart dovecot && systemctl restart opendkim' >> /etc/letsencrypt/renewal-hooks/deploy/reload-postfix.sh
# Make the script executable
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-postfix.sh
echo "Script 'reload-postfix.sh' has been created and configured."

In fact, this is the same as I emphasized above. IMMEDIATELY after receiving the certificates, you need to perform a COMPREHENSIVE UPDATE in Postfix itself, and most importantly - SNI MAP. And then there will be no such problems).

How create deploy-hook Certbot for automatic update SSL in Postfix?

  1. Create hook script in LE renewal-hooks directory:

sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-postfix.sh

and add:

#!/bin/bash
# Deploy hook for Certbot: updating SNI and restart Postfix-Dovecot

postmap -F /etc/postfix/vmail_ssl.map
systemctl restart postfix && systemctl restart dovecot && systemctl restart opendkim

# add info in log
echo "$(date): Certbot renew hook: Postfix, Dovecot та OpenDKIM was restarted." >> /var/log/letsencrypt/renew-hook.log
  1. Make file executable:

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-postfix.sh

How it works?

Certbot automatically executes scripts placed in the directory /etc/letsencrypt/renewal-hooks/deploy/ after the certificates are successfully renewed.

You can verify that Certbot is successfully running these scripts by viewing the Certbot log files (if configured) or by adding logging to the script itself (as in the example with writing the date to /var/log/letsencrypt/renew-hook.log).

Thus, you do not need to manually run this hook - it will be executed by Certbot during the renew process.

More info: User Guide — Certbot 3.2.0 documentation

Unlike most of the hashed maps, the contents of /etc/postfix/vmail_ssl.map are determined by reading the contents of a file, rather than the file being reread dynamically. That file must be reread and the "*.db" file must be recreated when contents (your certificate) change. Using the deploy hook is a decent way to handle that problem.

5 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.