44

I've seen conflicting recommendations. From the eff.org docs:

if you're setting up a cron or systemd job, we recommend running it twice per day... Please select a random minute within the hour for your renewal tasks.

I've also seen recommendations for weekly jobs.

I'm not a cron expert, so I'd prefer an answer with detailed steps for setting up the cron job.

Chapman Atwell
  • 1,007
  • 1
  • 9
  • 13
  • This question belongs on ServerFault and [has been asked there](https://serverfault.com/questions/790772/cron-job-for-lets-encrypt-renewal). – Dan Dascalescu Oct 11 '22 at 10:58

9 Answers9

53

I recently (April 2018) installed and ran certbot (version 0.22.2) on an Ubuntu 16.04 server, and a renewal cron job was created automatically in /etc/cron.d/certbot.

Here's the cron job that was created:

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew

Please check this before putting a new Cron job.

Update (From @Hamish Downer's comment):

It's worth being aware that the above cron job won't run certbot renew if /run/systemd/system is present - this is because instead a systemd timer is running certbot - read more about certbot and systemd timers here.

Jerry Chong
  • 7,954
  • 4
  • 45
  • 40
V-Q-A NGUYEN
  • 1,497
  • 16
  • 19
  • 5
    Very relevant answer. The `certbot renew` command (available as of certbot 0.10.0) solves a lot of the older `certbot-auto` hastles. See [Certbot docs](https://certbot.eff.org/docs/using.html#renewing-certificates) for more information. – kaicarno May 22 '18 at 21:23
  • As of June 2019 certbot v0.31.0 it's now `rand(43200)` instead of 3600. I guess they want to spread the requests over the entire 12-hour period, and not just the first hour. – Matt Janssen Jun 30 '19 at 08:41
  • Switched this to the accepted answer as it seems simpler and more current. – Chapman Atwell Aug 10 '19 at 01:46
  • 1
    I need help as I am fairly new to cron... I running Ubuntu 18.04 and after successfully getting the cert. Running `crontab -l` or `sudo crontab -l` shows "no crontab for `. Is this supposed to happen? How do I know if the referenced cronjob above will run? How does one check it? – Ohenepee Peps Aug 11 '19 at 15:42
  • 1
    I hope you edit the answer and add @HamishDowner comment. It clarified a very important point. – Amr Saeed May 24 '21 at 03:53
37

So I settled on scheduling it to run once a day. First I tested auto-renew as the docs recommend:

sudo letsencrypt renew --dry-run --agree-tos

Then I updated the crontab:

sudo crontab -e

This is the line I added:

12 3 * * *   letsencrypt renew >> /var/log/letsencrypt/renew.log

This runs the renew everday at 3:12 am. I presume the docs recommend "a random minute within the hour" to distribute the load on the renew servers. So I suppose anything other than 0, 15, 30, or 45 is preferred.

I looked into randomizing the minute in the cron setting, like Jenkins allows you to do. On original EEF page is this Example:

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot-auto renew

Finally, I tested the cron command using sudo bash:

sudo bash -c "letsencrypt renew >> /var/log/letsencrypt/renew.log"
Chapman Atwell
  • 1,007
  • 1
  • 9
  • 13
  • 14
    Consider upgrading to `certbot` so that you can automatically reload the web server when the certificate renewal succeeds. i.e. `certbot renew --renew-hook 'service nginx reload'`. – Flux Dec 16 '17 at 22:41
  • 1
    To avoid service overload, please add a random sleep in between (`perl -e 'sleep int(rand(43200))'`). Or better use the systemd certbot timer & service, which is now a days automatically deployed when installing the certbot package. See my post up. – Melroy van den Berg Feb 03 '19 at 22:32
  • There is an automated way, don't use crontab. See my answer below. – Melroy van den Berg Apr 13 '21 at 15:20
33

In Debian Jessie and up (incl. Ubuntu) cron is not executed for Certbot renewal. Instead the systemd timer is used. See timer: /lib/systemd/system/certbot.timer

This timer runs the following service: /lib/systemd/system/certbot.service

Which contains:

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true

In order to list all the timers, execute the following command in the terminal:

systemctl list-timers

Hopefully Certbot is part of this:

Mon 2019-02-04 08:38:45 CET 9h left Sun 2019-02-03 15:25:41 CET 8h ago certbot.timer certbot.service

UPDATE:

Due to the down votes. I'll add how to install Certbot on a Debian based distro (it may vary depending on your Linux distribution).

But within Debian Stretch for example you can install the back-port package of certbot via:

sudo apt-get install certbot -t stretch-backports

This will install the files I showed above for you automatically! And thus automatically schedule a certbot timer for you, which runs the service, which runs again the renew.

Manually running a renew is always possible via:

sudo /usr/bin/certbot renew

Can be forced via --force-renewal flag. For more info see the help text of renew:

/usr/bin/certbot --help renew

Files part of the certbot package (incl. but not limited by):

dpkg-query -L certbot
...
/lib/systemd/system/certbot.service
/lib/systemd/system/certbot.timer
...
Melroy van den Berg
  • 2,697
  • 28
  • 31
  • 3
    If you are a Raspberry PI user *this* is the way to go, do not mess with crontab. – ggariepy May 21 '19 at 15:57
  • 2
    This post deserves a lot more credit than it's getting. For the large number of people using Debian, Ubuntu et al, it's kind of a big deal that you don't need to set up your own cron and 'it just renews'. – fred2 Apr 11 '21 at 17:20
8

Ok. So being on Debian (or Ubuntu) with systemd I had probably the same problem like others - cron job not firing. I needed to make some extra steps and observations not mentioned elsewhere, so making separate answer for it.


In my case the /etc/systemd/system/ directory exists, so the job in /etc/cron.d/certbot stops at the initial test.

BUT the /etc/systemd/system/certbot.timer was a pointer to /dev/null. That means it is a masked timer. When I did systemd unmask certbot.timer the link was removed, but I had nothing to replace it with (tried locate certbot.timer but none was installed on my system). I could also still see the timer in systemd list-timers --all, but it was an emtpy file so removed that too using systemd disable certbot.timer. The service in /etc/systemd/system/certbot.service was completely absent.

So after actually cleaning all the certbot-related stuff from /etc/systemd/system/ I created the necessary files manually.

# /etc/systemd/system/certbot-renewal.service
[Unit]
Description=Certbot Renewal
[Service]
ExecStart=/usr/local/bin/certbot -q renew --post-hook "systemctl reload nginx"
# /etc/systemd/system/certbot-renewal.timer
[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target

The timer file content comes from this answer.

I started and checked the whole thing by running:

sudo systemctl start certbot-renewal.timer
sudo systemctl enable certbot-renewal.timer
sudo systemctl list-timers --all
sudo journalctl -u certbot-renewal.service

Few more notes:

  • I have certbot in /usr/local/bin/certbot instead of /usr/bin/certbot (figured using which certbot), don't know why.
  • I'm using nginx, so need to reload it in the post-hook to take the renewed certs into account.
kub1x
  • 3,272
  • 37
  • 38
2

Adding the following line to /etc/crontab runs renewal attempt daily on a random minute between 00:00 and approximately 16:40:

1  1    * * *   root    sleep ${RANDOM:0:3}m && /home/admin/certbot-auto renew --quiet --no-self-upgrade --authenticator webroot --installer apache -w /var/www/mywebroot

Works great for more than a year now.

The renew command itself may vary for you - I used webroot as it seemed most robust at that time.

andruso
  • 1,955
  • 1
  • 18
  • 26
2

Normally while you run a certbot for any webserver in an Ubuntu 16.04 server it automatically creates a cron

#cat /etc/cron.d/certbot

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew
Javeed Shakeel
  • 2,926
  • 2
  • 31
  • 40
1

None of these answers worked for me in 2023, because certbot cannot renew if nginx is running on port 80.

The following entry in the crontab works:

43 6 * * * sudo certbot renew --pre-hook "sudo systemctl stop nginx" --post-hook "sudo systemctl start nginx"

dessalines
  • 6,352
  • 5
  • 42
  • 59
0

for renew every 2 month:

#nano /etc/cron.d/certbot    

30 03 01 */2 * echo "2" | certbot --nginx -v -d yourdomain.com
ooo
  • 43
  • 1
  • 9
-1

To keep simple set a timer to validate automatically:

systemctl status certbot.timer
Flavio Oliveira
  • 381
  • 4
  • 12