이것은 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를 설치하여(아마도 지저분함) 문제를 해결할 수 있습니다.