fix: HAProxy could not read the placeholder, so a failed issuance took the site down
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 36s
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 36s
The placeholder is the whole reason a first start works at all: HAProxy resolves `bind ... ssl crt` while parsing its configuration, so it cannot start without site.pem, and certbot writes a self-signed one to break that circle. It wrote it 0600 root-only, under the umask the subshell sets for the private key it builds it from. HAProxy runs unprivileged (uid 1001 in the bitnami image), so it could not open the file and exited -- and because it never came up, it never created the runtime API socket the pass waits for, and the pass hung in that wait instead of reaching the 12-hour sleep. A node whose first issuance failed -- a typo in CERTBOT_DOMAIN is enough -- served nothing at all on 80 or 443, retried nothing, and said so only in two container logs. The real certificate escapes this by accident: 2-concatenate-cert.sh writes it with `cat >` under the default umask, so site.pem is 0644 on every node that ever issued one. That is why nobody hit this -- it needs a first issuance that fails. chmod on the temporary file rather than after the rename, so the atomic rename stays the only thing HAProxy can observe and site.pem never exists with a mode that stops it. The intermediates keep the tight umask. Reproduced on a disposable haproxy+certbot stack with empty volumes and CERTBOT_DOMAIN=testnet2.bitdeals.invalid: before, HAProxy crash-looped on "cannot open the file" while certbot waited for admin.sock; after, HAProxy starts on the placeholder, certbot reports the rejected domain, the loop retries in 12h, and the site answers on 80 and terminates TLS on 443 with the self-signed certificate. Claude-Session: https://claude.ai/code/session_01BvgYcYPWd1KGABLKViVPSk
This commit is contained in:
@@ -31,6 +31,15 @@ if [ ! -f /etc/certificates/site.pem ]; then
|
||||
-keyout site.key.tmp -out site.crt.tmp
|
||||
cat site.key.tmp site.crt.tmp > site.pem.tmp
|
||||
rm -f site.key.tmp site.crt.tmp
|
||||
# Readable by HAProxy, which runs unprivileged (uid 1001) and opens this
|
||||
# file while parsing `bind ... ssl crt`. Under the umask above the
|
||||
# placeholder came out 0600 root-only, HAProxy could not start at all, and
|
||||
# the pass then waited forever for a runtime API socket that no longer had
|
||||
# anyone to create it — a failed issuance took the whole site down instead
|
||||
# of leaving it on the placeholder. The real certificate has been 0644 all
|
||||
# along: 2-concatenate-cert.sh writes it with the default umask. Set on the
|
||||
# temporary file, so the rename below stays the only thing HAProxy can see.
|
||||
chmod 644 site.pem.tmp
|
||||
# Last and atomic: HAProxy reads site.pem at start-up and must never find
|
||||
# it half-written.
|
||||
mv site.pem.tmp site.pem
|
||||
|
||||
Reference in New Issue
Block a user