fix: the certificate follows CERTBOT_DOMAIN, on every pass

A pass branched on whether /etc/letsencrypt/live/<first-name> existed:
present, it ran `certbot renew`; absent, it handed over to the creation
script. Only the second path was ever told the names to ask for, so
after the first issuance CERTBOT_DOMAIN stopped reaching certbot
altogether -- renew takes the names off the certificate it already holds.
Editing the variable did nothing, silently, and the README documented the
manual issuance needed to work around it.

The branch is gone. Every pass now runs certonly with the names spelled
out, and certbot decides what that means:

  same names, not due    -> "Certificate not yet due for renewal; no
                            action taken", no connection opened, nothing
                            spent against the rate limits
  name added or removed  -> reissued with exactly the requested set
  due for renewal        -> renewed

--keep-until-expiring is what makes the first line true, and --cert-name
(already passed) is what keeps a changed list updating the existing
lineage instead of starting a second one beside it. No --expand is
needed to add a name once the lineage is named.

All three decisions were checked against the live stands: the no-op one
with a real run on testnet2, the other two as dry runs on testnet1 and
testnet2.

With the branch removed, 1-renew-cert.sh is a pass-through and the
numbering finally matches the order things run in -- 0-create-cert.sh
used to execute after 1-renew-cert.sh. So: 1-renew-cert.sh deleted,
0-create-cert.sh renamed to 1-ensure-cert.sh, which is what it now does.

Claude-Session: https://claude.ai/code/session_01BvgYcYPWd1KGABLKViVPSk
This commit is contained in:
bitdeals committed 2026-08-24 13:13:03 +00:00
1 parent 36e1865e37
commit e8204bbb4d
5 files changed
+56 -51

No files matched your search

@@ -1,5 +1,19 @@
#!/bin/sh
# One pass of the loop: make the certificate on the volume the one CERTBOT_DOMAIN
# asks for, then hand it to the running HAProxy. Every pass, not just the first.
#
# `certbot certonly` rather than `certbot renew`, and that is the whole reason
# this script is the pass: renew takes the names from the certificate it already
# holds and never reads CERTBOT_DOMAIN, so an edit to the variable stayed
# invisible until somebody issued the new set by hand. certonly is told the names
# on every pass, so the certificate follows the variable in both directions.
#
# --keep-until-expiring is what makes calling it twice a day free: with the same
# names and no expiry due, certbot answers "Certificate not yet due for renewal;
# no action taken" without opening a connection, so nothing is spent against
# Let's Encrypt's rate limits.
set -e
if [ ! -f /etc/certificates/site.pem ]; then
@@ -47,11 +61,15 @@ if [ -n "$CERTBOT_DOMAIN" ]; then
set -- --register-unsafely-without-email
fi
# Request certificate
# Request certificate. --cert-name pins the lineage to the first name, so a
# changed list updates that certificate instead of starting a second one
# beside it; with the lineage named, certbot needs no --expand to accept an
# added name non-interactively.
certbot certonly --standalone \
--non-interactive --agree-tos --http-01-port=380 \
"$@" \
--cert-name "${CERTBOT_DOMAIN%%,*}" \
--keep-until-expiring \
-d "$CERTBOT_DOMAIN"
# Concatenate certificates
-19
View File
@@ -1,19 +0,0 @@
#!/bin/sh
# Certificates exist
if [ -n "$CERTBOT_DOMAIN" -a -d /etc/letsencrypt/live/"${CERTBOT_DOMAIN%%,*}" ]; then
# Check certificates and renew them
certbot renew --http-01-port=380
# Concatenate certificates
. $(dirname $0)/2-concatenate-cert.sh
# Update certificates in HAProxy
. $(dirname $0)/3-update-haproxy-cert.sh
# Certificates don't exist
else
# Execute certificate creation script
. $(dirname $0)/0-create-cert.sh
fi
+2 -2
View File
@@ -17,7 +17,7 @@
# substitution runs in a subshell that reports the parent's jobs in bash but
# not in dash, and bare `wait` waits for every background job in either.
#
# One thing this cannot fix: a signal arriving while 1-renew-cert.sh is in the
# One thing this cannot fix: a signal arriving while 1-ensure-cert.sh is in the
# foreground is deferred until that script returns, and an issuance talking to
# Let's Encrypt can outlast docker's 10-second stop grace. Give the service a
# longer `stop_grace_period` if that matters.
@@ -25,7 +25,7 @@
trap 'exit 0' TERM INT
while :; do
/opt/scripts/1-renew-cert.sh \
/opt/scripts/1-ensure-cert.sh \
|| echo "entrypoint: renewal pass failed, retrying in 12h" >&2
sleep 12h &
wait