Certbot이 포스트 후크 스크립트를 실행하지 못하는 이유는 무엇입니까?

Certbot이 포스트 후크 스크립트를 실행하지 못하는 이유는 무엇입니까?

이것은 Certbot을 통해 Let's Encrypt 인증서를 갱신하려는 첫 번째 시도입니다. 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설정하고 내보낸 스크립트를 수동으로 실행할 수 있으며 예상대로 작업을 수행합니다.

제가 언급해야 할 또 다른 점은 와일드카드 인증서로 작업하고 있기 때문에 Docker 이미지 내에서 Certbot을 실행한다는 것입니다. 내 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

답변1

쉘 스크립트는 shebang 을 사용합니다 #!/bin/bash. 즉, 해당 프로그램으로 실행되지만 스크립트가 실행되는 Docker 컨테이너에는 bash가 포함되어 있지 않습니다. 이것이 명백히 존재하는 스크립트를 호출할 때 /bin/sh혼란스러운 오류를 보고하는 이유입니다 . not found발견되지 않은 것은 스크립트가 아니라 실행을 요청한 bash 인터프리터입니다.

스크립트 해석기를 변경하고 /bin/sh스크립트에서 bash-isms를 제거하거나(아마도 빠르고 쉬움) 컨테이너에 bash를 설치하여(아마도 지저분함) 문제를 해결할 수 있습니다.

관련 정보