Это моя первая попытка обновить сертификаты Let's Encrypt через Certbot. Внимательно прочитав руководство пользователя Certbot, я создал два таких сценария сообщений:
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). Сертификаты были обновлены успешно, но не удалось выполнить указанные выше сценарии обработки сообщений. Вот соответствующий результат:
[...]
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, потому что я работаю с сертификатами с подстановочными знаками. Мой 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).
Есть какие-нибудь подсказки, в чем может быть проблема?
РЕДАКТИРОВАТЬ: В соответствии с запросом, вот содержимое двух файлов, слегка отредактированное, чтобы заменить мой домен на «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
Ваши сценарии оболочки используют shebang #!/bin/bash
, что означает, что они должны выполняться с этой программой, но контейнер Docker, в котором они работают, не включает bash. Вот почему /bin/sh
сообщает о запутанных not found
ошибка при вызове этих явно присутствующих скриптов. Не найдены не сценарии, а интерпретатор bash, с которым вы их просили запустить.
Вы можете решить проблему, изменив интерпретатор скрипта на /bin/sh
и удаление любых bash-isms из скриптов (возможно, быстро и легко) или путем установки bash в контейнер (возможно, беспорядочно).