From a31c94f9b8ee4a60593037c2c9f1a7cdf0820445 Mon Sep 17 00:00:00 2001 From: noroot Date: Fri, 11 Sep 2026 10:32:54 +0200 Subject: [PATCH] =?UTF-8?q?fix(ha):=20squid/unbound=20liefen=20auf=20dem?= =?UTF-8?q?=20Standby=20nicht=20=E2=80=94=20ip=5Fnonlocal=5Fbind?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit squid und unbound lauschen auf den VLAN-Gateway-VIPs. Bei ip_nonlocal_bind=0 kann ein Node diese Adressen nur binden, waehrend er die VIP haelt. Bootet ein Node als Standby, scheitert der Start deshalb mit "FATAL: Unable to open HTTP Socket" und die Unit bleibt dauerhaft `failed` — systemd versucht es nicht erneut, keepalived-master.sh startet sie erst bei VIP-Uebernahme (Kaltstart im Umschaltmoment). Zwei Probleme daran: der Dauer-`failed`-Zustand ist nicht von einem echten Ausfall zu unterscheiden, und beim Failover kommen die Dienste erst nach dem Start hoch statt sofort bereit zu stehen. Mit nonlocal_bind laufen beide auf beiden Nodes durch. Traffic bekommt weiterhin nur der Node, der die VIP per ARP haelt — die VIP-Wahl selbst ist nicht betroffen, keepalived-check.sh prueft ausschliesslich edgeguard-api, haproxy und den :443-Bind. Zusaetzlich repariert der postinst gezielt Units, die enabled UND failed sind (also genau den obigen Fall); laufende oder bewusst deaktivierte Dienste bleiben unangetastet. Co-Authored-By: Claude Opus 5 --- .../debian/edgeguard-api/DEBIAN/postinst | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packaging/debian/edgeguard-api/DEBIAN/postinst b/packaging/debian/edgeguard-api/DEBIAN/postinst index dabef4a..e5be146 100755 --- a/packaging/debian/edgeguard-api/DEBIAN/postinst +++ b/packaging/debian/edgeguard-api/DEBIAN/postinst @@ -346,6 +346,19 @@ net.ipv6.conf.all.accept_source_route = 0 net.ipv4.conf.all.rp_filter = 2 net.ipv4.conf.default.rp_filter = 2 +# ─── Nonlocal-Bind (HA/VIP) ─────────────────────────────────────── +# squid und unbound lauschen auf den VLAN-Gateway-VIPs. Ohne diese +# Option kann ein Node sie nur binden, WÄHREND er die VIP haelt — auf +# dem Standby scheitert der Start mit "FATAL: Unable to open HTTP +# Socket" und die Unit steht dauerhaft auf `failed`. Das ist nicht von +# einem echten Ausfall zu unterscheiden und kostet beim Failover +# zusätzlich einen Kaltstart. Mit nonlocal_bind laufen beide Dienste auf +# beiden Nodes durch und sind im Umschaltmoment sofort bereit; Traffic +# bekommt weiterhin nur der Node, der die VIP per ARP wirklich haelt. +# Standard-Pattern für keepalived-Setups. +net.ipv4.ip_nonlocal_bind = 1 +net.ipv6.ip_nonlocal_bind = 1 + # ─── Conntrack — Edge-Box trackt viele parallele Sessions ───────── net.netfilter.nf_conntrack_max = 524288 net.netfilter.nf_conntrack_tcp_timeout_established = 86400 @@ -400,6 +413,21 @@ vm.dirty_background_ratio = 5 SYSCTL sysctl --system >/dev/null 2>&1 || true + # Ein Node, der als Standby gebootet hat, kann squid/unbound vor + # dem nonlocal_bind oben nicht gestartet haben — die Unit steht + # dann auf `failed` und systemd versucht es von sich aus nicht + # erneut. Gezielt nur solche Units anfassen: enabled UND failed. + # Laeuft der Dienst bereits oder ist er bewusst disabled (Forward- + # Proxy/DNS optional), passiert hier nichts. + for svc in squid unbound; do + if systemctl is-enabled --quiet "$svc" 2>/dev/null \ + && systemctl is-failed --quiet "$svc" 2>/dev/null; then + systemctl reset-failed "$svc" 2>/dev/null || true + systemctl start "$svc" 2>/dev/null || \ + echo "postinst: $svc start after nonlocal_bind failed" >&2 + fi + done + # ── Firewall-Logging via ulogd2 (NFLOG group 0) ────────────── # nft-Renderer emittiert `log prefix "edgeguard:" group 0` # für jede Rule mit log=true. ulogd2 subscribed auf netlink-group