qpsmtpd seems to be a little bit "picky" when it comes to the files it requires. I've tested it here locally and it can work, unfortunately just not "out of the box". For example, the following doesn't work:
tls /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/live/example.com/fullchain.pem
However, when I simply copy the fullchain.pem and privkey.pem files to /etc/qpsmtpd/ssl/
, it does work:
tls /etc/qpsmtpd/ssl/fullchain.pem /etc/qpsmtpd/ssl/privkey.pem /etc/qpsmtpd/ssl/fullchain.pem
What I noticed is that the permissions of privkey.pem are 644 in the letsencrypt directory. That's because certbot puts restrictions on the directory where the private keys are kept. By copying the private key out of this restricted directory to the unrestricted /etc/qpsmtpd/ssl
directory, I've exposed my private key to every non-root service on my server, including qpsmtp. That's the reason why it works after I've copied it.
It seems qpsmtp tries to load the files as the user smtpd
on my Gentoo system. It probably doesn't run as root on your server too.
You can check the user qpsmtp is running on by running:
lsof -i -P -n | grep LISTEN | grep :25
This identifies the service listening on port 25 (SMTP) and in the third column is the username.
Then, I suggest you use a script called by certbot after a renewal to copy the files to the correct location:
First, run this once:
mkdir -p /etc/qpsmtpd/ssl
(the directory might already exist)
Then, put the following script somewhere, for example, /usr/local/bin/deploy-qpsmtp-cert-files
#!/bin/bash
# Change the username to the user you've found earlier if applicable:
USER="smtpd"
# Directory where all qpsmtpd configuration files reside:
QPSMTPD_CONF_DIR="/etc/qpsmtpd/"
cp "$RENEWED_LINEAGE"{fullchain,privkey}".pem" "$QPSMTPD_CONF_DIR/ssl/"
chmod 600 "$QPSMTPD_CONF_DIR/ssl/privkey.pem"
chown $USER: "$QPSMTPD_CONF_DIR/ssl/"{fullchain,privkey}".pem"
Make the script executable by running chmod +x /usr/local/bin/deploy-qpsmtp-cert-files
Now, you can use that script in certbot as the deploy hook for your qpsmtp certificate like:
certbot ...other_options.. --deploy-hook /usr/local/bin/deploy-qpsmtp-cert-files
Note that all of this is necessary due to, in my opinion, improper design by qpsmtp, as I believe private keys should always be only readable by the root user! There might be security implications when the private key is owned by a user such as smtpd
. If there is a design flaw or exploitable bug in qpsmtpd, the private key might get exposed! This is obviously very bad.
If I've got the time, I might file an issue with qpsmtpd regarding this design flaw.