Auto Renew Lets Encrypt Certificates using Certbot

You can get free SSL certificates from Letsencrypt.org using several different programs. One program is Certbot. Your distro may come with a renewal script/cron. You can use rpm/apt-get/pacman/etc to check.

But if it doesn’t, or if it wasn’t working for you, you can try this:

Renewal Scripts

Here are the scripts that do various parts of the work:

Restart NGINX

This will restart NGINX/Apache safely.

/usr/local/bin/certbot-restart-nginx

#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

# you may have to modify this according to your setup. It is run
# only after a successful certificate renewal. You can tell it
# to restart any service you want. Just modify the following lines.
# You'll notice that it checks that NGINX/Apache has no errors before
# restarting. This is important so it doesn't restart it in the middle
# of you working on it, or if the config otherwise has errors.

# systemctl
nginx -tq && systemctl restart nginx
#httpd -t && systemctl restart httpd

# SysV
#nginx -tq && service nginx restart
#httpd -t && service httpd restart
#httpd -t && service apache2 restart

This sends out the renewal emails

/usr/local/bin/certbot-notify-renewals

#!/bin/sh

## script to send out email about renewed domains. 
## relies on certbot's $RENEWED_DOMAINS shell variable
umask 077

# get the first domain, so we can show it in the subject line
first="$(echo $RENEWED_DOMAINS | cut -f1 -d' ')"

# get the number of domains minus one, for the subject line
num=$(expr $(echo $RENEWED_DOMAINS | wc -w) - 1)

# only show the previous one if there's more than 1 domains
[ $num -gt 0 ] && other_domains=" and $num other domains"

# get a vertical list of domains
list="$(echo $RENEWED_DOMAINS | sed 's/ /\n/g')"

echo -e "The SSL Certs for the following domains have been renewed:\n\n$list\n" \
  | mail -s "Renewed SSL for ${first}${other_domains}" root

Set both to be executable by root:

chmod 744 /usr/local/bin/certbot-restart-nginx
chmod 744 /usr/local/bin/certbot-notify-renewals

CronJobs

Here are two options. One is the traditional cron job. You can put this in your cron job, or incorporate it into your cron service. And the other is a systemd timer.

Traditional Cron

/etc/cron.daily/certbot-renewal

#!/bin/bash

PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

certbot renew -q --post-hook certbot-restart-nginx --renew-hook certbot-notify-renewals

Remember to make it executable:

chmod 744 /etc/cron.daily/certbot-renewal

Systemctl

If you have systemd, here’s the systemd files:

/etc/systemd/system/certbot-renewal.timer

[Unit]
Description=This is the timer schedule Automatic renewals of SSL certificates obtained with certbot

[Timer]
OnCalendar=daily
RandomizedDelaySec=6hours
Persistent=true

[Install]
WantedBy=timers.target

/etc/systemd/system/certbot-renewal.service

[Unit]
Description=Automatically renews SSL certificates obtained with certbot

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew -q --post-hook /usr/local/bin/certbot-restart-nginx --renew-hook /usr/local/bin/certbot-notify-renewals

(The above assumes your certbot executable is in /usr/bin. You’ll need to modify it if it’s not.)

Activate the timer with:

systemctl daemon-reload
systemctl enable certbot-renewal.timer
systemctl start  certbot-renewal.timer
systemctl status certbot-renewal.timer

That last command should give something like:

[[email protected] ~]# systemctl status certbot-renewal.timer
● certbot-renew.timer - This is the timer schedule Automatic renewals of SSL certificates obtained with certbot
   Loaded: loaded (/etc/systemd/system/certbot-renewal.timer; enabled; vendor preset: disabled)
   Active: active (waiting) since Mon 2017-06-12 05:55:46 MDT; 24h ago

Resources

You can read the Certbot Renewal Usage Manual for more things to do, such as copying certificates that have renewed.