From 0aa27dfb25a81ff264f2d6ef986cc6d6c1a6fa65 Mon Sep 17 00:00:00 2001 From: rob thijssen Date: Mon, 31 Aug 2026 11:05:17 +0300 Subject: [PATCH] fix(infra-setup): don't report a cert mismatch mid-reload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The post-reload check compares the certificate on the wire against the one on disk, because nginx keeps its previous cycle -- and its previous certificates -- when a reload cannot rebind, while still reporting success. That check is right and it fired on the first run of this script. It was a false positive. Old workers finish their in-flight connections before exiting, so for a second or two after a reload either cycle may answer, and the check sampled the old one. A warning that cries wolf on every first install is worse than no warning, because the real thing gets ignored. Retries for up to twenty seconds before reporting a mismatch. Verified against hanzalova: the first run warned, the serials matched moments later, and a re-run reports the match immediately. Also makes the caveman and DNS steps report state rather than always printing instructions, now that both are provisioned, and points the bucket guidance at architecture/object-storage.md §3 -- including why the script refuses to read the MinIO root credentials itself. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XZG2i4AmfSqE97EJGBVb64 --- script/infra-setup.sh | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/script/infra-setup.sh b/script/infra-setup.sh index 51d7811..6779fd0 100755 --- a/script/infra-setup.sh +++ b/script/infra-setup.sh @@ -168,12 +168,21 @@ S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY." return 0 fi - warn "bucket and service-account creation needs MinIO root credentials, which -this script deliberately does not read. Run on $MINIO_HOST as an operator: + if ssh "$MINIO_HOST" "mc --version >/dev/null && test -d /srv/minio/$BUCKET"; then + ok "bucket $BUCKET exists" + return 0 + fi - mc alias set local $MINIO_URL \"\$MINIO_ROOT_USER\" \"\$MINIO_ROOT_PASSWORD\" + warn "bucket and service-account creation needs the MinIO root credentials, which +this script deliberately does not read -- they are root-equivalent for every bucket on +that host, not just this one. Run there as an operator (architecture object-storage.md §3): + + set -a; source <(sudo cat /etc/minio/minio.env); set +a + export MC_CONFIG_DIR=\$(mktemp -d); trap 'rm -rf \"\$MC_CONFIG_DIR\"' EXIT + mc alias set local http://127.0.0.1:9000 \"\$MINIO_ROOT_USER\" \"\$MINIO_ROOT_PASSWORD\" mc mb --ignore-existing local/$BUCKET - mc admin user svcacct add local \"\$MINIO_ROOT_USER\" --name rustingface + mc admin user svcacct add local \"\$MINIO_ROOT_USER\" --name $APP \\ + --access-key '$APP-<8 random>' --policy then set the Gitea repo secrets S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY. Re-run this script with --skip-minio once that is done." @@ -244,10 +253,18 @@ provision_proxy() { # A reload is a request, not a guarantee: nginx keeps its old cycle if it # cannot rebind, and then serves the certificate it loaded then. Compare # what is actually on the wire against what is on disk, by serial. + # + # Old workers finish their in-flight connections before exiting, so for a + # second or two after a reload either cycle may answer. Retry rather than + # report a mismatch that is really just the handover in progress. local served disk - served=$(echo | openssl s_client -servername ${VHOST}.internal -connect ${PROXY_HOST}:443 2>/dev/null \ - | openssl x509 -noout -serial || echo "serial=unavailable") disk=$(ssh "$PROXY_HOST" "sudo openssl x509 -noout -serial -in $cert") + for _ in $(seq 1 10); do + served=$(echo | openssl s_client -servername ${VHOST}.internal -connect ${PROXY_HOST}:443 2>/dev/null \ + | openssl x509 -noout -serial || echo "serial=unavailable") + [ "$served" = "$disk" ] && break + sleep 2 + done if [ "$served" = "$disk" ]; then ok "the certificate on the wire matches the one on disk" else @@ -260,7 +277,11 @@ Investigate the bind failure in the nginx error log, then restart nginx." fi info "DNS" - echo " Add the split-horizon record if it is not already present:" + if getent hosts "${VHOST}.internal" >/dev/null; then + ok "${VHOST}.internal resolves" + return 0 + fi + echo " Add the split-horizon record on both routers:" echo " opn-cli --config ~/.opn-cli/hanzalova.yml unbound host create \\" echo " --hostname ${VHOST} --domain internal --server 10.6.0.46 \\" echo " --description 'rustingface via hanzalova reverse proxy (bob backend)'"