Automatically Renew Certbot Certificates With systemd Timers
This article will introduce a relatively new way to perform automatic certificate renewal with systemd timers instead of traditional ways such as crontab.

It could be tiresome to have to manually renew your Let’s Encrypt certificates using Certbot on your VPSs every few months. This gets increasingly frustrating as you have more services and thus, more certificates to renew. Having to renew them manually is also quite detrimental to the scalability of your services and infrastructure. Therefore, there emerges a need to enable the certificates to self-renew. This article will introduce a relatively new way to perform automatic certificate renewal with systemd timers instead of traditional ways such as crontab.

Why? Because on a system with systemd, it is easier to have everything managed through systemd.

In order to achieve auto-renewal of certificates, we will need to write two systemd unit files: a service unit which defines what to execute, and a timer which defines when to execute.

Writing a Service Unit

In simple terms, the systemd service file defines the commands to be executed for the certificate renewal. You can think of it to be similar to a script. Here are some noteworthy points:

  • Type=oneshot: This option makes the service unit behave more like a script. The unit will not become a daemon, and you can define multiple ExecStart entries which will execute in serial. If any of the entries fail, the unit is considered failed.
  • The first ExecStart: Launches Certbot in -n (non-interactive) mode to renew the certificates. More arguments can be added as needed.
  • The second ExecStart: Optional. Certbot needs to listen on port 80 for web-based authentication. Since port 80 is a privileged port, Certbot needs to run with root privileges. However, this means that the certificates saved will be owned by root:root. This second command yields the ownership of the certificates. You can modify this command as needed.
  • The third ExecStart: Restart the service(s) using the expiring certificates so they can load in the refreshed certificate. reload might also be supported by some services as a more graceful version than restart.

This example below is written for one of my matrix-synapse servers. Since Certbot requires root privileges to listen on port 80 to renew the certificates, the renewed certificates it releases into /etc/letsencrypt are also owned by root:root. My coarse solution for this problem is to simply use a chown command to yield the ownership of the needed directories to the service’s group ssl-cert per the conventions. The user matrix-synapse is a member of the ssl-cert group, which gives it access to the certificates and keys.

Of course, should you have multiple services running on the same server or just wish to have more fine-grained permissions, you can always design a more intricate chown command or seek an alternative solution for the permissions. I am merely demonstrating the bare minimums here.

Another thing worth mentioning is that if you have Certbot installed via pip (not that you should) instead of a package manager, Certbot will be at /usr/local/bin/certbot instead of /usr/bin/certbot.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[Unit]
Description=Renew Certbot certificates
Wants=certbot-renew.timer

[Service]
Type=oneshot
WorkingDirectory=/etc/letsencrypt
ExecStart=/usr/bin/certbot renew --standalone -n
ExecStart=/usr/bin/chown root:ssl-cert -R /etc/letsencrypt/archive /etc/letsencrypt/live
ExecStart=/usr/bin/systemctl restart matrix-synapse

[Install]
WantedBy=multi-user.target

Unit file: /etc/systemd/system/certbot-renew.service

Writing a Timer Unit

The timer file controls when/how often the service file is executed.

  • OnCalendar=daily: Denotes that the service file above should be executed on a daily basis.
  • Persistent=true: The last time the timer is ran is stored on disk. If for whatever reason (e.g, power-off) the timer was not executed on-time, it will be executed immediately when the timer is next loaded.
1
2
3
4
5
6
7
8
9
[Unit]
Description=Daily Certbot renew

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Unit file: /etc/systemd/system/certbot-renew.timer


最后修改于 2021-07-12