Este es mi primer intento de renovar los certificados Let's Encrypt a través de Certbot. Después de leer detenidamente la guía del usuario de Certbot, creé dos scripts de enlace de publicación 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
Luego ejecuté el proceso de renovación manualmente en la línea de comando (es decir, no mediante cron). Esto logró renovar los certificados, pero no pudo ejecutar los scripts de enlace de publicación anteriores. Aquí está el resultado 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
[...]
No tengo idea de por qué sucede esto. Verifiqué dos veces:
- Los archivos de script existen
- Los archivos de script son ejecutables.
- Puedo ejecutar los scripts manualmente (con las variables de entorno configuradas
RENEWED_DOMAINS
yRENEWED_LINEAGE
exportadas) y hacen su trabajo como se esperaba.
Otra cosa que probablemente debería mencionar es que ejecuto Certbot dentro de una imagen de Docker porque estoy trabajando con certificados comodín. Mi proveedor de DNS es Cloudflare. Aquí está la línea de comando que estoy usando para iniciar el proceso de renovación:
docker run -it --rm --name certbot \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
certbot/dns-cloudflare
renew
La imagen de Docker ejecuta Certbot versión 0.25.0. El sistema es Debian 9 (stretch), recientemente actualizado desde Debian 8 (jessie).
¿Alguna pista de cuál podría ser el problema?
EDITAR: Según lo solicitado, aquí está el contenido de los dos archivos, ligeramente editado para reemplazar mi dominio con "ejemplo.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
Respuesta1
Sus scripts de shell usan un shebang #!/bin/bash
, lo que significa que deben ejecutarse con ese programa, pero el contenedor Docker en el que se ejecutan no incluye bash. Es por eso que /bin/sh
informa el not found
error confuso al llamar a estos scripts obviamente presentes. No son los scripts los que no se encuentran, sino el intérprete de bash con el que solicitó ejecutarlos.
Puede resolver el problema cambiando el intérprete de scripts /bin/sh
y eliminando cualquier bash-ismo de los scripts (probablemente rápido y fácil), o instalando bash en el contenedor (probablemente desordenado).