diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index 4aedaa7..b501b0c 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -385,15 +385,35 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". MikroTik-defconf). Umgedreht wurde sie beim handgebauten Core-Aufbau (TP21.1). - **Für TP6 ist das günstig:** Fasttrack umgeht die Queues, CAKE braucht sie — ein Konflikt, den man sonst erst auflösen müsste, existiert hier gar nicht. + - ✅ **ENTSCHIEDEN (Christoph, 2026-08-19): der Zustand bleibt — und gilt ab jetzt als Absicht, nicht + als Unfall.** Begründung: bei ~10 Mbit WAN kostet der Verzicht nichts (die Core-CPU trägt den + Forward-Pfad ohnehin, 32,9 Mio Pakete sind der Beleg), und für CAKE ist er die bequemere Ausgangslage. + Damit ist auch die TP21-Warnung „das Re-Baseline hat den Fehler zum Soll erklärt" **aufgelöst**: die + Reihenfolge in der SoT ist jetzt gewollt. Sie war es bei der Aufnahme nur nicht. + - ⚠️ **Gegenbedingung, unter der neu bewertet wird:** wenn **Inter-VLAN** je auf Gigabit soll + (NAS ↔ MAIN läuft geroutet über dieselbe 800-MHz-CPU), ist der Verzicht teuer. **Die Messung dafür + steht aus** — und sie, nicht die WAN-Zahl, ist die Vorbedingung jeder Neubewertung. - ⚠️ **Ungemessen ist der Preis:** ohne Fasttrack läuft **jedes** geroutete Paket durch die volle Kette samt Conntrack, auf der Core-CPU. Für 10 Mbit WAN irrelevant, für **Inter-VLAN**-Transfers (NAS ↔ MAIN, Synology Drive) möglicherweise nicht. Das ist messbar und sollte gemessen werden, bevor jemand die Reihenfolge „repariert". - 🔴 **Und es steht seit 2026-08-18 als ABSICHT in der SoT:** das Re-Baseline (`ingest-core-firewall.py --apply`) hat die Reihenfolge unverändert nach Nautobot geschrieben, - Rule `ip-firewall-filter` mit `config_ordered=true`. **Entscheidung nötig:** Reihenfolge korrigieren + Rule `ip-firewall-filter` mit `config_ordered=true`. ~~**Entscheidung nötig:** Reihenfolge korrigieren (Fasttrack lebt wieder) · Fasttrack-Regel entfernen (ehrlich: wir nutzen sie nicht) · so lassen und - hier begründet stehen lassen. Bis dahin ist der Zustand wenigstens dokumentiert statt still. + hier begründet stehen lassen.~~ → **entschieden am 2026-08-19, s. oben: so lassen.** Damit stimmen + SoT und Absicht wieder überein — bisher stimmten sie nur zufällig überein. +- 📋 **Runbook liegt bereit: `docs/tp6-praemisse-messrunbook.md`** (2026-08-19). Es reproduziert die + Methode von 2026-06-16 (3 Flows + 24 Pings idle/Last), misst erstmals auch die **Download-Richtung** + (die 2026-06-16 **nie** gemessen wurde — beim asymmetrischen Kabelanschluss die wahrscheinlichere + Problemseite), und trägt das Abbruchkriterium **vor** der Messung: A/A+ → TP6 wird **geschlossen statt + gebaut**. Enthält außerdem den Bau-Kontext für den Fall B, damit er nicht neu recherchiert wird — + vor allem: **`/queue` fehlt im GC-Template und hat keine ComplianceRule** (dieselbe blinde Stelle, die + TP26 für `/ip firewall filter` geschlossen hat), eine handgesetzte Queue wäre also driftend und + ungeschützt. +- 📌 **Nicht im Repo dokumentiert und deshalb Teil der Messung: die tatsächliche Liwest-Linerate.** + Die „~10 Mbit" stammen aus der Sättigungsmessung von 2026-06-16, nicht aus einem Tarifdatenblatt. + Ohne diese Zahl ist die übliche CAKE-Vorgabe „85–95 % Linerate" geraten. - **Abh.:** TP5 ✅ (keine Blocker mehr). Vorgelagert: die Messung oben. ### TP7 — Media-Discovery (mDNS) für VLAN 40 ▸ ✅ FERTIG (2026-07-02) — `docs/tp7-mdns.md` @@ -892,6 +912,10 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". war bewusst, die *Umgebung*, die mitgeschrieben wurde, hat aber niemand angesehen. **Merkregel: nach dem ersten Re-Baseline einer Sektion deren Diff einmal ganz lesen**, nicht nur die Zeilen, die man selbst angefasst hat. + - ✅ **Nachtrag 2026-08-19: der konkrete Fall ist aufgelöst** — Christoph hat entschieden, die + Fasttrack-Reihenfolge **so zu lassen** (Begründung in TP6). Der Eintrag in der SoT ist damit + nachträglich korrekt. **Die Merkregel bleibt trotzdem gültig:** dass ein versehentlich + mitgeschriebener Zustand sich hinterher als brauchbar herausstellt, ist Glück, kein Verfahren. - 🔧 **Zwei echte Template-Fehler, beim Re-Baseline 2026-08-18 gefunden** (beide gepusht): - `/ip service set … **address=**` → RouterOS 7.23/7.24 exportiert **`available-from=`**. Das erzeugte vier Dauer-Drifts (ap1/ap2/branch/core), bei denen das **Geraet** recht hatte und das @@ -1598,7 +1622,11 @@ Ziel ist. Alles andere läuft nebenher und blockiert nichts. Anlernen eines IoT-Geraets (User 2026-08-17). Wer im IOT-SSID sitzt, ist im selben VLAN wie das Geraet und beruehrt die `forward`-Kette gar nicht; fuer Ad-hoc-Zugriffe aus MAIN gibt es jetzt die selbstverfallende Gruppe `jit-admin`. -2. 🔜 **TP6 — QoS/CAKE + Call-Quality-A/B-Test.** Das eigentliche Projektziel; **keine offenen Blocker mehr**. +2. 🟠 **TP6 — QoS/CAKE + Call-Quality-A/B-Test.** ~~Das eigentliche Projektziel; **keine offenen Blocker mehr**.~~ + **Korrigiert 2026-08-19:** kein *Blocker*, aber eine offene **Prämisse** — der Satz oben und dieser + Punkt widersprachen sich seit dem 18. Richtig ist: der nächste Schritt ist eine **Messung**, kein Bau. + Runbook liegt bereit: `docs/tp6-praemisse-messrunbook.md`. Fällt sie A/A+ aus, wird TP6 **geschlossen + statt gebaut** — dann ist der kritische Pfad leer und das Projekt in seinem Kern fertig. **Eine harte Reihenfolge-Regel dazwischen:** TP5 darf die **DNS-Bypass-Sperre erst schließen, wenn TP23s Ausnahme-Oberfläche steht** — der bisherige Workaround „Client von Hand auf `1.1.1.1`" *ist* genau dieser diff --git a/docs/tp6-praemisse-messrunbook.md b/docs/tp6-praemisse-messrunbook.md new file mode 100644 index 0000000..da27f12 --- /dev/null +++ b/docs/tp6-praemisse-messrunbook.md @@ -0,0 +1,179 @@ +# TP6 — Prämissen-Messung: hat dieses Netz überhaupt ein Bufferbloat-Problem? + +> **Stand 2026-08-19 · vorbereitet, nicht ausgeführt.** Dieses Runbook ändert **nichts** am Netz. +> Es misst, und es sagt vorher, was das Ergebnis bedeutet. +> +> **Der Deliverable dieses Runbooks ist eine Entscheidung, keine Queue.** + +--- + +## 1. Warum gemessen wird, bevor gebaut wird + +TP6 wird seit Monaten als „DAS Ziel" des Projekts geführt. Gleichzeitig liegt seit dem 2026-06-16 eine +Messung im Repo, die zum gegenteiligen Schluss kommt — [`call-quality-diagnosis.md`](call-quality-diagnosis.md) +sagt im Kopf, TP6 habe sich als **Nicht-QoS-Problem** entpuppt, und in der Ergebnistabelle wörtlich: + +``` +CAKE / QoS | kein Bufferbloat-Spielraum | ❌ nicht deployt (wäre marginal) +``` + +**Die Zahlen von damals:** + +| Größe | Wert | +|---|---| +| Upload gesättigt (3 Flows) | **10,3 Mbit** sustained | +| Latenz idle | **12 ms** | +| Latenz unter Vollast | avg **17,5 ms** / max **26 ms** (24 Pings) | +| Bufferbloat-Grade | **A / A+** | + +Bei einem Latenzanstieg von 12 → 17,5 ms unter Sättigung holt CAKE nichts mehr. Das ist der Grund, +warum dieses Runbook existiert: **es wäre falsch, eine Queue zu bauen, ohne diesen Befund zu widerlegen.** + +### Was den Befund relativiert + +Die Messung stammt aus der **FritzBox-Ära**. Seither ist der Edge komplett getauscht: + +| damals (2026-06-16) | heute | +|---|---| +| FritzBox 6660 macht NAT + Queuing | **`crs326-core`** macht NAT + Queuing (ARM 2×800 MHz) | +| FB am Liwest-Anschluss | **Arris im Bridge-Mode**, Public-IP direkt auf `vlan100` | +| Double-NAT | kein Double-NAT | +| 2× Cudy als AP | 2× hAP ax² als CAPs unter CAPsMAN | + +**Die Leitung ist dieselbe. Das Pufferverhalten des neuen Edge ist ungemessen.** Genau diese Lücke +schließt die Messung. + +--- + +## 2. Methodengleichheit ist die halbe Messung + +⚠️ **Wer anders misst als 2026-06-16, kann die beiden Zahlen nicht vergleichen** — und ohne Vergleich +ist die Messung wertlos, weil die Kernfrage lautet „hat sich seit dem Edge-Tausch etwas verschlechtert?". + +Deshalb: **dieselbe Methode zuerst**, die bequemere danach. + +### 2.1 Primärmessung — reproduziert 2026-06-16 + +Von einem **kabelgebundenen** Client in VLAN10 (WLAN würde die Messung mit Funk-Jitter verseuchen): + +1. **Baseline idle** — 24 Pings gegen ein stabiles externes Ziel, Netz ansonsten ruhig. + ```bash + ping -c 24 1.1.1.1 + ``` + Notieren: min / avg / max. + +2. **Sättigung aufbauen** — 3 parallele Upload-Flows, bis die Rate steht (das war 2026-06-16 der + Aufbau: 3 Flows × ~430 KB/s = 1,28 MB/s = 10,3 Mbit). Sättigung heißt: die Summenrate ist über + ≥30 s stabil, nicht der Peak der ersten Sekunden. + +3. **Ping unter Last** — dieselbe Ping-Reihe **während** die Flows laufen. + ```bash + ping -c 24 1.1.1.1 + ``` + +4. **Dasselbe für Download.** 🔴 **Die Download-Seite wurde 2026-06-16 nie gemessen** — das ist die + größte Lücke im Altbefund. Kabelanschlüsse sind asymmetrisch, und der Down-Puffer sitzt beim ISP, + wo ein Router ihn nur per Ingress-Shaping erreicht. Wenn dieses Netz irgendwo Bufferbloat hat, + dann am wahrscheinlichsten hier. + +### 2.2 Sekundärmessung — waveform als unabhängige Zahl + +`https://www.waveform.com/tools/bufferbloat` vom selben Client. Liefert den Buchstaben-Grade und +trennt Up/Down sauber. **Dient der Gegenprobe, nicht als alleinige Grundlage** — die Ping-Reihe aus +2.1 ist die vergleichbare Zahl. + +### 2.3 Was am Core mitläuft (read-only, parallel) + +Während der Sättigung, damit die Zahl nicht ohne Kontext dasteht: + +- **CPU-Last:** `/system resource print` — der Core ist ein **Switch mit 800-MHz-ARM-CPU**, kein + Router-Boliden. Geht die CPU unter 10 Mbit schon hoch, ist das ein eigener Befund. +- **Interface-Rate:** `/interface monitor-traffic vlan100` — bestätigt, dass die Sättigung wirklich + am WAN ankommt und nicht vorher im LAN hängt. +- **Tatsächliche Linerate:** aus der gemessenen Sättigung ableiten. ⚠️ Die im Projekt kolportierten + „~10 Mbit Upload" stammen aus der Diagnose-Session; **der aktuelle Liwest-Tarif ist nirgends im Repo + dokumentiert.** Wenn die Messung deutlich mehr zeigt, gehört die Zahl nachgetragen — sie ist die + Grundlage jeder späteren Prozent-Vorgabe. + +--- + +## 3. Das Abbruchkriterium — steht VOR der Messung fest + +> Dieser Abschnitt ist der eigentliche Zweck des Runbooks. Eine Schwelle, die erst nach dem Ergebnis +> festgelegt wird, ist keine Schwelle. + +| Ergebnis unter Last | Entscheidung | +|---|---| +| **Grade A oder A+** (Latenzanstieg ≲ 30 ms über idle, beide Richtungen) | **TP6 wird geschlossen, nicht gebaut.** | +| **Grade B oder schlechter** in mindestens einer Richtung | **CAKE ist die Antwort** — dann mit einer Zahl als Begründung. | + +### Fall A — es bleibt A/A+ + +Das ist der wahrscheinliche Ausgang, und er ist **kein Misserfolg**: + +1. TP6 bekommt einen datierten Eintrag „✅ geschlossen — gemessen statt gebaut", mit beiden Messreihen + (2026-06-16 und heute) nebeneinander. +2. Der **kritische Pfad wird leer.** Das Projekt ist in seinem Kern fertig — deny-by-default steht, + Golden Config steht, WLAN steht, VLAN1 ist weg. +3. **Christoph entscheidet, was das neue Ziel ist.** Kandidaten aus der bestehenden Liste: TP24 (USV), + TP11 (Monitoring), TP16.2 (Härtung), TP12 (IPv6). +4. `call-quality-diagnosis.md` bekommt eine Bestätigungszeile — der Befund von damals hat gehalten. + +### Fall B — es ist schlechter geworden + +Dann ist **die Ursache neu**, denn 2026-06-16 war es gut. Vor jeder Queue erst die Ursache eingrenzen: + +- Neuer Edge (Arris-Puffer) · CPU-Deckel am Core · gestiegene Grundlast (7 VLANs statt flach) +- Erst danach CAKE — und dann als Antwort auf eine benannte Ursache, nicht als Ritual. + +--- + +## 4. Kontext für den Bau-Fall (damit er später nicht neu recherchiert wird) + +Beides ist am 2026-08-18/19 live erhoben und muss nicht erneut ermittelt werden. + +### 4.1 `/queue` fehlt im Golden-Config-Template + +[`nautobot/mikrotik_routeros.j2`](../nautobot/mikrotik_routeros.j2) hat **keinen `/queue`-Block**, und es +gibt keine ComplianceRule dafür. Eine von Hand gesetzte CAKE-Queue wäre damit: + +- **unsichtbar für die Compliance** (sie meldet weiter „compliant", während die Queue driftet), und +- **beim nächsten Deploy nicht geschützt.** + +→ CAKE braucht **Template-Block + ComplianceRule**, nicht nur die Queue. Das ist exakt dieselbe Lücke, +die **TP26** für `/ip firewall filter` geschlossen hat — dort war der blinde Fleck 25 Firewallregeln groß. + +### 4.2 Fasttrack ist auf dem Core faktisch tot — Entscheid: **so lassen** + +Live gezählt (2026-08-18/19): + +``` +2 accept | defconf: accept est,rel,untracked | 32.979.171 Pakete +3 fasttrack-connection | defconf: fasttrack | 0 Pakete + 0 von 445 Verbindungen fasttracked +``` + +Die `accept`-Regel steht **vor** der Fasttrack-Regel, also wird Fasttrack nie erreicht. +**Herkunft:** `ap1` hatte die Reihenfolge vor dem Cutover richtig (Fasttrack zuerst, MikroTik-defconf); +umgedreht wurde sie beim handgebauten Core-Aufbau in TP21.1. + +**Entscheidung (Christoph, 2026-08-19): der Zustand bleibt — und zwar als Absicht, nicht als Unfall.** + +- **Für CAKE ist er günstig.** Fasttrack umgeht die Queues; CAKE braucht sie. Der Konflikt, den man + sonst erst auflösen müsste, existiert hier gar nicht. +- **Bei ~10 Mbit WAN kostet er nichts.** Die Core-CPU trägt den Forward-Pfad ohnehin schon — + 32,9 Mio Pakete sind der Beweis, nicht die Vermutung. +- ⚠️ **Gegenbedingung, unter der neu bewertet wird:** wenn **Inter-VLAN** je auf Gigabit soll + (NAS ↔ MAIN läuft geroutet über dieselbe CPU), ist der Verzicht auf Fasttrack teuer. **Diese Messung + steht aus** und ist die Vorbedingung jeder Neubewertung — nicht die WAN-Zahl aus diesem Runbook. + +--- + +## 5. Abnahme dieses Runbooks + +1. Beide Messreihen (Up **und** Down, idle **und** Last) liegen als Zahlen vor, nicht als Eindruck. +2. Die Entscheidung ist gegen die Tabelle aus §3 gefallen — **nicht** gegen ein Bauchgefühl. +3. Das Ergebnis steht datiert in TP6, und der kritische Pfad ist entsprechend nachgezogen. +4. Die tatsächliche Linerate ist dokumentiert (sie fehlte bisher im ganzen Repo). +5. **Kein Netz-Eingriff** im Fall A. Im Fall B entsteht ein *zweites* Runbook, das gebaut wird — + dieses hier bleibt die Begründung dafür. diff --git a/routeros/tp5-e5-main-iot.rsc b/routeros/tp5-e5-main-iot.rsc new file mode 100644 index 0000000..a211a78 --- /dev/null +++ b/routeros/tp5-e5-main-iot.rsc @@ -0,0 +1,50 @@ +# TP5 Etappe 5 — MAIN -> IOT aufmachen. +# +# BEFUND (User-Meldung 2026-08-19: Brother P750W und die Shellys aus VLAN10 +# nicht erreichbar). Der Deny-by-default aus Etappe 3 arbeitet korrekt — es +# gab schlicht nie eine vlan10->vlan30-Zeile. Offen waren nur MAIN->MEDIA, +# MAIN->INFRA, MAIN->MGMT; IOT fehlte in der Liste. +# +# QUELLE: /opt/tp5-syslog/log/tp5-would-drop.log auf dem Docker-LXC, +# gefiltert auf "in:vlan10 out:vlan30". Aggregiert: +# 497 ICMP (Ping auf .30.5 und die Shellys) +# 489 udp 5353 mDNS +# 489 udp 137 NetBIOS +# 237 udp 3722 Apple-Continuity -> .30.201 +# 40 udp 161 SNMP -> 10.40.30.5 (Brother P750W) +# Quellen: .10.183 (1596, Subnetz-Sweep), .10.180 (118), .10.82 (38). +# +# MERKREGEL AUS DEM LOG: der Drucker faellt mit udp/161 auf, NICHT mit 631. +# macOS fragt zuerst den SNMP-Status ab und bricht ab, bevor es zu IPP kommt. +# Wer nur 631 whitelistet, repariert nichts. +# +# ENTSCHEID (User, 2026-08-19): voll einbahnig, kein Portfilter. +# - MAIN ist das vertrauenswuerdige VLAN und steht zu INFRA/MEDIA/MGMT +# ohnehin schon vollstaendig offen — INFRA haelt NAS, Proxmox und +# Nautobot, also deutlich mehr Wert als die Shellys. MAIN->IOT eng zu +# filtern waere an dieser Stelle Symbolik, kostet aber bei jedem neuen +# IoT-Geraet eine Runde Fehlersuche. +# - Der Sicherheitswert der Segmentierung sitzt in der GEGENRICHTUNG: +# IOT->MAIN bekommt bewusst KEIN accept und bleibt gedroppt. Antworten +# auf Anfragen aus MAIN laufen ueber "defconf: accept est,rel,untracked", +# dafuer braucht es keine Regel. +# +# NEBENWIRKUNG, bewusst in Kauf genommen: der Subnetz-Sweep von .10.183 +# (137/5353 an alle 254 Adressen) laeuft ab jetzt durch, statt im Drop-Log +# aufzulaufen. Betriebsneutral, aber der Log wird an dieser Stelle leiser — +# nicht mit "Problem geloest" verwechseln. +# +# INPUT-KETTE: unveraendert. "TP5-E4: MAIN->core admin" und +# "TP5: mDNS in vlan30" stehen bereits, der Core braucht nichts. +# +# BLOCKIERT NICHTS: ausschliesslich action=accept. +# +# Push: python3 nautobot/gc-manual-plan.py --device crs326-core \ +# --commands-file routeros/tp5-e5-main-iot.rsc \ +# --change-id TP5-E5-MAIN-IOT --deploy \ +# --assert '/ip/firewall/filter?comment=TP5-E5: MAIN->IOT|count=1' +# --------------------------------------------------------------------------- + +# 1) MAIN -> IOT, einbahnig. place-before die Log-Regel, damit sie vor dem +# Drop greift und der Log weiter zeigt, was uebrig bleibt. +:do { :if ([:len [/ip firewall filter find comment="TP5-E5: MAIN->IOT"]] = 0) do={ /ip firewall filter add chain=forward action=accept in-interface=vlan10 out-interface=vlan30 comment="TP5-E5: MAIN->IOT" place-before=[/ip firewall filter find comment="TP5: log-only, Vorstufe zum deny-by-default"] } } on-error={ :log info "tp5e5: 01 MAIN->IOT warf" }