From 0f15423d4f77ddbb63defd413693fd9fac3daac1 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 28 Dec 2024 17:09:07 -0300 Subject: [PATCH] feat: prune uneeded certificates --- Dockerfile | 2 +- certbotd.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e9a60c9..6747313 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ LABEL org.opencontainers.image.authors="f@sutty.nl" RUN addgroup -S -g 777 ssl RUN install -dm 2700 -o root -g root /root/.ssh -RUN apk add --no-cache certbot jq wget openssh-client rsync certbot-dns-standalone +RUN apk add --no-cache certbot jq wget openssh-client rsync certbot-dns-standalone gnutls-utils COPY ./monit.conf /etc/monit.d/certbot.conf COPY ./certbotd.sh /usr/local/bin/certbotd diff --git a/certbotd.sh b/certbotd.sh index b5eeaf4..fd432d3 100755 --- a/certbotd.sh +++ b/certbotd.sh @@ -8,6 +8,10 @@ not_ok() { echo "not ok - $@" >&2 } +remove_certificate() { + rm -rf "/etc/letsencrypt/renewal/${1}.conf" "/etc/letsencrypt/live/${1}" "/etc/letsencrypt/archive/${1}" +} + if test -z "${NODES}" && test -z "${SINGLE_NODE}"; then not_ok "The env var NODES is empty, if you don't want to synchronize to other servers, set SINGLE_NODE=true" exit 1 @@ -15,6 +19,7 @@ fi lock=/tmp/certbot.lck updated=/tmp/certbot.updated +domains=/tmp/domains ensure() { test -n "$1" && ok "$1 received, exiting gracefully..." @@ -75,7 +80,32 @@ case $1 in ;; prune) + # Prune certificates that are not needed anymore + if test -s "${domains}"; then + grep "^authenticator\s*=\s*webroot$" -m 1 -r /etc/letsencrypt/renewal -l | while read renewal; do + cert="`grep "^cert\s*=" -m 1 "${renewal}" | cut -d = -f 2 | tr -d " "`" + dir="${renewal##*/}" + dir="${dir%.conf}" + + # If the certificate exists and is non-empty + if test -s "${cert}"; then + domain="`certtool -i < "${cert}" | grep Subject: | cut -d = -f 2 | tr -d " "`" + + if grep -q "^${subject}$" "${domains}"; then + echo "ok - ${domain} certificate correctly set" + else + not_ok "${domain} certificate is not needed anymore, removing" + remove_certificate "${domain}" + fi + else + not_ok "${domain} certificate doesn't exist, removing" + remove_certificate "${domain}" + fi + done + fi + comm -13 <(realpath /etc/letsencrypt/live/*/*.pem | sort) <(find /etc/letsencrypt/archive/ -name "*.pem" | sort) | xargs rm -v + touch "${updated}" ;; # Generate certificates @@ -102,6 +132,7 @@ case $1 in "https://api.${SUTTY}/v1/sites.json" \ 2>"${headers}" \ | jq --raw-output .[] \ + | tee "${domains}" \ | while read domain; do if test -z "${domain}"; then not_ok "domain is empty"