Ein Totmannschalter für Firewall-Änderungen
Die beängstigendste Zeile in der Homelab-Automatisierung ist die, die eine Firewall-Regel auf dem Router ändert, mit dem man per SSH verbunden ist.
So bearbeiten Claude Code und ich sie trotzdem.
Die Angst
Ich musste eine UDM Pro-Regel namens “Block inter-VLAN traffic” von accept auf drop umstellen. Die Regel war seit Ewigkeiten falsch konfiguriert — auf accept gesetzt, wodurch jede per-Flow-Erlaubnis darüber kurzgeschlossen wurde — und sie wieder zu schließen war der ganze Punkt. Der Orchestrator, der die Änderung ausführte, war eine NixOS-VM in meinem Heimnetzwerk. Wenn die Umstellung den Pfad unterbrach, den diese VM (oder mein eigenes SSH) verwendete, wäre ich von meinem eigenen Router ausgesperrt ohne Konsolen-Fallback.
Die Lösung ist nicht “vorsichtig sein.” Die Lösung ist, die gefährliche Bearbeitung automatisch rückgängig zu machen, es sei denn, ich bestätige, dass alles in Ordnung ist.
Dieses Muster kennen Sie bereits. Ändern Sie die Auflösung Ihres Monitors unter macOS oder Windows, und das System wendet sie fünfzehn Sekunden lang mit einem herunterzählenden Dialog “Diese Anzeigeeinstellungen beibehalten?” an. Wenn Ihr Bildschirm schwarz wurde, können Sie nichts anklicken — und das ist der Punkt. Das Standardergebnis ist ein Rollback. Bestätigung ist Opt-in.
Genau das wollen wir für eine Firewall-Umstellung auf einem Router, dessen Regeln wir gerade ändern wollen.
Der Trick
udm_set_firewall_rules.py --flip-with-revert 300 --apply
Lesen als: “Regel umstellen, aber automatisch in 300 Sekunden zurücksetzen, es sei denn, ich sage, das nicht zu tun.”
Was es in Reihenfolge tut:
- Snapshot. GETs die aktuelle Regel und speichert das vollständige JSON-Payload auf dem UDM unter
/root/.udm-flip-revert/payload-<id>.json. - Rücksetzung vorbereiten. Schreibt ein kleines Shell-Skript neben das Payload, das den Snapshot wieder per PUT an die UDM API sendet.
- Rücksetzung einplanen.
systemd-run --on-active=300s --unit=udm-flip-revert-<id>stellt das Skript als transienten Timer in die Warteschlange. - Umstellen. PUTs die neue Regel (
action: drop).
Jetzt haben Sie ein 5-Minuten-Fenster zur Überprüfung:
✓ flipped 'Block inter-VLAN traffic' to action='drop'
⏱ auto-revert scheduled (~300s)
TO KEEP THE FLIP: ssh udm 'systemctl stop udm-flip-revert-66c1d…timer'
TO ROLL BACK NOW: ssh udm 'systemctl stop …timer; bash /root/.udm-flip-revert/revert-….sh'
WAIT IT OUT: do nothing — timer will revert in ~300s
Drei mögliche Ergebnisse:
- Es funktioniert. Timer stoppen. Die Umstellung ist dauerhaft.
- Es hat etwas kaputt gemacht. Timer stoppen, Rücksetzskript ausführen. Oder einfach aufhören zu tippen — der Timer läuft in N Sekunden ab und die Regel kommt von selbst zurück.
- Es hat mich ausgesperrt. Dasselbe. Der Timer braucht mich nicht, um auszulösen.
Der dritte Fall ist der Grund, warum das alles existiert.
Warum systemd-run und nicht at(1)
UDM Pro (Debian 11) wird ohne atd geliefert. Es hat systemd. systemd-run --on-active=Ns erstellt einen transienten Timer, der einmalig auslöst und sich selbst bereinigt, was genau die Form von “Tu dies in N Sekunden und verschwinde dann” ist.
ssh_udm(
f"systemd-run --on-active={seconds} --unit={unit} --collect "
f"--quiet /bin/bash {script_file}"
)
--collect ist das entscheidende Flag — ohne es verbleibt die Unit im failed/inactive-Zustand und macht systemctl unübersichtlich.
Der Vorbehalt
Transiente systemd-Units leben in /run, was tmpfs ist. Wenn der UDM innerhalb des Rücksetzfensters neu startet, ist der Timer verschwunden — und die Umstellung bleibt angewendet, ohne dass ein Totmannschalter darüber wacht.
Kontraintuitiv, aber real: Fenster kurz halten. Ein 5-Minuten-Fenster mit einem kleinen Neustartrisiko ist sicherer als ein 1-Stunden-Fenster, bei dem ein USV-Ausfall bei Minute 12 Sie mit einer dauerhaften Aussperrung zurücklässt. Lang genug zur Überprüfung, kurz genug, sodass “Habe ich eine ausstehende Rücksetzung vergessen?” nie eine Frage ist.
Fazit
Das Totmannmuster verallgemeinert sich über UDM-Firewall-Regeln hinaus. Überall, wo Sie eine Änderung anwenden wollen, die den Pfad unterbrechen könnte, über den Sie sie angewendet haben — Routing-Tabellen, sshd_config, nftables, BGP — funktioniert dieselbe Form:
- Aktuellen Zustand erfassen
- Ein Skript vorbereiten, das ihn wiederherstellt
- Das Skript einplanen, um in N Sekunden zu laufen
- Die Änderung anwenden
Wenn Sie noch in N+ε Sekunden da sind und alles gut aussieht, brechen Sie den Timer ab. Wenn nicht, bricht der Timer Sie ab.
Ich schlafe besser mit diesem in der Werkzeugkiste.