Это моя первая попытка обновления сертификатов Let's Encrypt через Certbot. После внимательного прочтения руководства пользователя Certbot я создал два скрипта post hook, например:
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
Затем я запустил процесс обновления вручную в командной строке (т.е. не через cron). Это успешно обновило сертификаты, но не удалось выполнить вышеуказанные скрипты post hook. Вот соответствующий вывод:
[...]
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
[...]
Понятия не имею, почему это происходит. Я перепроверил:
- Файлы скриптов существуют
- Файлы скриптов являются исполняемыми.
- Я могу запустить скрипты вручную (с заданными и экспортированными переменными среды
RENEWED_DOMAINS
)RENEWED_LINEAGE
, и они выполняют свою работу так, как и ожидалось.
Еще одна вещь, о которой я, вероятно, должен упомянуть, это то, что я запускаю Certbot в образе Docker, поскольку работаю с wildcard-сертификатами. Мой DNS-провайдер — Cloudflare. Вот командная строка, которую я использую для запуска процесса обновления:
docker run -it --rm --name certbot \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
certbot/dns-cloudflare
renew
Образ Docker запускает Certbot версии 0.25.0. Система — Debian 9 (stretch), недавно обновленная с Debian 8 (jessie).
Есть ли какие-нибудь подсказки, в чем может быть проблема?
EDIT: Как и просили, вот содержимое двух файлов, слегка отредактированное для замены моего домена на «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
решение1
Ваши скрипты оболочки используют shebang #!/bin/bash
, то есть они должны быть выполнены с помощью этой программы, но контейнер Docker, в котором они запущены, не включает bash. Вот почему /bin/sh
сообщает о запутанной not found
ошибке при вызове этих явно присутствующих скриптов. Не найдены не скрипты, а интерпретатор bash, с помощью которого вы просили их запустить.
Вы можете решить эту проблему, изменив интерпретатор скриптов /bin/sh
и удалив все bash-измы из скриптов (вероятно, это быстро и просто), или установив bash в контейнер (вероятно, это будет запутанно).