acme.sh: move to procd to ensure logging gets to syslog
authorAditya Bhargava <[email protected]>
Mon, 22 Sep 2025 07:56:17 +0000 (03:56 -0400)
committerToke Høiland-Jørgensen <[email protected]>
Wed, 8 Oct 2025 18:27:32 +0000 (20:27 +0200)
acme.sh error output never made it to the syslog, so:
* Add procd setup to catch stderr
* Make sure a message goes to syslog if acme.sh dies due to SIGINT

Signed-off-by: Aditya Bhargava <[email protected]>
net/acme-acmesh/files/hook.sh
net/acme-common/files/acme.init
net/acme-common/files/functions.sh

index 2143594463829930f8d0f22a2da703520c791382..0bca1f19aa25fa3bb01c27d8143e6f6f9dc4aeca 100644 (file)
@@ -67,7 +67,7 @@ get)
                else
                        set -- "$@" --renew --home "$state_dir" -d "$main_domain"
                        log info "$ACME $*"
-                       trap '$NOTIFY renew-failed;exit 1' INT
+                       trap 'log err "Renew failed: SIGINT";$NOTIFY renew-failed;exit 1' INT
                        $ACME "$@"
                        status=$?
                        trap - INT
@@ -141,7 +141,7 @@ get)
        set -- "$@" --issue --home "$state_dir"
 
        log info "$ACME $*"
-       trap '$NOTIFY issue-failed;exit 1' INT
+       trap 'log err "Issue failed: SIGINT";$NOTIFY issue-failed;exit 1' INT
        "$ACME" "$@" \
                --pre-hook "$NOTIFY prepare" \
                --renew-hook "$NOTIFY renewed"
index be29631917b78ad42ce20a04ef9b09f5a0acca28..5d441f2325385033a2e7054f926f152cead09a8c 100644 (file)
@@ -36,15 +36,15 @@ load_options() {
        if [ -z "$staging" ]; then
                config_get_bool staging "$section" use_staging 0
        fi
-       export staging
+       procd_append_param env staging="$staging"
        config_get calias "$section" calias
-       export calias
+       procd_append_param env calias="$calias"
        config_get dalias "$section" dalias
-       export dalias
+       procd_append_param env dalias="$dalias"
        config_get domains "$section" domains
-       export domains
+       procd_append_param env domains="$domains"
        main_domain="$(first_arg $domains)"
-       export main_domain
+       procd_append_param env main_domain="$main_domain"
        config_get keylength "$section" keylength
        if [ "$keylength" ]; then
                log warn "Option \"keylength\" is deprecated, please use key_type (e.g., ec256, rsa2048) instead."
@@ -55,24 +55,38 @@ load_options() {
        else
                config_get key_type "$section" key_type ec256
        fi
-       export key_type
-       config_get dns "$section" dns
-       export dns
+       procd_append_param env key_type="$key_type"
        config_get acme_server "$section" acme_server
-       export acme_server
+       procd_append_param env acme_server="$acme_server"
        config_get days "$section" days
-       export days
-       config_get standalone "$section" standalone
-       [ -n "$standalone" ] && log warn "Option \"standalone\" is deprecated."
+       procd_append_param env days="$days"
        config_get dns_wait "$section" dns_wait
-       export dns_wait
+       procd_append_param env dns_wait="$dns_wait"
        config_get webroot "$section" webroot
        if [ "$webroot" ]; then
                log warn "Option \"webroot\" is deprecated, please remove it and change your web server's config so it serves ACME challenge requests from $CHALLENGE_DIR."
                CHALLENGE_DIR=$webroot
        fi
+}
+
+first_arg() {
+       echo "$1"
+}
+
+get_cert() {
+       section=$1
+
+       config_get_bool enabled "$section" enabled 1
+       [ "$enabled" = 1 ] || return
 
+       # load `listen_port` here rather than in `load_options` so we can
+       # return early without leaving a dangling `procd_open_instance`; the
+       # check requires loading `validation_method` as well, which in turn
+       # requires loading `dns` and `standalone`
        config_get validation_method "$section" validation_method
+       config_get dns "$section" dns
+       config_get standalone "$section" standalone
+       [ -n "$standalone" ] && log warn "Option \"standalone\" is deprecated."
        # if validation_method isn't set then guess it
        if [ -z "$validation_method" ]; then
                if [ -n "$dns" ]; then
@@ -84,8 +98,9 @@ load_options() {
                fi
                log warn "Please set \"option validation_method $validation_method\"."
        fi
-       export validation_method
-
+       if [ "$validation_method" = "webroot" ]; then
+               mkdir -p "$CHALLENGE_DIR"
+       fi
        case "$validation_method" in
        standalone)
                config_get listen_port "$section" listen_port 80
@@ -97,24 +112,6 @@ load_options() {
                config_get listen_port "$section" listen_port
                ;;
        esac
-       export listen_port
-}
-
-first_arg() {
-       echo "$1"
-}
-
-get_cert() {
-       section=$1
-
-       config_get_bool enabled "$section" enabled 1
-       [ "$enabled" = 1 ] || return
-
-       load_options "$section"
-       if [ "$validation_method" = "webroot" ]; then
-               mkdir -p "$CHALLENGE_DIR"
-       fi
-
        if [ "$listen_port" != "$LAST_LISTEN_PORT" ]; then
                delete_nft_rule
 
@@ -128,15 +125,27 @@ get_cert() {
                LAST_LISTEN_PORT="$listen_port"
        fi
 
+       procd_open_instance "$section"
+       procd_set_param command "$HOOK" get
+       procd_set_param stdout 1
+       procd_set_param stderr 1
+       procd_set_param env CHALLENGE_DIR="$CHALLENGE_DIR" CERT_DIR="$CERT_DIR"
+       procd_append_param env account_email="$account_email" state_dir="$state_dir" debug="$debug"
+       procd_append_param env dns="$dns" validation_method="$validation_method" listen_port="$listen_port"
+
+       load_options "$section"
+
        load_credentials() {
-               eval export "$1"
+               eval procd_append_param env "$1"
        }
        config_list_foreach "$section" credentials load_credentials
 
-       "$HOOK" get
+       procd_close_instance
 }
 
 load_globals() {
+       [ -z "$account_email" ] || return 1  # only read the first acme section
+
        section=$1
 
        config_get account_email "$section" account_email
@@ -157,15 +166,9 @@ load_globals() {
 
        config_get_bool debug "$section" debug 0
        export debug
-
-       # only look for the first acme section
-       return 1
 }
 
 start_service() {
-       mkdir -p $run_dir
-       mkdir -p "$CHALLENGE_DIR"
-
        grep -q '/etc/init.d/acme' /etc/crontabs/root 2>/dev/null || {
                echo "0 0 * * * /etc/init.d/acme renew" >>/etc/crontabs/root
        }
@@ -188,7 +191,7 @@ service_triggers() {
                /etc/init.d/acme renew
 }
 
-renew() {
+load_and_run() {
        trap cleanup EXIT
 
        config_load acme
@@ -196,3 +199,7 @@ renew() {
 
        config_foreach get_cert cert
 }
+
+renew() {
+       rc_procd load_and_run
+}
index 5828a6b1f8eb34283023a1379ecfe27d20a71b88..853782a60f28ed235d28cad4d6b9f4e6ab1173d2 100644 (file)
@@ -2,6 +2,6 @@ log() {
        prio="$1"
        shift
        if [ "$prio" != debug ] || [ "$debug" = 1 ]; then
-               logger -t "$LOG_TAG" -s -p "daemon.$prio" -- "$@"
+               logger -t "$LOG_TAG" -p "daemon.$prio" -- "$@"
        fi
 }