M8: Netzwerk-Isolation live verifiziert (manuell + über den Wizard)

Isolation zuerst manuell per SSH nachgebaut (ether5), danach über den
App-Wizard (Experte-Modus, ether4), um die eigentliche Abnahme-
Bedingung ("kompletter Wizard-Durchlauf") zu erfüllen. Dabei drei
App-Bugs gefunden und gefixt:

- Bug 22: neues LAN-/VLAN-Interface wurde nie der defconf-Interface-
  Liste "LAN" hinzugefügt, wodurch DNS-Anfragen an den Router selbst
  blockiert blieben (Werks-Firewall droppt Input von allem außerhalb
  dieser Liste).
- Bug 23: ein voller Wizard-Durchlauf gegen einen bereits konfigurierten
  Router brach am ersten nicht-idempotenten Add-Befehl ab
  (/ip address, /ip pool, /ip dhcp-server, /ip dhcp-server network).
- Bug 24: ein als eigenes isoliertes Netz konfiguriertes Interface
  blieb Bridge-"Slave" (Werks-Bridging), wodurch RouterOS die
  generierten Isolationsregeln selbst als ungültig verwarf.

Alle drei in DhcpServerCommandBuilder/SetupViewModel gefixt, 52 Unit-
Tests grün, Isolation+DNS+Internet am echten Gerät bestätigt. M8 auf
live verifiziert gesetzt. Nebenbei zwei veraltete Doku-Stellen zum
Gitea-Remote korrigiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
This commit is contained in:
Kay
2026-09-15 10:28:09 +02:00
co-authored by Claude Sonnet 5
parent 19fa1d6ef4
commit fc3b2ca039
7 changed files with 286 additions and 75 deletions
+133 -51
View File
@@ -56,17 +56,60 @@ Farbwerte, alles adaptive System-Farben) — vom Nutzer live bestätigt.
Release-Build unter `/Applications/RouterOS Assistant.app` ist auf
aktuellem Stand.
**Zum Sessionende:** M8-Hardware-Test (Netzwerk-Isolation) begonnen —
voller Wizard-Durchlauf über den Experte-Modus, WAN neu einrichten.
Dabei Bug 21 gefunden: der Wizard-Apply nutzte für WAN-DHCP-Client/PPPoE
immer `.add`, was auf einem bereits konfigurierten Interface (hier: aus
der zurückgespielten Sicherung) mit "failure: dhcp-client on that
interface already exists" scheiterte. Fix: `SetupViewModel.
applyIdempotently` versucht bei `.add` auf `/ip dhcp-client` oder
`/interface pppoe-client` nach einem Fehlschlag automatisch `.set`
(nach "interface" gematcht) — deployt, **aber der eigentliche
M8-Isolationstest selbst ist noch nicht zu Ende geführt/verifiziert**,
das ist der erste Schritt für die nächste Session.
**Danach, neue Session: M8 komplett live verifiziert — erst manuell,
dann über den Wizard selbst.** Bug 21 aus der Vorsession (WAN-DHCP-
Client/PPPoE-Apply nicht idempotent) blieb bestätigt gefixt. Isolation
zuerst manuell per SSH an `ether5` nachgebaut (eigenes Subnetz, eigener
DHCP-Server, `/interface list`-basierte Forward-Drop-Regel) — dabei drei
reine Konfigurationsfehler der Reihe nach gefunden und behoben (Adresse
versehentlich als `/32` bzw. `.0`-Netzadresse statt Host-Adresse
eingetragen; `ether5` fehlte in der defconf-Interface-Liste "LAN",
wodurch DNS-Anfragen an den Router selbst blockiert wurden, obwohl
DHCP/Routing/Internet normal liefen). Isolation danach beidseitig
bestätigt (iMac ↔ Laptop erreichen sich nicht, Internet für beide
weiterhin ja).
Anschließend derselbe Test **über den App-Wizard** (Experte-Modus,
`ether4`) wiederholt, um die Abnahme-Bedingung aus der Vorsession
("kompletter Wizard-Durchlauf") tatsächlich zu erfüllen — dabei drei
echte App-Bugs gefunden und gefixt, alle auf denselben "Wizard wurde nie
gegen einen bereits konfigurierten Router bzw. mit bereits gebrückten
Ports erneut ausgeführt" blinden Fleck zurückzuführen:
- **Bug 22:** `DhcpServerCommandBuilder` fügte ein neues LAN-/VLAN-
Interface nie der defconf-Interface-Liste "LAN" hinzu — derselbe
DNS-Bug wie oben, jetzt als App-Bug bestätigt. Fix: automatisch
`/interface list add name=LAN` + `/interface list member add
list=LAN interface=<name>`, beide toleriert falls schon vorhanden.
- **Bug 23:** ein voller Wizard-Durchlauf gegen einen bereits
konfigurierten Router brach beim zweiten Befehl ab
(`/ip address add address=192.168.88.1/24 interface=bridge`
"already have such address"), weil nur WAN-DHCP-Client/PPPoE
idempotent behandelt wurden (Bug 21). Fix: `SetupViewModel.
applyIdempotently` erweitert — `/ip pool`/`/ip dhcp-server`/
`/ip dhcp-server network` werden bei Duplikat jetzt als `.set`
(gematcht auf name/name/address) erneut versucht, `/ip address` bei
exaktem Duplikat als bereits erledigt behandelt (ein Interface darf
mehrere Adressen halten, ein `.set` nach "interface" träfe sonst
potenziell die falsche).
- **Bug 24:** LAN-/VLAN-Schritt löste ein gewähltes physisches Interface
nie aus einer bestehenden Bridge — auf Werks-Routern sind ether25 ab
Werk gebridged. Als eigenes isoliertes Netz konfiguriert blieb das
Interface Bridge-"Slave", RouterOS verwarf die generierten
Isolationsregeln selbst als ungültig ("in/out-interface matcher not
possible when interface is slave - use master instead"), live an
`ether4` bestätigt. Fix: `DhcpServerCommandBuilder` stellt jetzt
`/interface bridge port remove [find interface=<name>]` voran
(übersprungen für "bridge" selbst), toleriert als bereits erledigt
falls nie gebridged.
Nach allen drei Fixes lief der komplette App-Wizard-Durchlauf für
`ether4` fehlerfrei durch (inkl. Neuanwendung der bereits vorhandenen
`bridge`/`ether1`-Konfiguration), Isolation + DNS + Internet vom Nutzer
am echten Gerät bestätigt. Alle 52 Unit-Tests grün. M8 damit als
einziger Milestone bisher **sowohl manuell als auch über die App selbst**
live verifiziert.
## Ziel
Native macOS-App (SwiftUI), die Laien per geführtem Interview-Wizard durch
@@ -104,7 +147,8 @@ killall Dock # Icon-Cache auffrischen, falls sich nur das Icon geändert hat
Abhängigkeiten stehen in `project.yml`, das ist die Quelle der Wahrheit —
nicht das generierte `.xcodeproj` von Hand editieren.
Git: lokales Repo, kein Remote (Nutzer hat aktuell keine Gitea-Instanz).
Git: Remote `origin` zeigt auf eine selbst gehostete Gitea-Instanz
(`git@192.168.178.222:kay/RouterOS.git`).
`.xcodeproj`, `DerivedData`, `.build`, Firmware-Dateien (`*.npk`, `*.cpgz`)
und Router-Backups (`*.rsc`, `/Backups/`) sind gitignored.
@@ -458,7 +502,33 @@ Singleton-Fallback, der für ein Menü per Exception ausgelöst wurde
(Bug 8), blieb für ein anderes Menü aus, weil RouterOS denselben
Fehlertext dort mit Exit-Code 0 zurückgibt; robuste Erkennung muss immer
auch den Output-Text selbst prüfen, nie nur auf eine geworfene Exception
vertrauen.
vertrauen. **Wizard-Apply nutzte für WAN-DHCP-Client/PPPoE immer `.add`**
(Bug 21) — scheiterte live mit "failure: dhcp-client on that interface
already exists" auf einem Interface, das (z.B. aus einer zurückgespielten
Sicherung) schon einen Client hatte; `SetupViewModel.applyIdempotently`
versucht seitdem bei `.add`-Fehlschlag auf diesen beiden Menüs
automatisch `.set` (nach "interface" gematcht). **Ein neu eingerichtetes
LAN-/VLAN-Interface wurde nie der defconf-Interface-Liste "LAN"
hinzugefügt** (Bug 22) — auf Routern mit Werks-Firewall
(`chain=input action=drop in-interface-list=!LAN`) blieb dadurch jede
Anfrage an den Router selbst (DNS, Winbox) vom neuen Netz aus blockiert,
obwohl DHCP/Routing/Internet normal liefen (reine Forward-Chain-Sache,
unberührt) — live an einer manuell nachgebauten Isolation gefunden
(Lease + Default-Route vorhanden, jede DNS-Anfrage lief trotzdem in
Timeout). **Voller Wizard-Durchlauf gegen einen bereits konfigurierten
Router brach an jedem nicht-idempotenten `.add` ab** (Bug 23) — nur
WAN-DHCP-Client/PPPoE waren idempotent (Bug 21); `/ip address`
(exaktes Duplikat = bereits erledigt) sowie `/ip pool`/`/ip
dhcp-server`/`/ip dhcp-server network` (Retry als `.set`, gematcht auf
name/name/address) kamen dazu. **Ein als eigenes isoliertes Netz
konfiguriertes Interface blieb Bridge-"Slave"** (Bug 24) — auf
Werks-Routern sind ether25 ab Werk gebridged; ohne explizites Lösen aus
der Bridge verwarf RouterOS die generierten Forward-Isolationsregeln
selbst als ungültig ("in/out-interface matcher not possible when
interface is slave - use master instead"), live an `ether4` bestätigt;
`DhcpServerCommandBuilder` stellt seitdem ein `/interface bridge port
remove [find interface=<name>]` voran (übersprungen für "bridge"
selbst).
## `xcodebuild test` hängt — Gatekeeper, kein Code-Bug
@@ -511,12 +581,11 @@ wiederholen.
nur der "kein WLAN"-Zweig ist bestätigt (zwei Testgeräte, beide ohne
WLAN-Chip). Sicherheitsprofil-Anlage + SSID/Passwort-`.set` auf einem
echten `/interface wireless`-Interface noch nie live gelaufen.
- **Firewall-Regeln mit korrektem WAN-Interface noch nicht erneut
bestätigt**der erste Live-Test (M6) lief technisch durch, traf aber
wegen Bug 6 oben `lo` statt des echten WAN-Ports. Nach dem Parser-Fix
wurde nur die Interface-**Auswahl** erneut bestätigt ("alle Interfaces
auswählbar"), nicht aber ein erneuter Firewall-Apply mit korrektem
Interface + Kontrolle der resultierenden Regeln.
- ~~Firewall-Regeln mit korrektem WAN-Interface noch nicht erneut
bestätigt~~ — erledigt: beim M8-App-Test (siehe oben) lief ein voller
`FirewallConfig`-Apply mit `ether1` als WAN erneut durch,
`/ip firewall filter print` zeigte alle Basisregeln (established/
related, invalid-drop, ICMP-Accept, WAN-Drop) korrekt mit `ether1`.
- **Neuer RouterOS-WiFi-Treiber (`/interface wifi`, wifiwave2/802.11ax)
nicht unterstützt** — wird erkannt und im UI erklärt, aber nicht
konfiguriert.
@@ -560,10 +629,20 @@ Isolation vom Hauptnetzwerk, ohne dass eine einzige Firewall-Regel das
durchsetzte — reiner Text ohne Wirkung. Jetzt ist Isolation ein echter,
optionaler Schalter mit tatsächlicher Regel-Erzeugung.
Nur gegen Unit-Tests verifiziert (`FirewallConfigTests`: isoliertes
Netzwerk gegen nicht-isoliertes, gegenseitige Isolation, keine Isolation).
**Noch nicht gegen echte Hardware getestet** — bräuchte zwei getrennte
Testnetze am selben Router, um die Drop-Regeln praktisch zu bestätigen.
**Live gegen Hardware verifiziert (2026-09-15)** — zuerst manuell per
SSH nachgebaut (siehe "Zum Sessionende" oben), danach über den
App-Wizard selbst (`ether4`, Experte-Modus). iMac ↔ Laptop erreichen
sich über die Netzgrenze nicht mehr, Internet + DNS funktionieren auf
beiden Seiten weiter. Dabei drei App-Bugs gefunden und gefixt (Bug
2224, siehe Bug-Liste oben) — alle drei Voraussetzung dafür, dass ein
per Wizard eingerichtetes isoliertes Netz auf einem bereits
konfigurierten bzw. werksseitig gebridgten Router überhaupt funktioniert:
fehlende "LAN"-Interface-Listen-Mitgliedschaft (DNS zum Router blockiert),
fehlende Idempotenz bei erneutem Wizard-Lauf (Apply brach sofort ab),
und ein nie aus der Bridge gelöstes physisches Interface (RouterOS
verwarf die Isolationsregeln selbst als ungültig). Weiterhin unverändert
seit vorher: `FirewallConfigTests` (isoliertes Netzwerk gegen
nicht-isoliertes, gegenseitige Isolation, keine Isolation).
## M9: Einfach/Experte-Modus im Einrichten-Wizard
@@ -692,9 +771,12 @@ beim Ändern die RouterOS-Suffix-Form zurück) — angewendet auf DHCP-Server
bestätigt** (inkl. neuem "Trennen"-Button im Verbinden-Tab, der dafür
nötig wurde). Fehlerzustände/Politur und REST-Schreibpfad-Verifikation
gegen ein Gerät mit aktivem `www-ssl` stehen noch aus.
- 🔶 M8: Mehrere LAN-Interfaces mit eigenem DHCP + Netzwerk-Isolation
(eigene Firewall-Regeln pro LAN/VLAN) — gebaut, nur Unit-Test-verifiziert,
noch nicht gegen echte Hardware getestet.
- M8: Mehrere LAN-Interfaces mit eigenem DHCP + Netzwerk-Isolation
(eigene Firewall-Regeln pro LAN/VLAN) — **live gegen Hardware
verifiziert**, sowohl manuell (SSH) als auch über den App-Wizard
selbst (`ether4`), dabei drei App-Bugs gefunden+gefixt (Bug 2224,
siehe oben). Isolation, DNS und Internet vom Nutzer am echten Gerät
bestätigt.
- 🔶 M9: Einfach/Experte-Modus im Einrichten-Wizard — gebaut, Compile/
Unit-Test-verifiziert. UI (Modusumschalter selbst) noch nicht manuell
durchgeklickt — nur M10s Experte-Tab wurde das (siehe M10).
@@ -765,41 +847,35 @@ beim Ändern die RouterOS-Suffix-Form zurück) — angewendet auf DHCP-Server
## Nächste Schritte
1. **In Arbeit, hier weitermachen:** kompletter Wizard-Durchlauf
(WAN/LAN mit zwei Interfaces ether2+ether3, eins isoliert/Firewall)
über den Experte-Modus — kombiniert M8-Hardware-Test (Netzwerk-
Isolation) mit diesem Punkt. Wurde in dieser Session begonnen, brach
beim WAN-Schritt mit Bug 21 ab (jetzt gefixt, deployt, aber
**ungetestet**). Nach erneutem Durchlauf: Firewall-Ergebnis mit
korrektem WAN-Port UND die Isolations-Regeln per
`/ip firewall filter print` kontrollieren, plus praktisch testen
(iMac ↔ Laptop sollten sich nicht erreichen, Internet für beide
schon).
2. WLAN (M5) an einem Gerät mit echtem WLAN-Chip nachholen.
3. Rest von M7: Fehlerzustände/Politur, REST-Schreibtest an einem Gerät
1. WLAN (M5) an einem Gerät mit echtem WLAN-Chip nachholen.
2. Rest von M7: Fehlerzustände/Politur, REST-Schreibtest an einem Gerät
mit aktivem `www-ssl`.
4. M8 gegen echte Hardware testen: zwei LAN-Interfaces/VLANs anlegen, eins
isoliert, anwenden, per `/ip firewall filter print` kontrollieren, dass
die Drop-Regeln greifen und der Rest (Internetzugriff, nicht-isolierte
Netzwerke) unangetastet bleibt.
5. M9 UI (Einfach/Experte-Modusumschalter im Einrichten-Tab selbst) noch
3. M9 UI (Einfach/Experte-Modusumschalter im Einrichten-Tab selbst) noch
manuell durchklicken — M10s Experte-Tab wurde bereits vom Nutzer
bestätigt (siehe oben), der Moduswechsel im Wizard noch nicht.
6. M10: WLAN-Schemas (an Gerät mit WLAN-Chip), Bonding, PPPoE-Client
4. M10: WLAN-Schemas (an Gerät mit WLAN-Chip), Bonding, PPPoE-Client
(mit echten oder Test-ISP-Zugangsdaten) noch gegen Hardware verifizieren.
7. Optional, kleinere Politur: den neuen Dauer-Editor
5. Optional, kleinere Politur: den neuen Dauer-Editor
(`RouterOSFieldSchema.Kind.duration`) auch auf weitere Zeitwert-Felder
anwenden, die bisher nur Text mit Beispiel-Tooltip sind — WireGuard-
Peer "Keepalive", Scheduler "Intervall", Netwatch "Prüf-Intervall".
Optional auch für den Geräte-Tab, falls dort künftig Zeitfelder
dazukommen.
8. **`.id`-Positions-Überlagerung (`fetchMenuItems`) auf weitere Menüs
6. **Firewall-NAT-/Filter-`add`-Befehle sind bei wiederholtem Wizard-Lauf
weiterhin nicht idempotent** — im Gegensatz zu den bei Bug 2224
gefixten Menüs lässt RouterOS identische NAT-/Filter-Regeln mehrfach
zu (kein Fehler, kein Abbruch), aber jeder erneute Wizard-Durchlauf
häuft doppelte Regeln an. Nicht blockierend (heute so live
beobachtet, Apply lief trotzdem durch), aber auf Dauer Regel-Bloat —
bei Gelegenheit auf "vorhandene identische Regel überspringen"
umstellen.
7. **`.id`-Positions-Überlagerung (`fetchMenuItems`) auf weitere Menüs
prüfen** — live als falsch bestätigt für `/ip dhcp-server lease`
(Bug 15). Betrifft potenziell jedes `.set`/`.remove` im Experte-Tab.
Am ehesten zu prüfen: bei einem Menü mit mehreren gleichzeitig
vorhandenen Einträgen `:put [<Pfad> find]` und `<Pfad> print terse`
unabhängig ausführen und die Reihenfolgen von Hand vergleichen.
9. **Router wurde zwischen M12 und M13 vom Nutzer komplett auf
8. **Router wurde zwischen M12 und M13 vom Nutzer komplett auf
Werkseinstellungen zurückgesetzt** ("damit wir sauber weitermachen
können"), und im Zuge des ersten M13-Testlaufs (Bug 18, Login-Sperre)
nochmal per Hardware-Reset zurückgesetzt. `test-vlan`/`testpool`/
@@ -812,7 +888,7 @@ beim Ändern die RouterOS-Suffix-Form zurück) — angewendet auf DHCP-Server
— vor Annahmen über den genauen aktuellen Stand lieber neu per
Geräte-/Übersicht-/Verbinden-Tab prüfen statt auf ältere Einträge hier
zu vertrauen.
10. **`fetchMenuItems`s Output-Text-Fallback (Bug 20) auf weitere
9. **`fetchMenuItems`s Output-Text-Fallback (Bug 20) auf weitere
Singleton-Menüs prüfen** — live nur für `/system routerboard`
bestätigt gebraucht zu werden (`/system identity` etc. liefen schon
vorher über den Exception-Zweig, siehe Bug 8). Nicht geprüft, ob es
@@ -820,10 +896,16 @@ beim Ändern die RouterOS-Suffix-Form zurück) — angewendet auf DHCP-Server
(weder Exception noch im Output-Text) — bei einer leer bleibenden
Liste in Übersicht/Geräte/Experte-Tab als erste Verdachtsquelle
prüfen.
10. **Offener Nutzerwunsch, noch nicht umgesetzt:** ausführlichere
Tooltips im Experte-Tab für alle Sektionen, mit konkretem
Adress-Format-Beispiel (z.B. "10.10.10.1/24") statt nur "mit
Präfix". Viele `RouterOSFieldSchema.help`-Texte in
`RouterOSSchemaCatalog.swift` sind aktuell leer (`help: ""`) oder
knapp ohne Beispielwert — wurde diese Session zugunsten des
M8-Hardware-Tests zurückgestellt.
Kein Gitea-Remote vorhanden — falls der Nutzer später eine Gitea-Instanz
aufsetzt (z.B. selbst gehostet auf der vorhandenen OMV-NAS, siehe
`Aperto/`-Projekt), Remote hinzufügen und pushen; bis dahin lokales Git.
Gitea-Remote `origin` ist eingerichtet und wird laufend gepusht (siehe
oben) — dieser Hinweis war veraltet, korrigiert am 2026-09-15.
`/Applications/RouterOS Assistant.app` ist der aktuell installierte
Release-Build, auf dem Stand des jeweils letzten Commits auf `main`