Ubuntu 18.10 certbot.service systemd & hooks


#1

There is some confusion on setting up my certbot auto renew.

I’m using Ubuntu 18.10 with systemd.

Under /lib/systemd/system there is a certbot.service file already created.
If I run sudo systemctl enable certbot.service it fails to put certbot.serivce in /etc/systemd/system, and there is no default certbot.service file there.

------- The Error
:/etc/systemd/system$ sudo systemctl enable certbot.service
The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:

  1. A unit may be statically enabled by being symlinked from another unit’s
    .wants/ or .requires/ directory.
  2. A unit’s purpose may be to act as a helper for some other unit which has
    a requirement dependency on it.
  3. A unit may be started when needed via activation (socket, path, timer,
    D-Bus, udev, scripted systemctl call, …).
  4. In case of template units, the unit is meant to be enabled with some
    instance name specified.

I do have /etc/systemd/system/timers.target.wants/certbot.timer file, and when I do a systemctl status it shows the timer is running.

So first do I need to move the /lib/systemd/system/certbot.service file to /etc/systemd/system/certbot.service?

Second, I want to restart a few services in my hooks, so would this line work?

ExecStart=/usr/bin/certbot renew --post-hook “systemctl restart nginx, systemctl restart dovcot, systemctl restart postfix”

(Not sure I need to restart dovecot)

Thanks!


#3

Hi,

(Please correct me if I’m wrong)
Certbot, unlike webservers or sql server, should not run in background unstopping…

If you created a systemd timer for certbot cron, you could just use that, as systemd timer should wake up certbot at the specific time and execute as specified.

I’m not sure if certbot would execute those commands correctly (as I never used a post-hook)… however, you could restart several softwares at once…

"systemctl restart nginx dovcot postfix”

You should restart dovecot if it’s using the let’s encrypt certificate.

If certbot apprars in your systemd timer, that’s it. You don’t (and shouldn’t) add certbot to systemctl enabled list just because you want to make certbot executive once in a while.

Thank you


#4

Hi @Frostcandy,

No, you shouldn’t touch/modify anything related to certbot.service nor certbot.timer.

@stevenzhu already said it but just in case, certbot.service is triggered by certbot.timer so you should not touch it, if you want to see when run your timer just check it using this command:

systemctl list-timers certbot.timer

You should separate the commands using semicolon ; instead of comma ,

ExecStart=/usr/bin/certbot renew --post-hook “systemctl restart nginx; systemctl restart dovcot; systemctl restart postfix”

Also, I suppose it is an errata because dovcot should be dovecot and instead of restart you should use reload, all those services support reload so use it instead.

ExecStart=/usr/bin/certbot renew --post-hook “systemctl reload nginx; systemctl reload dovecot; systemctl reload postfix”

Anyway, don’t do this, you shouldn’t modify certbot.service directly because if certbot is upgraded you could lose your modifications, instead, create a simple shell script to reload your services and put it inside /etc/letsencrypt/renewal-hooks/post/ dir.

Something like this:

echo -e '#!/bin/sh\nsystemctl reload nginx\nsystemctl reload dovecot\nsystemctl reload postfix' > /etc/letsencrypt/renewal-hooks/post/reload-services.sh
chmod 750 /etc/letsencrypt/renewal-hooks/post/reload-services.sh

And you should be done, every time your cert is renewed (and only when it is renewed) certbot will execute the reload-services.sh script to reload your 3 services (nginx, dovecot and postfix).

Good luck,
sahsanu


#5

In addition to the great advice from @sahsanu above (reloading is the way to go!), I think for just enabeling new certificates in services, you should use the --deploy-hook, not the --post-hook. See for more information Renewing certificates in the certbot documentation. The post hook will run always, even when no certificate was renewed. The deploy hook however, only runs when a new certificate is ready for deployment.


#6

Hi @Osiris,

Just to be clear because post-hook doc could be a bit confusing (at least for me :wink: ), post-hook will run “always” IF and only IF it will attempt to renew a certificate, that is, one certificate that will expire in less than 30 days or if you force the renew. If there is no certificate to be renewed at the time certbot renew runs, the post-hook command/script won’t run, I mean, if you have a cron job or timer running twice a day, that doesn’t mean your services will be reloaded twice a day, just when the cert will be renewed, of course, if the certificate needs to be renewed and it is not renewed because there is some error, the post-hook will run and as you said, deploy-hook will only run if the certificate was renewed successfully. The other difference is that deploy-hook will run for every certificate renewed and post-hook will run only once when all the certificates have been renewed (if there are several of them that need to be renewed at the time certbot runs :wink: ) so if you have 10 certificates renewed at the same time, the deploy-hook will run 10 times and using post-hook will run only once.

Said that, I prefer to use deploy-hook instead of post-hook but I used it in the examples because op already used it ;).

Cheers,
sahsanu


#7

I guess I left that part out, yes :grin: The docs clearly say (and I didn’t read nor mention it) “Hooks will only be run if a certificate is due for renewal, so you can run the above command frequently without unnecessarily stopping your webserver.”
The information about the deploy hook is a little bit fragmented. It isn’t mentioned in the text, but it is mentioned in the cerrbot --help part: " --deploy-hook DEPLOY_HOOK Command to be run in a shell once for each successfully issued certificate."
Also lacking in the text is the use of the $RENEWED_LINEAGE and $RENEWED_DOMAINS variables.
And b/c of some mismanagement on LE’s part with regard to community input on PRs on GitHub, I personally am not really motivated to go and fix all that…


#8

Good information all thanks.

One question:

sudo systemctl list-timers certbot.timer shows ACTIVATES certbot.serivce but doesn’t give the path, does it just somehow know to run certbot.service under /lib/systemd/system?

After reading all of your comments I’ve decided to do it this way, I have 10 certs:

  1. Create reload-services.sh under /etc/letsencrypte/renewal-hooks/post/
    #!/bin/sh
    systemctl reload nginx
    systemctl reload dovecot
    systemctl reload postfix

#9

Hi @Frostcandy,

Yes, don’t worry, systemctl knows what to launch :wink: indeed a timer will launch the service with the same name, if the timer’s name is certbot.timer it will launch certbot.service if the timer’s name is frostcandy.timer it will launch frostcandy.service

It is fine, I suppose it is just a typo but the right path to letsencrypt is /etc/letsencrypt/renewal-hooks/post/ without e at the end of letsencrypt

Also, remember to give execution perms to the script or it won’t run:

chmod 750 /etc/letsencrypt/renewal-hooks/post/reload-services.sh

Cheers,
sahsanu