containers-certbot/certbotd.sh
f ffed22b2df
All checks were successful
ci/woodpecker/push/woodpecker/1 Pipeline was successful
ci/woodpecker/push/woodpecker/2 Pipeline was successful
fix: tap
2024-06-14 18:47:42 -03:00

143 lines
4.1 KiB
Bash
Executable file

#!/bin/sh
ok() {
echo "ok - $@" >&2
}
not_ok() {
echo "not ok - $@" >&2
}
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
fi
lock=/tmp/certbot.lck
updated=/tmp/certbot.updated
ensure() {
test -n "$1" && ok "$1 received, exiting gracefully..."
if test -f "${updated}" ; then
rm -f "${updated}"
# Fix permissions, users in group ssl have read access
find /etc/letsencrypt -type d | xargs -r chmod 2750
find /etc/letsencrypt -type f | xargs -r chmod 640
chgrp -R ssl /etc/letsencrypt
if ! ${SINGLE_NODE:-false}; then
for NODE in ${NODES}; do
rsync -avHAXL --delete-after /etc/letsencrypt/live/ ${NODE}/ || continue
done
fi
fi
# Remove the lock after synchronization
rm -f "${lock}"
# Exit with the error code
exit $1
}
for SIG in 1 2 3 6 9 14 15; do
trap "ensure ${SIG}" ${SIG}
done
set -E
case $1 in
# Renew certificates, trust in certbot's algorithms
renew)
/usr/bin/certbot renew --quiet --agree-tos || true
touch "${updated}"
;;
bootstrap)
test -d "/etc/letsencrypt/live/${SUTTY}" && exit 0
# Get a single certificate for the whole domain
/usr/bin/certbot \
certonly \
--non-interactive \
--authenticator "dns-standalone" \
--email "certbot@${SUTTY}" \
--agree-tos \
-d "${SUTTY}" \
-d "*.${SUTTY}" \
-d "*.testing.${SUTTY}" && touch "${updated}"
;;
prune)
comm -13 <(realpath /etc/letsencrypt/live/*/*.pem | sort) <(find /etc/letsencrypt/archive/ -name "*.pem" | sort) | xargs rm -v
touch "${updated}"
;;
# Generate certificates
*)
# Only one instance can run at a time
if test -f "${lock}" ; then
not_ok "There's a certbotd instance already running, doing nothing..."
not_ok "If the problem persists, you may need to remove ${lock} manually."
exit 1
fi
touch "${lock}"
# Save headers here
headers=/tmp/headers
# Gets ETag from previous headers
test -f "${headers}" \
&& etag="$(grep "^ Etag: " "${headers}" | cut -d : -f 2)"
# Get site list from the API and transform to a list. Save headers
# for next run. Use ETag to avoid running when nothing changed
wget --user="${HTTP_BASIC_USER}" --password="${HTTP_BASIC_PASSWORD}" \
--header="If-None-Match:${etag}" -qSO - \
"https://api.${SUTTY}/v1/sites.json" \
2>"${headers}" \
| jq --raw-output .[] \
| while read domain; do
if test -z "${domain}"; then
not_ok "domain is empty"
continue
fi
# Skip already existing domains
if test -s "/etc/letsencrypt/renewal/${domain}.conf"; then
ok "${domain} already issued"
continue
else
ok "${domain} renewal conf was empty, fixing..."
other_renewal="$(grep -l -m 1 "^authenticator = webroot$" /etc/letsencrypt/renewal/*.conf | head -1)"
if test -z "${other_renewal}"; then
not_ok "${domain} couldn't fix"
ensure 1
fi
other_domain="$(basename "${other_renewal}" .conf)"
sed -re "s/${other_domain}/${domain}/g" "${other_renewal}" > "/etc/letsencrypt/renewal/${domain}.conf"
fi
# Ignore non local domains
if ! nslookup "${domain}" 8.8.8.8 | grep -qE "(${SUTTY_ADDRESSES// /|})" ; then
ok "${domain} is not configured to any Sutty node or DNS records are still cached, ignoring for now # skip"
continue
fi
# Get the certificate for the domain, the webserver will need
# access to this directory
/usr/bin/certbot certonly --email "certbot@${SUTTY}" \
-n \
--webroot \
--agree-tos \
--webroot-path /var/lib/letsencrypt \
-d "${domain}" || ensure $?
touch "${updated}"
done
esac
ensure 0