diff --git a/net/acme-common/Makefile b/net/acme-common/Makefile index c8c4a0bb38992..49e5f76f7ee2a 100644 --- a/net/acme-common/Makefile +++ b/net/acme-common/Makefile @@ -38,8 +38,6 @@ define Package/acme-common/install $(INSTALL_DIR) $(1)/etc/ssl/acme $(INSTALL_DIR) $(1)/etc/config $(INSTALL_CONF) ./files/acme.config $(1)/etc/config/acme - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) ./files/acme.sh $(1)/usr/bin/acme $(INSTALL_DIR) $(1)/usr/lib/acme $(INSTALL_DATA) ./files/functions.sh $(1)/usr/lib/acme $(INSTALL_BIN) ./files/acme-notify.sh $(1)/usr/lib/acme/notify @@ -50,15 +48,15 @@ define Package/acme-common/install $(INSTALL_DIR) $(1)/etc/hotplug.d/acme endef -define Package/acme/postinst +define Package/acme-common/postinst #!/bin/sh -grep -q '/usr/bin/acme' /etc/crontabs/root 2>/dev/null && exit 0 -echo "0 0 * * * /usr/bin/acme get" >> /etc/crontabs/root +grep -q '/etc/init.d/acme' /etc/crontabs/root 2>/dev/null && exit 0 +echo "0 0 * * * /etc/init.d/acme start" >> /etc/crontabs/root endef define Package/acme-common/prerm #!/bin/sh -sed -i '\|/usr/bin/acme|d' /etc/crontabs/root +sed -i '\|/etc/init.d/acme|d' /etc/crontabs/root endef define Build/Configure diff --git a/net/acme-common/files/acme.init b/net/acme-common/files/acme.init index e654054f4c263..1bca639f492c8 100644 --- a/net/acme-common/files/acme.init +++ b/net/acme-common/files/acme.init @@ -1,9 +1,137 @@ #!/bin/sh /etc/rc.common -START=80 USE_PROCD=1 +run_dir=/var/run/acme +export CHALLENGE_DIR=$run_dir/challenge +export CERT_DIR=/etc/ssl/acme +NFT_HANDLE= +HOOK=/usr/lib/acme/hook +LOG_TAG=acme + +# shellcheck source=net/acme/files/functions.sh +. /usr/lib/acme/functions.sh + +cleanup() { + log debug "cleaning up" + if [ -e $run_dir/lock ]; then + rm $run_dir/lock + fi + if [ "$NFT_HANDLE" ]; then + # $NFT_HANDLE contains the string 'handle XX' so pass it unquoted to nft + nft delete rule inet fw4 input $NFT_HANDLE + fi +} + +load_options() { + section=$1 + + # compatibility for old option name + config_get_bool staging "$section" use_staging + if [ -z "$staging" ]; then + config_get_bool staging "$section" staging 0 + fi + export staging + config_get calias "$section" calias + export calias + config_get dalias "$section" dalias + export dalias + config_get domains "$section" domains + export domains + export main_domain + main_domain="$(first_arg $domains)" + config_get keylength "$section" keylength ec-256 + export keylength + config_get dns "$section" dns + export dns + config_get acme_server "$section" acme_server + export acme_server + config_get days "$section" days + export days + config_get standalone "$section" standalone 0 + export standalone + config_get dns_wait "$section" dns_wait + export dns_wait + + config_get webroot "$section" webroot + export 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." + fi +} + +first_arg() { + echo "$1" +} + +get_cert() { + section=$1 + + config_get_bool enabled "$section" enabled 1 + [ "$enabled" = 1 ] || return + + load_options "$section" + if [ -z "$dns" ] && [ "$standalone" = 0 ]; then + mkdir -p "$CHALLENGE_DIR" + fi + + if [ "$standalone" = 1 ] && [ -z "$NFT_HANDLE" ]; then + if ! NFT_HANDLE=$(nft -a -e insert rule inet fw4 input tcp dport 80 counter accept comment ACME | grep -o 'handle [0-9]\+'); then + return 1 + fi + log debug "added nft rule: $NFT_HANDLE" + fi + + load_credentials() { + eval export "$1" + } + config_list_foreach "$section" credentials load_credentials + + "$HOOK" get +} + +load_globals() { + section=$1 + + config_get account_email "$section" account_email + if [ -z "$account_email" ]; then + log err "account_email option is required" + exit 1 + fi + export account_email + + config_get state_dir "$section" state_dir + if [ "$state_dir" ]; then + log warn "Option \"state_dir\" is deprecated, please remove it. Certificates now exist in $CERT_DIR." + mkdir -p "$state_dir" + else + state_dir=/etc/acme + fi + export state_dir + + config_get debug "$section" debug 0 + export debug + + # only look for the first acme section + return 1 +} + +start_service() { + mkdir -p $run_dir + exec 200>$run_dir/lock + if ! flock -n 200; then + log err "Another ACME instance is already running." + exit 1 + fi + + trap cleanup EXIT + + config_load acme + config_foreach load_globals acme + + config_foreach get_cert cert +} service_triggers() { procd_add_config_trigger config.change acme \ - /usr/bin/acme get + /etc/init.d/acme start } diff --git a/net/acme-common/files/acme.sh b/net/acme-common/files/acme.sh deleted file mode 100644 index defd660059f57..0000000000000 --- a/net/acme-common/files/acme.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/bin/sh -# Wrapper for acme.sh to work on openwrt. -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free Software -# Foundation; either version 3 of the License, or (at your option) any later -# version. -# -# Authors: Toke Høiland-Jørgensen - -run_dir=/var/run/acme -export CHALLENGE_DIR=$run_dir/challenge -export CERT_DIR=/etc/ssl/acme -NFT_HANDLE= -HOOK=/usr/lib/acme/hook -LOG_TAG=acme - -# shellcheck source=/dev/null -. /lib/functions.sh -# shellcheck source=net/acme/files/functions.sh -. /usr/lib/acme/functions.sh - -cleanup() { - log debug "cleaning up" - if [ -e $run_dir/lock ]; then - rm $run_dir/lock - fi - if [ "$NFT_HANDLE" ]; then - # $NFT_HANDLE contains the string 'handle XX' so pass it unquoted to nft - nft delete rule inet fw4 input $NFT_HANDLE - fi -} - -load_options() { - section=$1 - - # compatibility for old option name - config_get_bool staging "$section" use_staging - if [ -z "$staging" ]; then - config_get_bool staging "$section" staging 0 - fi - export staging - config_get calias "$section" calias - export calias - config_get dalias "$section" dalias - export dalias - config_get domains "$section" domains - export domains - export main_domain - main_domain="$(first_arg $domains)" - config_get keylength "$section" keylength ec-256 - export keylength - config_get dns "$section" dns - export dns - config_get acme_server "$section" acme_server - export acme_server - config_get days "$section" days - export days - config_get standalone "$section" standalone 0 - export standalone - config_get dns_wait "$section" dns_wait - export dns_wait - - config_get webroot "$section" webroot - export 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." - fi -} - -first_arg() { - echo "$1" -} - -get_cert() { - section=$1 - - config_get_bool enabled "$section" enabled 1 - [ "$enabled" = 1 ] || return - - load_options "$section" - if [ -z "$dns" ] && [ "$standalone" = 0 ]; then - mkdir -p "$CHALLENGE_DIR" - fi - - if [ "$standalone" = 1 ] && [ -z "$NFT_HANDLE" ]; then - if ! NFT_HANDLE=$(nft -a -e insert rule inet fw4 input tcp dport 80 counter accept comment ACME | grep -o 'handle [0-9]\+'); then - return 1 - fi - log debug "added nft rule: $NFT_HANDLE" - fi - - load_credentials() { - eval export "$1" - } - config_list_foreach "$section" credentials load_credentials - - "$HOOK" get -} - -load_globals() { - section=$1 - - config_get account_email "$section" account_email - if [ -z "$account_email" ]; then - log err "account_email option is required" - exit 1 - fi - export account_email - - config_get state_dir "$section" state_dir - if [ "$state_dir" ]; then - log warn "Option \"state_dir\" is deprecated, please remove it. Certificates now exist in $CERT_DIR." - mkdir -p "$state_dir" - else - state_dir=/etc/acme - fi - export state_dir - - config_get debug "$section" debug 0 - export debug - - # only look for the first acme section - return 1 -} - -usage() { - cat < [arguments] -Commands: - get issue or renew certificates -EOF - exit 1 -} - -if [ ! -x "$HOOK" ]; then - log err "An ACME client like acme-acmesh or acme-uacme is required, which is not installed." - exit 1 -fi - -case $1 in -get) - mkdir -p $run_dir - exec 200>$run_dir/lock - if ! flock -n 200; then - log err "Another ACME instance is already running." - exit 1 - fi - - trap cleanup EXIT - - config_load acme - config_foreach load_globals acme - - config_foreach get_cert cert - ;; -*) - usage - ;; -esac diff --git a/net/acme-common/files/acme.uci-defaults b/net/acme-common/files/acme.uci-defaults index 0b92c2e26591c..206f87e23d1c6 100644 --- a/net/acme-common/files/acme.uci-defaults +++ b/net/acme-common/files/acme.uci-defaults @@ -1,4 +1,4 @@ #!/bin/sh -grep -q '/usr/bin/acme' /etc/crontabs/root 2>/dev/null && exit 0 -echo "0 0 * * * /usr/bin/acme get" >> /etc/crontabs/root +grep -q '/etc/init.d/acme' /etc/crontabs/root 2>/dev/null && exit 0 +echo "0 0 * * * /etc/init.d/acme start" >>/etc/crontabs/root diff --git a/net/acme-common/files/functions.sh b/net/acme-common/files/functions.sh index 3325a7ea2ca3a..5828a6b1f8eb3 100644 --- a/net/acme-common/files/functions.sh +++ b/net/acme-common/files/functions.sh @@ -1,7 +1,7 @@ log() { prio="$1" shift - if [ "$prio" != debug ] || [ "$debug" = 0 ]; then + if [ "$prio" != debug ] || [ "$debug" = 1 ]; then logger -t "$LOG_TAG" -s -p "daemon.$prio" -- "$@" fi }