Nairobi GNU/Linux Users Group

A lively community of GNU/Linux enthusiasts

Using systemd Timers to Renew Let’s Encrypt Certificates


This is a quick blog post to share the systemd timers that I use to automate the renewal of my Let's Encrypt certificates. I prefer systemd timers to cron jobs for task scheduling because they are more flexible and easier to debug. I assume that you know what Let's Encrypt is and that you already have some certificates. If not, I recommend that you check out Certbot (the official reference client) and get some.

Let's Encrypt logo

Because Let's Encrypt issues TLS certificates with much shorter lifetimes (currently ninety days) than traditional certificate authorities, they expect you to reduce the burden of the issuance and renewal processes by performing them programmatically and automating them.

Check Early, Check Often

Your certificates are good for ninety days, but checking them for renewal on a daily or weekly basis allows for some margin of error in case of server downtime, network interruptions, beach holidays, etc. In the future Let's Encrypt might use even shorter lifespans so it's good to get familiar with this automation now. You will need to create both the service and timer unit files below.

/etc/systemd/system/renew-letsencrypt.service :

[Unit]
Description=Renew Let's Encrypt certificates

[Service]
Type=oneshot
# check for renewal, only start/stop nginx if certs need to be renewed
ExecStart=/opt/certbot-auto renew --standalone --pre-hook "/bin/systemctl stop nginx" --post-hook "/bin/systemctl start nginx"

/etc/systemd/system/renew-letsencrypt.timer :

[Unit]
Description=Daily renewal of Let's Encrypt's certificates

[Timer]
# once a day, at 2AM
OnCalendar=*-*-* 02:00:00
# Be kind to the Let's Encrypt servers: add a random delay of 0–3600 seconds
RandomizedDelaySec=3600
Persistent=true

[Install]
WantedBy=timers.target

This timer runs once a day at 2AM, but each execution is delayed by a random amount of time between zero and 3600 seconds using the RandomizedDelaySec option.

Pay attention to the location of the certbot-auto script in the service file and adjust accordingly for your setup. Also note that I'm using the standalone mode of execution because the nginx one isn't stable yet. See the Certbot renewal documentation for more examples.

Activate and Enable the Timer

Tell systemd to read the system's unit files again, and then start and enable the timer:

$ sudo systemctl daemon-reload
$ sudo systemctl start renew-letsencrypt.timer
$ sudo systemctl enable renew-letsencrypt.timer

Starting the timer is necessary because otherwise it wouldn't be active until the next time you rebooted (assuming it was enabled, that is). You can verify that the timer has been started, its planned execution times, service logs, etc using the following commands:

$ sudo systemctl list-timers
$ sudo journalctl -u renew-letsencrypt
$ sudo journalctl -u renew-letsencrypt --since="yesterday"

More Information

See the following for more information:

This was originally posted on my personal blog; re-posted here for posterity.