certbot / certbot

Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.
Other
31.49k stars 3.4k forks source link

Run script on renewal of certificate #1504

Closed bwesterb closed 8 years ago

bwesterb commented 8 years ago

The preferred way to use letsencrypt certificates, is pointing applications directly into /etc/letsencrypt/live. However, for several reasons (see below), this might not work and some custom steps need to be taken to install a certificate for an application. An admin should be able to install a script which is run on the renewal of a certificate to install it.

A hypothetical implementation could work as follows

letsencrypt -d mydomain --on-renewal=/usr/local/bin/install-cert-for-lighttpd

With the script /usr/local/bin/install-cert-for-lighttpd containing, for instance

cat "/etc/letsencrypt/live/$1/privkey.pem" "/etc/letsencrypt/live/$1/cert.pem" > /etc/lighttpd/ssl/$1.pem
chown www-data:www-data /etc/lighttpd/ssl/$1.pem
service lighttpd reload

Some reasons I can think of for a script are:

  1. The applications requires that the certificate and key in a modified format. See #1201
  2. The application does not run as root. Thus, we need to make a copy of the certificate only readable by the user as which the application is running. See e.g. #1425
HepplerDotNet commented 8 years ago

Why not just putting the letsencrypt call into install-cert-for-lighttpd? I also wrote a python script, which stores the current hpkp pin, runs letsencrypt, retrieves the new hpkp pin and write both to a config file. It also hits my dns api to update TLSA records.

NEOatNHNG commented 8 years ago

@PatrickHeppler Probably because the install-cert-for-lighttpd script has no idea when the renewal will happen.

@bwesterb I think this is rather inelegant. The main selling point of Let's Encrypt is to make the life of admins easier. One way it does that is by automating the installation process for standard software. So there should not be a script that you have to give on the command line to make renewal work on standard software. #1425 is easily solvable by setting the group permissions of the certificates right – no script needed. For the automation on cert renewal you are probably right: We need some kind of hook that gets executed. But that should be a module in the letsencrypt client, not a script you have to write yourself and it should take into account that multiple applications use the certificate and therefore need to have their hooks executed. As the format is needed for multiple pieces of software it should be either generated unconditionally (which would make custom configurations for software where we do not have an installer module easier) or it should use a dependency based mechanism to generate the formats that are required by an installer module.

HepplerDotNet commented 8 years ago

@NEOatNHNG That's why I wrote he should put the letsencrypt call into his script ;)

bwesterb commented 8 years ago

@NEOatNHNG I agree that this should not be the intended way to use letsencrypt – it is however convenient to have an easy to use fallback like this. It might not even help with corner cases I did not anticipate yet.

@PatrickHeppler The problem there is that there might be multiple callers of letsencrypt. Isn't it likely that letsencrypt in the future will automatically install a cronjob? Then this cronjob has to be disabled first.

HepplerDotNet commented 8 years ago

If letsencrypt installs a cronjob, you can run your script thru cron a few seconds later. I'll stick to my script and disable the letsencrypt cronjob.

mjrider commented 8 years ago

@NEOatNHNG one of the key features of unix is that tools do 1 thing and do it good. Trying to make letsencrypt configure any piece of software is an impossible task, providing a hook for a post-cert/renew makes it possible for to provide integration's which are not a use case letsencrypt would like to offer. considering how git works , i would go for generic pre and post hooks for all operations, and let the admin create all the scripts it would like to use for integration. default use case for users is ngxin/apache with ssl that makes sense for letsencrypt to include, but my haproxy with multiple backend servers setup where the list valid domains is on the backend, en the ssl certicates would live in the loadbalancer. i would be insane to expect that letsencrypt would understand such a setup.

NEOatNHNG commented 8 years ago

@mjrider That's right but I would only see this as an additional option provided by a module that you would hook in if you needed some custom script to be executed on renewal, not the default way to do those things. So you would have your apache module, your nginx module and your script module that calls a script for every event that it receives.

DenWav commented 8 years ago

This is a very necessary feature that will enable the auto-renewal process to work for any system. Without something like this I can see significantly fewer people using the auto-renewal system, which is one of the nice features of letsencrypt. Something as trivial as calling scripts that are in some directory should not be a separate module, it should be a core part of the system. To me this would be a much more elegant (and stable) system than a separate module which would probably just lead to confusion as most server admins would look for a system like this. And of course it's just an option -- for more basic servers the server admin can safely ignore it and not worry about it.

NEOatNHNG commented 8 years ago

@DemonWav You're right and I guess I didn't made my intention clear. I think to have a directory where you can place your hook scripts is nice and executing them if there are any should even be enabled by default. But calling hook scripts should not be the main way the renewal hooks get called for standard software and the way to unify these two approaches on the code level would probably be to have a module that instead of implementing its own logic would execute those hook scripts.

SwartzCr commented 8 years ago

I don't think this makes sense. The Let's Encrypt renewer doesn't set up a cron job, you as the user set up a cron job. If you're wanting a script to run after the renewer runs I think it's best to have cron call a bash script that then calls your second command or series of commands after the renewer runs. This especially makes sense in the case where you need to worry about user permissions, since LE won't handle those well. The only reason I can think of that this would be useful is if you needed an assurance that the renewer successfully fetched a new cert.