Automating Let’s Encrypt Certificate Renewal¶
This guide documents how the aclark.net production server automatically
renews its Let’s Encrypt SSL certificate before it expires.
Overview¶
The server (Amazon Linux 2023, EC2) uses certbot to manage the
Let’s Encrypt certificate for aclark.net and www.aclark.net.
Renewal is automated with a systemd timer rather than cron, since
Amazon Linux 2023 does not ship a cron daemon by default.
The certbot package installs two systemd units:
certbot-renew.timer— schedules renewal checkscertbot-renew.service— runscertbot renewwhen triggered
By default, certbot renew only renews a certificate once it is
within ~30 days of expiry (certbot’s built-in default). This
threshold is not configurable via a simple flag; it is handled
internally by certbot for every certificate it manages.
Checking Current Status¶
SSH into the server and inspect the certificate and timer:
ssh aclark.net
# Certificate details and expiry date
sudo certbot certificates
# Timer schedule and status
systemctl list-timers certbot-renew.timer
systemctl status certbot-renew.timer
Enabling the Renewal Timer¶
The timer ships disabled. Enable and start it so renewal checks run automatically going forward:
sudo systemctl enable --now certbot-renew.timer
This runs certbot renew twice daily (00:00 and 12:00 UTC),
each with up to a 12-hour randomized delay (RandomizedDelaySec=12hours)
to avoid load spikes across Let’s Encrypt’s infrastructure. Certificates
are only actually renewed when within the ~30-day expiry window, so most
runs are no-ops.
Manually Renewing a Certificate¶
If a certificate has already expired or you want to force an immediate renewal without waiting for the random delay:
sudo certbot renew --cert-name aclark.net --non-interactive --no-random-sleep-on-renew
--no-random-sleep-on-renew skips certbot’s built-in randomized
delay, which otherwise can add several minutes before renewal starts.
Verifying Renewal¶
After a renewal (automatic or manual), confirm the new expiry date:
sudo certbot certificates
Look for Expiry Date and confirm it is roughly 90 days out, and that
nginx was reloaded (certbot’s nginx hook does this automatically).
Troubleshooting¶
Timer shows inactive (dead)¶
The timer was never enabled. Run:
sudo systemctl enable --now certbot-renew.timer
Certificate still expired after a timer run¶
Check the service logs:
journalctl -u certbot-renew.service --no-pager -n 50
Renewal seems stuck / slow¶
Manual (non-timer) invocations of certbot renew include a random
delay of up to several minutes by default. Use
--no-random-sleep-on-renew to skip it for one-off manual runs.