Automated email for Let's Encrypt certificate expiration

The Let's Encrypt certificate I use for an email server again wasn't automatically renewed - see Let's Encrypt certificate expired. The Let's Encrypt certificates exipre every 90 days, so I wanted the system to automatically email me a message at least a week before the certificate expires. I manually renewed the certificate today by running the command letsencrypt renew from the root account and checked the new expiration date with the command openssl x509 -enddate -noout -i cert_pem_file_location where cert_pem_file_location is the location of the relevant cert.pem file.

# openssl x509 -enddate -noout -in /etc/letsencrypt/live/
notAfter=Sep  8 19:14:00 2017 GMT

Since the new certificate expiration date is September 8, 2017, I wanted an email notice sent to me on September 1. I can then manually renew the certificate, if needed. I would then want to be notified every 3 months again indefinitely. Since the mailx utility is a standard email program found on Linux and OS X/macOS systems, I use it for sending scheduled email messages.

To have mailx send the output of a script/program by email, you can pipe the output of the program into mailx, e.g., program | mailx -s "Subject_for_Message" email_address where Subject_for_Message is whatever you would like to appear as the subject for the email message and email_address is the recipient's email address. E.g., I can use the openssl command to determine when the Let's Encrypt certificate will expire as shown above. I can pipe it's output into mailx as shown below:

openssl x509 -enddate -noout -in /etc/letsencrypt/live/ | mailx -s "Let's Encrypt Certificate Expiration"

The above command would result in mailx sending an email with the subject "Let's Encrypt Certificate Expiration" and "notAfter=Sep 8 19:14:00 2017 GMT" in the body of the message.

I can put the line above in a script named


openssl x509 -enddate -noout -in /etc/letsencrypt/live/ | mailx -s "Let's Encrypt Certificate Expiration"

I can make the script executable by changing the file permissions on it with chmod 744 I can then schedule the script to be executed every 3 months starting on September 1 by issuing the crontab command crontab -e for the root account to add the following line to the crontab file:

0 9 01 Sep,Dec,Mar,Jun * /root/bin/

The first 5 space-separated elements on the line in the crontab file are scheduling elements:

The first 5 elements on the line in the crontab file are scheduling elements:

 # ┌───────────── min (0 - 59)
 # │ ┌────────────── hour (0 - 23)
 # │ │ ┌─────────────── day of month (1 - 31)
 # │ │ │ ┌──────────────── month (1 - 12 or the short name of the month, e.g., Jan, Feb, etc.)
 # │ │ │ │ ┌───────────────── day of week (0 - 6) (0 to 6 are Sunday to
 # │ │ │ │ │                  Saturday, or use names; 7 is also Sunday)
 # │ │ │ │ │
 # │ │ │ │ │
 # * * * * *  command to execute

So the "0 9 01" at the beginning of the line indicates that the script should be run at 9:00 AM on the first day of the month. I can then specify the months in which I want the command to be executed. I put "*" for the day of the week since I don't want to specify a specific day of the week, so the day of the week can match any possible value. The last item on the line is the location of the script I want to run.

Related articles:

  1. Daily testing of email deliveries using mailx
  2. Sending messages and files with mailx
  3. Let's Encrypt certificate expired