-
-
Save greenmoss/8ee9d4acd3a21df699cde2225a78399e to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash | |
# This script renews letsecnrypt SSL certificates using Cloudflare dns-1 renewal | |
# It assumes you are using Mailcow | |
set -euo pipefail | |
# REQUIRED set these: | |
[email protected] | |
your_domain=mail.your.domain # only tested with single domain | |
cloudflare_ini_path=/root/.cloudflare # add your Cloudflare file here, called cloudflare.ini | |
# OPTIONAL also set these: | |
log_file=/var/log/certbot-cloudflare.log # if you don't want any logs, change it to /dev/null | |
# send all output and errors to log file | |
exec 1>$log_file | |
exec 2>&1 | |
# log what we are doing | |
set -x | |
date # overwrite, no log rotate! | |
echo "starting renewal" | |
docker pull certbot/dns-cloudflare | |
docker run --rm \ | |
-v $cloudflare_ini_path/cloudflare.ini:/cloudflare.ini \ | |
-v /opt/mailcow-dockerized/data/assets/ssl:/etc/letsencrypt \ | |
certbot/dns-cloudflare \ | |
certonly -n --agree-tos -m $your_email \ | |
--dns-cloudflare --dns-cloudflare-credentials /cloudflare.ini \ | |
-d $your_domain | |
cd /opt/mailcow-dockerized/data/assets/ssl | |
newcerts=$(find live/$your_domain/ -mmin -5) | |
if [ -z "$newcerts" ]; then | |
echo "no renewals found, not restarting services" | |
exit | |
fi | |
ln -sfv live/$your_domain/privkey.pem key.pem | |
ln -sfv live/$your_domain/cert.pem cert.pem | |
cd ../../.. | |
function reload_ssl_service () { | |
service=$1 | |
port=$2 | |
echo "restarting SSL service $1 on port $2" | |
docker-compose restart $service | |
timeout 30 sh -c '\ | |
while ! \ | |
openssl s_client -showcerts -connect $0:$1 2>/dev/null </dev/null | openssl x509 -noout 2>/dev/null; do | |
# $0 and $1 are inside single quotes, which means they expand to the arguments provided to sh -c | |
sleep 1 | |
done' $your_domain $port | |
echo "$service SSL cert expiration" | |
openssl s_client -showcerts -connect $your_domain:$port 2>/dev/null </dev/null | openssl x509 -noout -text | grep 'Not After' | |
} | |
reload_ssl_service nginx-mailcow 443 | |
reload_ssl_service dovecot-mailcow 993 | |
reload_ssl_service postfix-mailcow 465 | |
date | |
echo "completed" |
Logs indicate all 3 have successfully restarted. Restarting manually didn't make any difference.
I think the issue is path related. Mailcow docs say not to use simlinks for certs.
Built in acme client places certs in to /data/assets/ssl/{domain.com}. It appears /data/assets/ssl is then mapped to the containers as /etc/ssl/mail. Your script symlinks them to /data/assets/ssl directly. From there it gets confusing.
Perhaps there's been some changes to cert placement in the current version. (2023-05a).
Edit. Rereading the mailcow docs - specifically https://docs.mailcow.email/post_installation/firststeps-ssl/#how-to-use-your-own-certificate
Does indeed indicate
To use your own certificates, just save the combined certificate (containing the certificate and intermediate CA/CA if any) to data/assets/ssl/cert.pem and the corresponding key to data/assets/ssl/key.pem.
IMPORTANT: Do not use symbolic links! Make sure you copy the certificates and do not link them to data/assets/ssl.
I'm not sure how /data/assets/ssl/{domain.com} got created in my instance to begin with. It does have a date of few weeks ago, so perhaps it was made by the built in acme client. So the only change then is copying files rather than symlinking?
My first guess would be that the services didn't actually restart.