Certbot, Dovecot, Postfix, certificate renewal issue


#1

Recently I had an issue where certbot failed to renew my certificate due to a misconfiguration in my Apache config file. I managed to fix the issue and get the certificate renewed, and everything worked fine as far as my webserver is concerned. However I also use the same certificate in both Dovecot and Postfix and my mail clients all started complaining about an expired certificate.

Eventually I realized that restarting those services fixed the problem. I’m not sure about whether this is related to Dovecot or Postfix because I restarted both at once and the issue disappeared. But somehow it seems that one (or both) of those services possibly caches the certificate.

Does anyone know for sure which of these would have been the culprit? I was thinking maybe I need to restart those services when a renewal takes place but can that be done as part of the certbot renewal process? Or is there possibly a way to turn off certificate caching? Any help here is appreciated.

Ubuntu 18.04.1
Certbot 0.26.1
Postfix 3.3.0
Dovecot 2.2.33.2


#2

Perhaps you have changed the path of your certificates. Check this older answer:

Something like

# file /etc/postfix/main.cf
...
smtpd_tls_cert_file=  /etc/letsencrypt/live/domainname/fullchain.pem
smtpd_tls_key_file=  /etc/letsencrypt/live/domainname/privkey.pem
# File /etc/dovecot/conf.d/10-ssl.conf
...
ssl = yes
ssl_cert = </etc/letsencrypt/live/domainname/fullchain.pem
ssl_key  = </etc/letsencrypt/live/domainname/privkey.pem

is required.


#3

No, nothing changed with the path. As I said everything is fine now after restarting both services. Since a restart was all that was necessary we can rule out any issue with my config files.


#4

Yes, restarting is required. I forgot to copy this.

You can use something like

certbot renew --post-hook "service postfix restart ..."

to do that automatic. Don’t know if there is a direct restart command, but with a --post-hook you can do such things.


#5

Interesting. Thanks - is this only required by Postfix? Does Dovecot require restart as well? Where do I make that change? Would this be a change to the cron.d script?


#6

No, both services need a restart to use the new certificate. This was only a sample.

Check your cronjob. There, where certbot renew can be found.


#7

Almost all services will keep the certificate in memory, it’s a lot more efficient than reading it from disk constantly. You will need to reload that somehow. Some services, like Apache and Nginx, have a ‘reload’ function that leaves the service available during a reload. Others require a full restart. Certbot, depending on how you used it initially, will usually reload Apache for you.


#8

Thanks. /etc/cron.d/certbot is:

0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e ‘sleep int(rand(43200))’ && certbot -q renew

Can you give me the exact syntax to make sure these services get restarted on subsequent renewals? Also, is this something that might get overwritten on future updates?

It would be really great if we had a certbot user configuration file where post renewal hooks or other settings could be stored without worry of them being touched. Is there such a thing?


#9

I modified that cron entry to look like this:

0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e ‘sleep int(rand(43200))’ && certbot -q renew --post-hook “service postfix restart; service dovecot restart”

Does that look right?


#10

Postfix and Dovecot both support the reloading as reported earlier. I would suggest to search Google if this is also possible for your current method using the service application (I don’t have experience with it).


#11

There are several: the global one is /etc/letsencrypt/cli.ini and there’s one per existing certificate in /etc/letsencrypt/renewal/ (though those are overwritten when you renew with specific options). You can also place renewal hook scripts in the directories under /etc/letsencrypt/renewal-hooks/.

If systemd is present, service seems to act as a backward-compatible wrapper around systemctl. So it should be possible.

However, if systemd is present, the cron entry installed by the certbot package is ignored in favour of the systemd timer, so modifying it won’t do any good.

It would be better to update the renewal configuration file(s), as that works no matter which scheduling method is used.

The recommended way to do that is to run certbot again with the correct options so that they get saved automatically to the per-certificate renewal config files. For example:

sudo certbot renew --force-renewal --deploy-hook "service postfix reload; service dovecot reload"

The --force-renewal option is needed to force it to renew immediately so that it will save the new configuration (normally it skips certificates that aren’t close to expiry), and --deploy-hook is slightly better than --post-hook here because it only runs after a successful renewal. If you have multiple certificates you should add the --cert-name option to tell certbot which one you want to update.


#12

(related: any chance an explanatory comment regarding systemd could be added to that cron job? It seems to confuse a lot of people… and what’s the best place to make such a suggestion? Guessing @hlieberman is the person to ask, sorry if I got that wrong)


#13

Sure thing! I’ve filed https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=908841 to track it and committed a patch. It’ll go out with the next certbot release in Debian.


#14

I’m not sure about this. Ubuntu 18 definitely uses systemd, but I have all sorts of things running in my crontab and cron is definitely checking cron.d and executing those entries.


#15

The certbot cronjob specifically checks if you’re running systemd, and it refuses to run if so. That’s because we install BOTH a cronjob (for people not using systemd) and a systemd timer (for people who are). We don’t want them both to run, though, so the cronjob short-circuits itself if you’re running systemd.

That’s what the \! -d /run/systemd/system part of the test is checking for inside the cronjob.


#16

Ahh… I see. Thanks for explaining. I took a look at the renewal hooks directory and will have to do a bit more reading on this one. I’ll also look at the per-certificate config. Really appreciate the support you’ve provided here.


#17

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