💾 Archived View for ser1.net › post › le-mail.gmi captured on 2024-06-16 at 12:48:51. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-03-21)
-=-=-=-=-=-=-
--------------------------------------------------------------------------------
title: "LetsEncrypt and email" description: "How to use LetsEncrypt certificates with Postfix and Dovecot" tags: [ "server", "email", "letsencrypt" ] date: "2017-01-12T00:00:00Z"
--------------------------------------------------------------------------------
I'm using the most excellent Dehydrated[1] utility, which is both easy to use and lightweight (few dependencies).
1: https://github.com/lukas2511/dehydrated
These instructions assume you have control of a web server that can serve requests for the same domain as the mail server.
First, grab Dehydrated. I put it in `/usr/local`:
cd /usr/local sudo git clone https://github.com/lukas2511/dehydrated
LetsEncrypt offers a couple of ways of verifying that you own the domain, but the one I'm using depends on LetsEncrypt being able to query a specific asset on the server. To support this, create a `.well-known/acme-challenge` directory in the web root for the mail server domain of your web server:
sudo mkdir $WEBROOT/.well-known/acme-challenge
Now, configure Dehydrated with that informtion. Per the dehydrated instructions, you also need to put your domain(s) in a file called `domains.txt`.
cd dehydrated sudo cp docs/examples/config . sudo sed -i "s%^#WELLKNOWN=.*%WELLKNOWN=$WEBROOT/.well-known/acme-challenge%" config echo $MAILHOST > domains.txt
I also set a value for `CONTACT_EMAIL`. For testing, you *should* also change to the LetsEncrypt staging server; in case you have to run multiple times, you don't want to be blacklisted:
sudo sed -i 's%^#CA=.*%CA="https://acme-staging.api.letsencrypt.org/directory"%' config
Run dehydrated:
cd /usr/local/dehydrated sudo ./dehydrated -c
You now should have certificates in the `/usr/local/dehydrated/certs` directory. You can reference these directly with both Dovecot and Postfix. Dovecot accesses certs as root; however, Postfix's TLS agent runs as `postfix`, so it can't read the certs which dehydrated sets to 700 for perms. I weakened the security of the certs a bit by making them group readable for the `postfix` group. This is all on Ubuntu; it may be different for other distributions.
sudo hgrp -R postfix certs sudo find certs -type d -exec chmod 750 {} \; sudo find certs -type f -name \*.pem -exec chmod 640 {} \;
Now, it's just telling Dovecot and Postfix where to find the certs, and restart the services:
# Dovecot sudo sed -i "s%^ssl_cert.*%ssl_cert = </usr/local/dehydrated/certs/$MAILHOST/fullchain.pem%" /etc/dovecot/dovecot.conf sudo sed -i "s%^ssl_key.*%ssl_key = </usr/local/dehydrated/certs/$MAILHOST/privkey.pem%" /etc/dovecot/dovecot.conf # Postfix sudo sed -i "s%^smtpd_tls_cert_file.*%smtpd_tls_cert_file = /usr/local/dehydrated/certs/$MAILHOST/fullchain.pem%" /etc/postfix/main.cf sudo sed -i "s%^smtpd_tls_key_file.*%smtpd_tls_key_file = /usr/local/dehydrated/certs/$MAILHOST/privkey.pem%" /etc/postfix/main.cf sudo service dovecot restart sudo service postfix restart
Now test:
# Dovecot openssl s_client -connect mail.germane-software.com:993 # Postfix openssl s_client -connect mail.germane-software.com:587
If everything is working, change the LetsEncrypt server back to the non-staging server and re-run dehydrated with `-x` (force renew) to get a real cert:
sudo sed -i 's%^CA=%#CA=%' config sudo ./dehydrated -x sudo service dovecot restart sudo service postfix restart
Test again, and openssl should stop complaining about being unable to find the SSL root certificate for Dovecot, at least. able to find the SSL root certificate for Dovecot, at least.