Назад | Перейти на главную страницу

Почему Certbot не запускает сценарии обработки сообщений?

Это моя первая попытка обновить сертификаты 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
[...]

Понятия не имею, почему это происходит. Я перепроверил:

Еще одна вещь, о которой я, вероятно, должен упомянуть, - это то, что я запускаю 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 в контейнер (возможно, беспорядочно).