Lets-Encrypt
為什麼 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
您的 shell 腳本使用 shebang
#!/bin/bash
,這意味著它們將與該程序一起執行,但它們執行的 Docker 容器不包含 bash。這就是為什麼在呼叫這些明顯存在的腳本時會/bin/sh
報告令人困惑的錯誤。not found
不是找不到腳本,而是您要求執行它們的 bash 解釋器。您可以通過將腳本解釋器更改為
/bin/sh
並從腳本中刪除任何 bash-isms(可能快速而簡單)或在容器中安裝 bash(可能很混亂)來解決問題。