Why does Certbot fail to run post hook scripts?
Your shell scripts use a shebang #!/bin/bash
, meaning they are to be executed with that program, but the Docker container in which they run doesn't include bash. This is why /bin/sh
reports the confusing not found
error when calling these obviously present scripts. It is not the scripts that are not found, but the bash interpreter that you asked to run them with.
You can resolve the problem by changing the script interpreter to /bin/sh
and removing any bash-isms from the scripts (probably quick and easy), or by installing bash in the container (probably messy).
Related videos on Youtube
herzbube
Coding keeps me healthy. My main StackExchange haunt is Stack Overflow. My pet project currently is the Little Go iOS app. My level of activity on SO varies, but the importance of #SOreadytohelp remains constant. I avidly read Science Fiction, mostly older stuff, which is probably why I don't like scifi.stackexchange.com very much. I get very excited by Space Exploration. Nobody around me shares my feelings, so I regularly make a fool of myself. It may also have been a mistake to tell people how much time I spend exploring the semi-fictitious galaxy of Elite: Dangerous.
Updated on September 18, 2022Comments
-
herzbube over 1 year
This is my first attempt at renewing Let's Encrypt certificates via Certbot. After carefully reading the Certbot user guide I created two post hook scripts like this:
root@pelargir:~# ls -l /etc/letsencrypt/renewal-hooks/post total 8 -rwxr-xr-x 1 root root 697 Aug 29 16:35 10-setup-courier.sh -rwxr-xr-x 1 root root 377 Aug 29 16:32 20-restart-services.sh
I then ran the renewal process manually on the command line (i.e. not via cron). This was successful in renewing the certificates, but it failed to execute the above post hook scripts. Here is the relevant output:
[...] Running post-hook command: /etc/letsencrypt/renewal-hooks/post/10-setup-courier.sh Hook command "/etc/letsencrypt/renewal-hooks/post/10-setup-courier.sh" returned error code 127 Error output from 10-setup-courier.sh: /bin/sh: /etc/letsencrypt/renewal-hooks/post/10-setup-courier.sh: not found Running post-hook command: /etc/letsencrypt/renewal-hooks/post/20-restart-services.sh Hook command "/etc/letsencrypt/renewal-hooks/post/20-restart-services.sh" returned error code 127 Error output from 20-restart-services.sh: /bin/sh: /etc/letsencrypt/renewal-hooks/post/20-restart-services.sh: not found [...]
I have no idea why this happens. I double-checked:
- The script files exist
- The script files are executable
- I can run the scripts manually (with the environment variables
RENEWED_DOMAINS
andRENEWED_LINEAGE
set and exported) and they do their job as expected
One other thing that I probably should mention is that I run Certbot within a Docker image because I am working with wildcard certificates. My DNS provider is Cloudflare. Here's the command line that I am using to start the renewal process:
docker run -it --rm --name certbot \ -v "/etc/letsencrypt:/etc/letsencrypt" \ -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ certbot/dns-cloudflare renew
The Docker image runs Certbot version 0.25.0. The system is Debian 9 (stretch), recently upgraded from Debian 8 (jessie).
Any clues what the problem could be?
EDIT: As requested, here is the content of the two files, slightly edited to replace my domain with "example.com":
root@pelargir:~# cat /etc/letsencrypt/renewal-hooks/post/10-setup-courier.sh #!/bin/bash # Exit immediately if a command exits with non-zero status set -e case $RENEWED_DOMAINS in # Courier runs only under a example.com subdomain example.com) # We don't care about file permissions because we know that the # filesystem folder where we generate the file is not generally # accessible cat "$RENEWED_LINEAGE/fullchain.pem" "$RENEWED_LINEAGE/privkey.pem" >"$RENEWED_LINEAGE/courier.cert-and-key.unsecure" ;; esac root@pelargir:~# cat /etc/letsencrypt/renewal-hooks/post/20-restart-services.sh #!/bin/bash # Exit immediately if a command exits with non-zero status set -e case $RENEWED_DOMAINS in # Courier and Exim run only under a example.com subdomain *example.com*) systemctl restart courier-imap.service systemctl restart exim4.service systemctl restart apache2.service ;; # Apache has vhosts for all domains. Unfortunately the daemon is # restarted several times if several certificates are renewed. *) systemctl restart apache2.service ;; esac
-
herzbube over 5 yearssigh So obvious. After fixing the problem I now found out that, of course, I cannot restart system services from within the Docker container. I have to work more with Docker...
-
Michael Hampton over 5 yearsA certbot container is useful for managing certificates for another related container, but it's probably not so useful if you're managing certificates for things running on the container host.