fix(scheduler): ACME-Renewal nur auf VIP-Master — Standby-403 verursachte Cert-Drift — v1.3.20

Der Scheduler fuhr runRenewer (ACME) ungated auf beiden Nodes. ACME-HTTP-01-
Challenges laufen aber auf :80 der VIP → nur der VIP-Master kann sie bestehen.
Der BACKUP-Node scheiterte immer mit 403 (invalid authorization) und setzte
tls_certs.status lokal auf "error" → Divergenz zur replizierten Row
(Primary=active) → Config-Drift-Banner + Log-Noise. runRenewer jetzt hinter
nodeHoldsVIP() gegated (Start + 6h-Tick); runCertExpiryCheck bleibt ungated
(read-only). Die Cert-Row/PEM repliziert ohnehin vom Master auf den Standby.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-08-07 08:35:03 +02:00
parent f1f7df74f7
commit b70db4ccf0
2 changed files with 10 additions and 3 deletions

View File

@@ -1 +1 @@
1.3.19 1.3.20

View File

@@ -191,7 +191,8 @@ func main() {
auditRepo := audit.New(pool) auditRepo := audit.New(pool)
alertDedupe := newDedupe(12 * time.Hour) alertDedupe := newDedupe(12 * time.Hour)
if renewer != nil { // ACME nur auf dem VIP-Master (siehe Tick-Kommentar unten).
if renewer != nil && nodeHoldsVIP(ctx, pool) {
runRenewer(ctx, renewer, alertSvc, alertDedupe) runRenewer(ctx, renewer, alertSvc, alertDedupe)
} }
runLicenseVerify(ctx, licClient, licKeyStore, licRepo, nodeID, alertSvc, alertDedupe) runLicenseVerify(ctx, licClient, licKeyStore, licRepo, nodeID, alertSvc, alertDedupe)
@@ -258,7 +259,13 @@ func main() {
for { for {
select { select {
case <-renewTick.C: case <-renewTick.C:
if renewer != nil { // ACME-HTTP-01-Challenges laufen auf :80 der VIP → nur der
// VIP-Master kann sie bestehen. Ein BACKUP-Node scheitert IMMER
// mit 403 (invalid authorization) und setzt tls_certs.status lokal
// auf "error" → Divergenz zur replizierten Row (Primary=active) →
// Config-Drift-Banner + Log-Noise. Renewal daher nur am VIP-Master;
// die Cert-Row/PEM repliziert von dort ohnehin auf den Standby.
if renewer != nil && nodeHoldsVIP(ctx, pool) {
runRenewer(ctx, renewer, alertSvc, alertDedupe) runRenewer(ctx, renewer, alertSvc, alertDedupe)
} }
runCertExpiryCheck(ctx, tlsRepo, alertSvc, alertDedupe) runCertExpiryCheck(ctx, tlsRepo, alertSvc, alertDedupe)