Just a quick technical note.
As mentioned before, I started self hosting email a while ago. Exactly three months ago, in fact, and I know this because that's how long Let's Encrypt SSL certificates are valid for. Yesterday, my email clients started complaining about an invalid certificate coming from my mail server.
After a few minutes of worrying if I'm being man-in-the-middled, I ssh'd into my VPS to debug.
Turns out when configuring Dovecot (the IMAP server I use), the SSL certificate you set is just a static string, not a filename pointing to a file that Dovecot will read every time it needs to serve it. As such, even after Certbot correctly got a new certificate, Dovecot was still using the old one.
This can be fixed by restarting Dovecot, allowing it to read the new certificate, assuming its available at the same path.
I already have a cronjob that runs certbot renew
once a month to
renew any SSL certificates going stale. I'm going to change it to instead point
to a script that does
certbot renew systemctl restart dovecotto automate reloading the certificate.
A few things I learned while debugging this issue:
My first step was to check the certificate I thought should have been served by Dovecot. In particular, I wanted to see its expiry date as well as compare its fingerprint to that reported by my mail client.
Certificates are stored in ASCII armor format, which is not human readable.
Turns out you can get a human readable interpretation of your certificate with
the openssl
CLI tool:
openssl x509 -text -noout -in <certificate file>will get you a detailed, human readable output. For example, you can find a "Validity" section, specifying the time period during which the certificate is valid.
Adding the -fingerprint
flag will also output the fingerprint hash.
The -noout
flag is just there to suppress the output of the
non-readable ASCII armor text.
Currently valid certificates from Let's Encrypt are stored under
/etc/letsencrypt/live/<domain name>/
. This is where my
Dovecot server was configured to get its certificate from, so before I realized
that the certificate is only read once, I was surprised that the fingerprint of
the certificate stored here did not match the one my mail client was receiving.
Turns out Let's Encrypt also stores historic certificates under
/etc/letsencrypt/archive/
. Here I was able to find the certificate
with a matching fingerprint to the faulty one received by my client, and confirm
that it did indeed expire yesterday. Finding this is what led me to realizing
how Dovecot handles its certificate configuration.