feat(ha): VIP-Preempt zurück zum PG-Primary — mit gehärtetem Health-Gate — v1.3.16

Preempt-Rückkehr (preempt_delay 120) wieder aktiv: der bevorzugte Node
(PG-Primary, Prio 200) holt die VIP nach Erholung zurück. Der Incident
2026-08-03 (halb-kaputter Node riss die VIP an sich) wird verhindert, weil
keepalived-check.sh jetzt zusätzlich fordert:
  - haproxy-Prozess aktiv
  - :443 gebunden (bedient wirklich Traffic)
Ein nicht-bedienender Node geht damit in FAULT und kann NICHT (mehr) preempten.

Außerdem: CrowdSec-Management-Whitelist (Backend api_backend) fest ins postinst
gebacken (Admin-SPA-Traffic wird nie mehr als http-crawl gebannt, IP-unabhängig,
Incident-Root-Fix) + Altlast netcell-mgmt-whitelist.yaml wird aufgeräumt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-08-03 13:39:15 +02:00
parent d395e3ea68
commit 0846eaa05b
6 changed files with 104 additions and 29 deletions

View File

@@ -1,6 +1,30 @@
#!/bin/bash
# Keepalived health check: edgeguard-api erreichbar?
# Weight -50 → BACKUP gewinnt wenn Primary-API nicht antwortet.
# Keepalived-Health-Check (chk_edgeguard).
#
# WICHTIG (Incident 2026-08-03): Dieser Check entscheidet mit, ob ein Node die
# VIP übernehmen bzw. per Preempt zurückholen darf. Er darf NUR dann "gesund"
# (exit 0) melden, wenn der Node Traffic WIRKLICH bedienen kann — nicht nur
# "edgeguard-api-Prozess up". Sonst reißt ein frisch gebooteter / mitten im
# Deploy befindlicher Node (haproxy noch nicht bereit) die VIP an sich, obwohl
# er nichts bedient → Cluster-Ausfall, bis der Node hart abgeschaltet wird.
#
# ALLE Bedingungen müssen erfüllt sein, sonst exit 1 → Instanz geht in FAULT →
# kein (Re-)Preempt, der gesunde Peer behält/bekommt die VIP.
# 1) edgeguard-api antwortet auf den Health-Endpoint (Unix-Socket oder Loopback)?
curl -sf --max-time 2 --unix-socket /run/edgeguard/api.sock \
http://localhost/api/v1/system/health > /dev/null 2>&1 \
|| curl -sf --max-time 2 http://127.0.0.1:9443/api/v1/system/health > /dev/null 2>&1
|| curl -sf --max-time 2 http://127.0.0.1:9443/api/v1/system/health > /dev/null 2>&1 \
|| exit 1
# 2) haproxy-Prozess aktiv? Während Boot/Restart kurz false → Node bleibt in dem
# Fenster Backup (kann nicht preempten).
systemctl is-active --quiet haproxy 2>/dev/null || exit 1
# 3) haproxy hört wirklich auf dem oeffentlichen TLS-Port :443 (bindet = bedient)?
# Faengt "Prozess up, aber Config kaputt / Port nicht gebunden" ab. :443 ist
# architektur-bedingt immer gebunden (Public-TLS + ACME-Webroot + Mgmt-FQDN-
# Fallback), also ein verlaessliches Ready-Signal.
ss -H -ltn 2>/dev/null | awk '{print $4}' | grep -Eq ':443$' || exit 1
exit 0