これは、Certbot 経由で Let's Encrypt 証明書を更新する初めての試みです。Certbot ユーザー ガイドを注意深く読んだ後、次のような 2 つのポスト フック スクリプトを作成しました。
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
エクスポートします)。スクリプトは期待どおりに機能します。
もう 1 つ言及しておくべきことは、ワイルドカード証明書を使用しているため、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」に置き換えるために少し編集した 2 つのファイルの内容を以下に示します。
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 関連の要素を削除する (おそらく迅速かつ簡単) か、コンテナーに bash をインストールする (おそらく面倒) ことで解決できます。