How to prevent certbot from about-renewing?

I'm creating a new cert with the --no-autorenew option however on creation I am told:

Certbot has set up a scheduled task to automatically renew this certificate in the background.

I do not want Certbot to auto renew - what is the correct way to turn off auto-renew per domain and globally?

I'd remove the scheduled task.
...unless you have other certs that DO need to be renewed.

So, how many certs does certbot manage?
[and why not renew this cert automagically?]

2 Likes

Hi, thanks for the quick reply! :smiley:

Where are the scheduled tasks located? (I can't see anything relating to letsencrypt in my usual cron locations)

Quite a few (depending on server - could range from 5 to 20)

I need to stop/start other related services, copy certs to specific locations etc. It's much easier to do this with my own script like I have for years.

What is the best way to switch off auto-renewals globally? And per domain? Should --no-autorenew work? If so should we post this as a bug somewhere?

That option does not come up often and I don't have time to test it.

But, I think it just sets something in that cert's /etc/letsencrypt/renewal profile config file. That allows the regularly scheduled renew to handle any others you might want auto-renewed.

You could check that profile to see if it has such a thing. Or, even try

sudo certbot renew --dry-run

to see if it processes that. Although maybe --dry-run is not definitive for this special setting IDK.

It seems you could use pre and post hooks to automate whatever needs doing to auto-renew. More info on that and how to find the auto-renew is in the Certbot docs

https://eff-certbot.readthedocs.io/en/latest/using.html#certbot-command-line-options

4 Likes

HI Mike,

I've just checked the /etc/letsencrypt/renewal/... configs and it looks like I have autorenew = False only set for some domains - so I am guessing it is my mistake as there are some domains on the same server that only have a couple of days left and are correctly showing as autorenew = False, so fingers crossed they will get auto-renewed by my own script.

I have also deleted and re-created certs for the domains which didn't have autorenew = False - so hopefully those will work correctly too going forward (if not I will report back).


So for anyone reading in future (if I don't make any further posts in this thread) then to stop certbot from auto renewing you need to add --no-autorenew when you create your cert.

If you have already created it (perhaps mistakingly without using that flag) then you can delete and then recreate, using:

certbot certificates # this will show you certs and domains
sudo certbot delete --cert-name domain.com # to delete cert

Then create your certs as normal, perhaps with something like:

sudo certbot --cert-name domain.com certonly --standalone --no-autorenew --preferred-challenges http --http-01-port 54321 -d domain.com -d www.domain.com -d mail.domain.com

Hope that helps and thank you Rudy and Mike for all your help :heart:

2 Likes

Modern Certbot versions (2.3.0 I believe, fixed in 2.9.0) also have a reconfigure subcommand, so there's no need to delete and reissue a cert just to set some option.

(Also, while usually discouraged, this modification is tiny enough to possibly change manually in the renewal configuration file.)

(Also also, I'm personally not a big fan of custom scripts "interfacing" with Certbot to renew certs.)

2 Likes

Just to add onto this, the intended use case is for certbot to be run regularly (like twice a day), with any needed interaction with other systems configured using its --pre-hook, --post-hook, --deploy-hook, etc. That way, it can tell what certificates need renewing at that time and just manage everything. In addition to needing renewal due to the certificate expiring soon, it might also need renewing due to an issue on Let's Encrypt's side (such as the recent incident involving very long domain names). Certbot checks OCSP (and I assume one day will check ARI) to see if the certificate needs to be updated sooner.

While I understand that some people might like a more "hands-on" approach and that especially if you have something working for you now one might not want to change it, be aware that you'll need to be more hands-on in the case of any issues with your certificates that require earlier renewal.

5 Likes

I agree. Certbot should be able to cater almost all your needs. If it doesn't, it's probably not the right ACME client for you and you should consider using a different one. (Although I personally don't have experience with other ACME clients so I have no clue how those non-Certbot clients can interface with scripts et cetera.)

1 Like

So it looks like setting --no-autorenew stops even our own scripts from renewing. A cert had expired today and when my script is run (which uses sudo /usr/bin/certbot renew) it says skipped for that domain:

/etc/letsencrypt/live/domain.com/fullchain.pem expires on 2024-10-02 (skipped)

Is that the expected behaviour? If so perhaps as Rudy originally said it may just be better to stop the scheduled tasks from running - however I can't find them :confused:

On this page: Certbot Instructions | Certbot it says:

The command to renew certbot is installed in one of the following locations:

  • /etc/crontab/
  • /etc/cron.*/*
  • systemctl list-timers

There's nothing in the crontab file:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

And also relating nothing to letsencrypt in the cron. files (other than my own script):

cron.d/       cron.daily/   cron.deny     cron.hourly/  cron.monthly/ crontab       cron.weekly/  

Nor is there anything listed with systemctl list-timers.

I suspect then that when my script runs certbot renew Certbot goes ahead and renews whichever domains it sees fit (ignoring our 30 day window) so perhaps all I need to do is just ensure my script does all the additional bits it needs to do for every domain every day just in case certbot has renewed that domain.

Does that seem like a good way forward?
Or should I check in a specific location for the scheduled task?

Pretty sure any cert profile that was marked as --no-autorenew will not be renewed using the renew command. Doesn't matter how renew command is run.

I am not entirely sure what you are asking so sorry if I misunderstand.

The renew command looks at each of the certbot renewal profiles and acts on each one. If one is set to --no-autorenew certbot renew skips it. For any others you "allow" it to renew it checks the days to expiry and the revocation status. Either may trigger an actual new cert request to renew it.

4 Likes

As a one-time test, you could try:
/usr/bin/certbot renew -d domain.com --force-renewal
[the syntax may need some tweaking]

WARNING: The use of --force-renewal is highly discouraged in any script.

2 Likes

Thanks Mike, that explains what's going on. I thought my script renewed each domain individually but it looks like it simply runs renew. So I think the best (/easiest) thing would be for me to simply run renew twice a day and then each time also copy each domain's certs where I need them and then restart all the services I need to. In other words just assume certbot will be renewing every domain's cert each time the script runs.

In case it's of any interest to you this is what I need to do after each cert is created/updated:

  def create_combined_files
    @msgs << "Creating combined files... \n"
    @domains.each do |domain|
      fullchain = File.read("/etc/letsencrypt/live/#{domain}/fullchain.pem")
      privkey = File.read("/etc/letsencrypt/live/#{domain}/privkey.pem")
      cert = File.read("/etc/letsencrypt/live/#{domain}/cert.pem")
      chain = File.read("/etc/letsencrypt/live/#{domain}/chain.pem")
      
      # For HAPROXY
      File.open("/etc/haproxy/certs/#{domain}.pem", "w") do |f|
        f.write(fullchain)
        f.write(privkey)
      end
      
      # For Dovecot / Postfix
      File.open("/home/#{domain}/ssl.key", "w") do |f|
        f.write(privkey)
      end
      File.open("/home/#{domain}/ssl.cert", "w") do |f|
        f.write(cert)
      end
      File.open("/home/#{domain}/ssl.ca", "w") do |f|
        f.write(chain)
      end
      File.open("/home/#{domain}/ssl.combined", "w") do |f|
        f.write(fullchain)
      end
      File.open("/home/#{domain}/ssl.everything", "w") do |f|
        f.write(privkey)
        f.write(cert)
        f.write(chain)
      end
      @msgs << "Finished creating combined_file for #{domain}... \n"
    end
  end
  
  def reload_haproxy
    @msgs << "Reloading HAProxy \n"
    system("/bin/systemctl reload haproxy.service")
    @msgs << "Renewal process finished. \n"
  end
  
  def reload_postfix
    @msgs << "Reloading Postfix \n"
    system("/bin/systemctl reload postfix.service")
    @msgs << "Renewal process finished. \n"
  end
  
  def reload_dovecot
    @msgs << "Reloading Dovecot \n"
    system("/bin/systemctl reload dovecot.service")
    @msgs << "Renewal process finished. \n"
  end

(Just out of interest, would it be easy enough to configure Certbot to do all of that? Or is my use-case quite unique?)


I tried adding /usr/bin/certbot renew --force-renewal -d domain.com and the script got the following for each domain :joy:

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): Saving debug log to /var/log/letsencrypt/letsencrypt.log
An unexpected error occurred:
EOFError
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
1 Like

Then, I suspect there is no cert to renew with only that one single domain name.
Check your cert, with:
certbot certificates

Then use either of:

  • --cert-name [name-of-cert]
    [instead of -d domain.name]

  • -d [list-of-all-names-on-cert]

3 Likes

I don't think that is the right format

To renew one cert you use --cert-name (name-of-cert) and not -d example.com

@AstJ I'll post later on my thoughts on your approach and options

4 Likes

Well, I did write:

3 Likes

Overall I think you are better off letting Certbot renew do what it normally does. Let it monitor your certs and renew when needed.

That script could just be a Certbot --deploy-hook. This hook runs each time a cert is issued. So, most times when renew runs the hook is not invoked since Certbot just inspects a cert and action is not needed. The domain name gets passed to the hook as a variable (see Certbot docs)

Assuming your Certbot is new-ish the reconfigure command Osiris mentioned earlier could modify your cert profiles. Be sure to remove the setting for no-auto-renew too.

Try it with one cert with commands like

sudo certbot help reconfigure
sudo certbot reconfigure --cert-name (name) --deploy-hook (path-to-hook-command) --run-deploy-hooks
sudo certbot renew --cert-name (name) --dry-run --run-deploy-hooks

not sure if --run-deploy-hooks is needed on renew if set by reconfigure

Looking at the reconfigure help I am not sure it can un-set the no-auto-renew flag.

That all said, the other way is to still let certbot renew act on all your certs. Then, say daily (or like M-F) run your script for each cert. Sure you would copy and reload services on many days for an un-changed cert. You could get fancy and check the file timestamps and only act when it is recent.

In general, trying to control when your certs renew is trickier than it appears. It is not just days to expiry but CA-originated revocations (which LE just had one this week) and ARI benefits (future). Changing cert life durations are also likely in future.

4 Likes

Thanks Mike.

I will look into deploy-hooks, however in the meantime I get the feeling there are no Certbot scheduled tasks because I couldn't find any - is there a way to ask Certbot to say where it has installed or set up the scheduled task?

If I need to rely on my own scheduled task to run certbot renew then I don't mind the files being copied and services being started twice a day like I am now doing since it happens so quickly anyway.

2 Likes

That is puzzling. Your first post indicated it had one. And, usually one is setup when you install Certbot. Although, this depends what method you used and your o/s. How did you install it? (snap, apt, pip, ... and what o/s)

You did check all the places from the docs and if there isn't one then you can just add a cronjob. Here is the way to add that manually.
https://eff-certbot.readthedocs.io/en/latest/using.html#setting-up-automated-renewal

4 Likes

That's what I had thought too... but it appears that renew was just getting triggered by my own script (and I think, was renewing some domains that weren't exactly with 30 days remaining, hence got out of sync with my script).

Installed on Rocky9 using:

	dnf install epel-release
	dnf install certbot

Am curious now, does certbot renew certs when there is 30 days remaining?

Yes, by default. But, of course it needs to have the renew command scheduled for that to work. It should be setup to run at least daily if not twice daily.

There is a setting in the cert renewal conf file that can change that but 30 days is recommended (actually, 1/3 of life left is recommended).

You can check the /var/log/letsencrypt for run history (or syslog maybe). Might help you track down what happens when.

I don't know offhand if epel/Rocky install would also install a scheduled auto-renew. Perhaps not if you didn't see one and never deleted one. Not something that's come up before and I don't have a Rocky to test with.

Certbot may also renew a cert if it detects it was revoked. Let's Encrypt (and other CAs) do rarely revoke certs issued in error. LE had such an incident this week. And, in future Certbot may support ARI (acme renewal info) which may also allow LE to renew "early" during slow periods.

It sounds like you might be trying to tightly couple something of yours to a specific schedule. Just wanted to warn you away if that's the case.

4 Likes