Lets-Encrypt
使用 Let’s Encrypt certbot 時,如何僅在證書實際更新時才重新啟動/重新載入網路服務?
該
certbot
命令提供了兩個在自動續訂後執行的掛鉤,來自文件:--post-hook POST_HOOK Command to be run in a shell after attempting to obtain/renew certificates. Can be used to deploy renewed certificates, or to restart any servers that were stopped by --pre-hook. This is only run if an attempt was made to obtain/renew a certificate. If multiple renewed certificates have identical post- hooks, only one will be run. (default: None) --deploy-hook DEPLOY_HOOK Command to be run in a shell once for each successfully issued certificate. For this command, the shell variable $RENEWED_LINEAGE will point to the config live subdirectory (for example, "/etc/letsencrypt/live/example.com") containing the new certificates and keys; the shell variable $RENEWED_DOMAINS will contain a space-delimited list of renewed certificate domains (for example, "example.com www.example.com" (default: None)
這個問題在這個(現已關閉的)LE 執行緒中進行了概述,基本上是關於最大限度地減少對服務的中斷。
POST_HOOK
每次嘗試更新時都會執行,即使沒有頒發證書,但只有一次。這使得不必要地重新啟動服務成為可能。DEPLOY_HOOK
為每個成功的證書續訂執行。如果一個人使用DEPLOY_HOOK
, 並且有多個證書,則每個服務可能會在一次足夠的情況下重新啟動多次。有關更新掛鉤的更多資訊,請點擊此處。我使用一種完全不會中斷我的服務的發行方法,例如:
certbot certonly --webroot ...
或者
certbot certonly --dns-PROVIDER ...
我只想重新啟動/重新載入每個依賴服務一次,並且只有在其證書實際更改的情況下。
通過使用兩個鉤子和一個簡單的腳本來保存狀態,我能夠克服這個限制。例如,要重新載入 nginx,並在他們都使用的證書被更新時重新啟動 vsftpd:
certbot certonly ... \ --deploy-hook '/usr/local/sbin/read-new-certs-services nginx --restart vsftpd' \ --post-hook /usr/local/sbin/read-new-certs-services
腳本
/usr/local/sbin/read-new-certs-services
是這樣的:#!/bin/sh run_base=/run dir_reloads="$run_base/new-cert-reloads" dir_restarts="$run_base/new-cert-restarts" if [ $# -gt 0 ]; then some=0 dir="$dir_reloads" while [ $# -gt 0 ]; do case $1 in -h|--help) >&2 cat <<-'EOHELP' Usage: read-new-certs-services [-l|-s] service1 [[-l|-s] service2] or read-new-certs-services When called without arguments, marked services will be reloaded or restarted. Arguments: -h, --help This help. -l, --reload Mark all subsequently listed services for reloading. -s, --restart Mark all subsequently listed services for restarting. EOHELP exit ;; -l|--reload) dir="$dir_reloads" ;; -s|--restart) dir="$dir_restarts" ;; *) if [ -n "$1" ]; then some=1 run_file="$dir/$1" if [ ! -f "$run_file" ] && ! install -D /dev/null "$run_file"; then >&2 echo "Service could not be marked: $run_file" exit 1 fi fi ;; esac shift done if [ $some -eq 0 ]; then >&2 echo 'No service(s) specified.' exit 1 fi exit fi if [ -d "$dir_restarts" ]; then find "$dir_restarts" -mindepth 1 -printf '%P\t%p\n' | while IFS="$(printf '\t')" read -r svc run_file; do systemctl restart "$svc" && rm "$run_file" # no need to reload if restarting run_file="$dir_reloads/$svc" if [ -f "$run_file" ]; then rm "$run_file" fi done fi if [ -d "$dir_reloads" ]; then find "$dir_reloads" -mindepth 1 -printf '%P\t%p\n' | while IFS="$(printf '\t')" read -r svc run_file; do systemctl reload "$svc" && rm "$run_file" done fi
這必須用於每個證書問題,以便他們不會使用衝突的重新啟動服務的方法。
您可以更改現有證書續訂以使用此方法,方法是編輯其
/etc/letsencrypt/renewal/*.conf
文件以包含如下[renewalparams]
部分中的鉤子:renew_hook = /usr/local/sbin/read-new-certs-services nginx -s vsftpd post_hook = /usr/local/sbin/read-new-certs-services