diff options
author | Marcin Chrzanowski <m@m-chrzan.xyz> | 2021-05-12 16:14:42 +0200 |
---|---|---|
committer | Marcin Chrzanowski <m@m-chrzan.xyz> | 2021-05-12 16:14:42 +0200 |
commit | d68be22176db3d7947682c945c16a44396a024c0 (patch) | |
tree | 03c87038adbff81cac3c22ff99950c11e3ee6197 /src/blog | |
parent | 5669a274b156b57d5b2e9e5427006a8626de143e (diff) |
Add Dovecot SSL post
Diffstat (limited to 'src/blog')
-rw-r--r-- | src/blog/dovecot-ssl-certificate-renewal.erb.html | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/blog/dovecot-ssl-certificate-renewal.erb.html b/src/blog/dovecot-ssl-certificate-renewal.erb.html new file mode 100644 index 0000000..2cafcde --- /dev/null +++ b/src/blog/dovecot-ssl-certificate-renewal.erb.html @@ -0,0 +1,97 @@ +title: Dovecot SSL Certificate Renewal +date: May 12, 2021 11:06 +--- +<p> +Just a quick technical note. +</p> + +<p> +As mentioned before, I +<a href='<%= path_to "blog_hosting-on-vultr-vps" %>'> + started self hosting email +</a> 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. +</p> + +<p> +After a few minutes of worrying if I'm being man-in-the-middled, I ssh'd into my +VPS to debug. +</p> + +<h3>TL;DR: Root cause and solution</h3> +<p> +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. +</p> + +<p> +This can be fixed by restarting Dovecot, allowing it to read the new +certificate, assuming its available at the same path. +</p> + +<h4>Long term solution</h4> +<p> +I already have a cronjob that runs <code>certbot renew</code> once a month to +renew any SSL certificates going stale. I'm going to change it to instead point +to a script that does + +<pre> +certbot renew +systemctl restart dovecot +</pre> + +to automate reloading the certificate. +</p> + +<h3>Learnings</h3> +<p> +A few things I learned while debugging this issue: +</p> + +<h4>Viewing certificate info on the command line</h4> +<p> +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. +</p> + +<p> +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 <code>openssl</code> CLI tool: + +<pre> +openssl x509 -text -noout -in <certificate file> +</pre> + +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. +</p> + +<p> +Adding the <code>-fingerprint</code> flag will also output the fingerprint hash. +The <code>-noout</code> flag is just there to suppress the output of the +non-readable ASCII armor text. +</p> + +<h4>Let's Encrypt certificate locations</h4> +<p> +Currently valid certificates from Let's Encrypt are stored under +<code>/etc/letsencrypt/live/<domain name>/</code>. 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. +</p> + +<p> +Turns out Let's Encrypt also stores historic certificates under +<code>/etc/letsencrypt/archive/</code>. 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. +</p> |