Por que o Certbot não consegue executar scripts pós-hook?

Por que o Certbot não consegue executar scripts pós-hook?

Esta é minha primeira tentativa de renovar certificados Let's Encrypt via Certbot. Depois de ler atentamente o guia do usuário do Certbot, criei dois scripts de pós-gancho como este:

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

Em seguida, executei o processo de renovação manualmente na linha de comando (ou seja, não via cron). Isso foi bem-sucedido na renovação dos certificados, mas não conseguiu executar os scripts pós-gancho acima. Aqui está a saída relevante:

[...]
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
[...]

Não tenho ideia de por que isso acontece. Eu verifiquei novamente:

  • Os arquivos de script existem
  • Os arquivos de script são executáveis
  • Posso executar os scripts manualmente (com as variáveis ​​de ambiente definidas RENEWED_DOMAINSe RENEWED_LINEAGEexportadas) e eles fazem seu trabalho conforme o esperado

Outra coisa que provavelmente devo mencionar é que executo o Certbot em uma imagem do Docker porque estou trabalhando com certificados curinga. Meu provedor de DNS é Cloudflare. Esta é a linha de comando que estou usando para iniciar o processo de renovação:

docker run -it --rm --name certbot \
           -v "/etc/letsencrypt:/etc/letsencrypt" \
           -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
           certbot/dns-cloudflare
           renew

A imagem Docker executa o Certbot versão 0.25.0. O sistema é o Debian 9 (stretch), recentemente atualizado do Debian 8 (jessie).

Alguma pista de qual poderia ser o problema?


EDIT: Conforme solicitado, aqui está o conteúdo dos dois arquivos, ligeiramente editados para substituir meu domínio por "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

Responder1

Seus scripts de shell usam um shebang #!/bin/bash, o que significa que devem ser executados com esse programa, mas o contêiner Docker no qual eles são executados não inclui o bash. É por isso que /bin/shrelata o not founderro confuso ao chamar esses scripts obviamente presentes. Não são os scripts que não foram encontrados, mas o interpretador bash com o qual você pediu para executá-los.

Você pode resolver o problema alterando o interpretador de script /bin/she removendo quaisquer bash-ismos dos scripts (provavelmente rápido e fácil) ou instalando o bash no contêiner (provavelmente confuso).

informação relacionada