Monitor certificates statuses

Posted on 2025-03-30 in Trucs et astuces

Let’s encrypt recently announced they will stop sending emails when certificates must be renewed. Following this announcement, I created a small script to monitor the status of my certificates and receive an email if they are not renewed in time. Since it can be handy, here it is!

The check-certs.sh script. It will sent an email if a certificate in the supplied list is due to expired in 20 days.

#!/usr/bin/env bash

set -eu

WARN_IF_LESS_THAN_DAYS_LEFT=20
EMAIL=jujens@jujens.eu
# Replace with our list of sites to moniftor.
sites=(jujens.eu www.jujens.eu comments.jujens.eu)
certificates_will_expired_soon=""

now_ts=$(date +%s)

for site in ${sites[@]}; do
    expiration_date=$(echo -n | openssl s_client -servername $site -connect $site:443 |& openssl x509 -noout -dates |& grep notAfter | cut -d = -f 2)
    expiration_ts=$(date -d "$expiration_date" +%s)

    ((diff=expiration_ts-now_ts, seconds_to_days=60*60*24, nb_days_left=diff/seconds_to_days))
    message="$site will expire in $nb_days_left days"
    echo $message
    if [[ $nb_days_left -le $WARN_IF_LESS_THAN_DAYS_LEFT ]]; then
        certificates_will_expired_soon+="$message\n"
    fi
done

if [[ -n "$certificates_will_expired_soon" ]]; then
    echo -e $certificates_will_expired_soon | mail -s "Certs renewal issue!" $EMAIL
fi

I launch it weekly with a systemd timer.

The script to renew the certificates (also launched weekly with a systemd timer) is much more simple:

#!/usr/bin/env bash

set -eu

certbot renew
systemctl restart nginx