diff --git a/build.sh b/build.sh index 7c40641..355e021 100755 --- a/build.sh +++ b/build.sh @@ -91,10 +91,14 @@ cp "$MOUNT/usr/src/acme-mgmt/src/acme-issue" "$MOUNT/usr/local/bin/acme-issue" echo + "cp …/usr/src/acme-mgmt/src/acme-renew …/usr/local/bin/acme-renew" >&2 cp "$MOUNT/usr/src/acme-mgmt/src/acme-renew" "$MOUNT/usr/local/bin/acme-renew" +echo + "cp …/usr/src/acme-mgmt/src/acme-check …/usr/local/bin/acme-check" >&2 +cp "$MOUNT/usr/src/acme-mgmt/src/acme-check" "$MOUNT/usr/local/bin/acme-check" + cmd buildah run "$CONTAINER" -- \ chmod 755 \ "/usr/local/bin/acme-issue" \ - "/usr/local/bin/acme-renew" + "/usr/local/bin/acme-renew" \ + "/usr/local/bin/acme-check" echo + "cp …/usr/src/acme-mgmt/conf/config.env …/usr/local/share/acme/config.env" >&2 cp "$MOUNT/usr/src/acme-mgmt/conf/config.env" "$MOUNT/usr/local/share/acme/config.env" diff --git a/container.env b/container.env index c3a6d94..27ceef6 100644 --- a/container.env +++ b/container.env @@ -8,9 +8,9 @@ ACME_TINY_GIT_REPO="https://github.com/diafygi/acme-tiny.git" ACME_TINY_GIT_REF="refs/tags/$ACME_TINY_VERSION" ACME_TINY_GIT_COMMIT="1858f68204983d86d3bb8f51463af91301965322" -ACME_MGMT_VERSION="1.9" +ACME_MGMT_VERSION="1.10" ACME_MGMT_GIT_REPO="https://github.com/PhrozenByte/acme.git" ACME_MGMT_GIT_REF="refs/tags/v$ACME_MGMT_VERSION" -ACME_MGMT_GIT_COMMIT="cd8028646ead184be8958adef3d1ec97d28aec3c" +ACME_MGMT_GIT_COMMIT="dee583257bc90436d7949973424e29f4f4a98e8a" BASE_IMAGE="ghcr.io/sgsgermany/alpine:v3.18" diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 7420ab6..f74ca76 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -12,7 +12,9 @@ set -e -if [ $# -eq 0 ] || [ "$1" == "crond" ] || [ "$1" == "acme-issue" ] || [ "$1" == "acme-renew" ]; then +if [ $# -eq 0 ] || [ "$1" == "crond" ] \ + || [ "$1" == "acme-issue" ] || [ "$1" == "acme-renew" ] || [ "$1" == "acme-check" ] +then # runtime setup /usr/local/lib/acme/acme-setup @@ -21,7 +23,7 @@ if [ $# -eq 0 ] || [ "$1" == "crond" ] || [ "$1" == "acme-issue" ] || [ "$1" == exec crond -f -l 7 -L /dev/stdout fi - # run acme-issue, or acme-renew + # run acme-issue, acme-renew, or acme-check exec su -p -s /bin/sh acme -c '"$@"' -- '/bin/sh' "$@" fi diff --git a/src/etc/crontabs/.gitignore b/src/etc/crontabs/.gitignore new file mode 100644 index 0000000..adfe48c --- /dev/null +++ b/src/etc/crontabs/.gitignore @@ -0,0 +1 @@ +# This directory is empty by default diff --git a/src/etc/crontabs/acme b/src/etc/crontabs/acme deleted file mode 100644 index e260780..0000000 --- a/src/etc/crontabs/acme +++ /dev/null @@ -1 +0,0 @@ -0 0 1 * * acme-renew --all --retry --clean --verbose diff --git a/src/usr/local/lib/acme/acme-setup b/src/usr/local/lib/acme/acme-setup index 45ee1e1..7ecf6b3 100755 --- a/src/usr/local/lib/acme/acme-setup +++ b/src/usr/local/lib/acme/acme-setup @@ -71,4 +71,53 @@ if [ ! -f "/etc/acme/config.env" ]; then [ -z "${ACME_ACCOUNT_CONTACT:-}" ] || __config_set ACME_ACCOUNT_CONTACT "$ACME_ACCOUNT_CONTACT" [ -z "${ACME_DIRECTORY_URL:-}" ] || __config_set ACME_DIRECTORY_URL "$ACME_DIRECTORY_URL" [ -z "${TLS_KEY_GROUP:-}" ] || __config_set TLS_KEY_GROUP "$TLS_KEY_GROUP" + [ -z "${FP_REVOCATION_LIST:-}" ] || __config_set FP_REVOCATION_LIST "$FP_REVOCATION_LIST" +fi + +# create crontab file, if necessary +if [ ! -f "/etc/crontabs/acme" ]; then + __is_cron_valid() { + [ -n "$1" ] && [[ "$1 " =~ ^(((\d+|\*)(/\d+)?|\d+-\d+)(,((\d+|\*)(/\d+)?|\d+-\d+))* ){5}$ ]] + } + + __crontabs() { + local HASH="$(md5sum - <<< "$1")" + local MONTHLY_CRON="$2" MONTHLY_CMD="$3" + local DAILY_CRON="$4" DAILY_CMD="$5" + + # TIME represents the `n`th minute of the month (e.g. 12,345 is the 9th day at 13:45) + # since the cronjob wouldn't run in February otherwise, we accept the 28th day max, + # thus we perform an euclidean division by 28 days * 24 hours * 60 minutes = 40,320 + local TIME=$(( 0x${HASH:0:14} % 40320 )) + + # DAILY_TIME_OFFSET represents a `n` minute offset from TIME's time of day + # the daily cronjob shall run between 00:30 and 23:30 hours later than the monthly cronjob, + # thus we perform an euclidean division by 24 hours * 60 minutes - 2 * 30 minutes + 1 = 1,381 + # yielding some value between 00:00 and 23:00 hours, thus adding another 30 minutes + local DAILY_TIME_OFFSET=$(( 0x${HASH:16:14} % 1381 + 30 )) + + if ! __is_cron_valid "$MONTHLY_CRON"; then + local MONTHLY_DAY=$(( TIME / 1440 + 1 )) + local MONTHLY_HOUR=$(( TIME % 1440 / 60 )) + local MONTHLY_MINUTE=$(( TIME % 1440 % 60 )) + MONTHLY_CRON="$(printf '%d %d %d * *' $MONTHLY_MINUTE $MONTHLY_HOUR $MONTHLY_DAY)" + fi + + if ! __is_cron_valid "$DAILY_CRON"; then + local DAILY_TIME=$(( ( TIME % 1440 + DAILY_TIME_OFFSET ) % 1440 )) + local DAILY_HOUR=$(( DAILY_TIME / 60 )) + local DAILY_MINUTE=$(( DAILY_TIME % 60 )) + DAILY_CRON="$(printf '%d %d * * *' $DAILY_MINUTE $DAILY_HOUR)" + fi + + printf '%s %s\n' "$MONTHLY_CRON" "$MONTHLY_CMD" + printf '%s %s\n' "$DAILY_CRON" "$DAILY_CMD" + } + + log "creating crontab file '/etc/crontabs/acme'..." + + __crontabs "$(ls -1 "/var/local/acme/live")" \ + "${CRON_RENEW:-}" "acme-renew --all --retry --clean --verbose" \ + "${CRON_CHECK:-}" "acme-check --all --renew --retry-renew --verbose" \ + > "/etc/crontabs/acme" fi