RouterBOOT-Klickanleitung + TP5 E3/E4 abgenommen, NTP-Zeitquelle, Template-Fixes
docs/routerboot-firmware-klickanleitung.md: Schritt-fuer-Schritt fuer WinBox. RouterOS ist auf allen vier bereits 7.24, nur der Bootloader haengt zurueck (core/branch 7.19.5, ap1/ap2 7.23.2 -- live erhoben). Der Weg geht per Hand, weil `/system routerboard upgrade` interaktiv nachfragt: MikroMCP blockt ihn per Deny-Policy, und Netmiko bekommt den Prompt statt einer Antwort und quittiert mit E3001 bei LEERER Fehlermeldung. Auf core/branch waere ein Scheduler-Umweg moeglich, auf den APs nicht (device-mode=home sperrt ihn). Reihenfolge ap1 -> ap2 -> core -> branch mit Ausfall je Geraet; branch zuletzt, weil der Arbeitsplatz per Kabel daran haengt. Dazu Gegenprobe-Einzeiler fuer alle vier und die Falle, dass ohne Schritt 7 (Reboot) `Current Firmware` alt bleibt. Aus der Parallelsession dazugekommen: - TP5 Etappe 3 UND 4 sind abgenommen, beide Auto-Reverts abbestellt. Die Abnahmen stehen in den Skriptkoepfen: forward-Drop hat in der Testphase 11 Pakete gefressen, ausschliesslich die eigene pve->branch:22-Sonde; beim input-Drop war es reines Broadcast-Rauschen (NetBIOS, SSDP). Der GC-Deploy-Pfad wurde als Pfadbeweis mitgetestet (nautobot-worker -> ap2:22 = SUCCESS). - E4-Nachtrag: MNDP und CAPWAP muessen in den input. Die CAPs finden ihren Manager per Layer-2-Discovery (`current-caps-man-address` ist eine MAC, keine IP) -- bestehende Sitzungen laufen ueber seal-est weiter, der Bruch schluege also erst beim naechsten AP- oder Manager-Neustart zu. - TP19 NTP: alle drei Nicht-Core-Geraete fragten einen Zeitserver, den es nicht gab (`status=waiting`, branch hatte gar keinen). ap2 war 17 Stunden nach und hat einen Logeintrag von 04:57 als 12:19 gestempelt -- geraeteuebergreifende Korrelation war damit wertlos. Core wird Zeitquelle, die drei werden Clients. - Template: `/ip service` exportiert `available-from=`, nicht `address=`. Das Soll war falsch und das Geraet hatte recht -- vier Dauer-Drifts. Und `hw-offload` fliegt aus dem Firewall-Renderer, weil REST es meldet und /export es weglaesst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
18
CLAUDE.md
18
CLAUDE.md
@@ -1,7 +1,8 @@
|
|||||||
# BF-Netzwerk — Projekt-Kontext (auto-read)
|
# BF-Netzwerk — Projekt-Kontext (auto-read)
|
||||||
|
|
||||||
**Standort BF:** VLAN-segmentiertes Heimnetz auf MikroTik/RouterOS. Ziel: CAKE/QoS gegen Bufferbloat,
|
**Standort BF:** VLAN-segmentiertes Heimnetz auf MikroTik/RouterOS. Ziel: CAKE/QoS gegen Bufferbloat,
|
||||||
DNS/DHCP-Ablösung, WLAN via Standalone-APs (kein CAPsMAN), Firewall Least-Privilege, Multi-Site VPN.
|
DNS/DHCP-Ablösung, WLAN via **CAPsMAN auf dem Core** (TP28, 2026-08-17 — der Standalone-Entscheid von
|
||||||
|
2026-07-22 ist revidiert), Firewall Least-Privilege (**TP5 deny-by-default scharf seit 2026-08-18**), Multi-Site VPN.
|
||||||
|
|
||||||
**Für jede TP-Session: zuerst `docs/teilprojekte.md` lesen** — enthält kanonischen Stand, Scope, Abhängigkeiten
|
**Für jede TP-Session: zuerst `docs/teilprojekte.md` lesen** — enthält kanonischen Stand, Scope, Abhängigkeiten
|
||||||
und Reihenfolge aller Teilprojekte. Kein anderer Kontext nötig.
|
und Reihenfolge aller Teilprojekte. Kein anderer Kontext nötig.
|
||||||
@@ -29,10 +30,10 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| ~~ALLNET Core-Switch (sw1)~~ | — | ❌ **außer Betrieb (2026-08-08)** — durch `crs326-core` (L3-Router + Core-Switch, Technik UG) ersetzt; physisch abgelöst. (Telnet-Runner `switch/` = nur noch historisch.) |
|
| ~~ALLNET Core-Switch (sw1)~~ | — | ❌ **außer Betrieb (2026-08-08)** — durch `crs326-core` (L3-Router + Core-Switch, Technik UG) ersetzt; physisch abgelöst. (Telnet-Runner `switch/` = nur noch historisch.) |
|
||||||
| ~~Omada Access-Switch (sw2)~~ | — | ❌ **abgebaut 2026-07-23** (TP15 Branch-Tausch) — durch `crs326-branch` in Technik OG ersetzt, physisch entfernt |
|
| ~~Omada Access-Switch (sw2)~~ | — | ❌ **abgebaut 2026-07-23** (TP15 Branch-Tausch) — durch `crs326-branch` in Technik OG ersetzt, physisch entfernt |
|
||||||
| **crs326-branch** (CRS326, Technik OG) | **10.40.99.2** (VLAN99; temp VLAN10 `.10.2`) · Bootstrap Rev4 2026-08-08 | RouterOS 7.19.5 · `admin`/`~/.secrets` (`CRS326_BRANCH_*`) · REST `http://10.40.99.2/rest` · MikroMCP `crs326-branch` ✅ **live** (2026-08-16 verifiziert) · **TP15 ✅: ersetzt sw2** (L2-Switch), volle Portbelegung (ether1 Uplink-Trunk, 2/8 NAS, 3 Drucker, 4 Dock, 5/6 Sonos, 7 macmini, 24 ap2) · sw-id RGZJ-UK0T, MAC 04:F4:1C:B4:15:58 |
|
| **crs326-branch** (CRS326, Technik OG) | **10.40.99.2** (VLAN99) · Bootstrap Rev4 2026-08-08 | RouterOS **7.24** · `admin`/`~/.secrets` (`CRS326_BRANCH_*`) · REST `http://10.40.99.2/rest` · MikroMCP `crs326-branch` ✅ **live** (2026-08-16 verifiziert) · **TP15 ✅: ersetzt sw2** (L2-Switch), volle Portbelegung (ether1 Uplink-Trunk, 2/8 NAS, 3 Drucker, 4 Dock, 5/6 Sonos, 7 macmini, 24 ap2) · sw-id RGZJ-UK0T, MAC 04:F4:1C:B4:15:58 |
|
||||||
| **crs326-core** (CRS326, Technik UG) | **10.40.99.1** (VLAN99-SVI = L3-GW; same-subnet-Fallback `10.40.10.1`) · Identity `crs326-core` | RouterOS 7.19.5 · `admin`/`~/.secrets` (`CRS326_CORE_*`) · MikroMCP routerId `crs326-core` ✅ **live** (2026-08-16 verifiziert) · **TP15/TP21.1 ✅ 2026-08-08: PRODUKTIVER L3-Router** (ersetzt ap1) — Routing/DHCP (7 Server + 54 Leases)/DNS (plain `1.1.1.1`, DoH-Cloudflare-TODO)/NAT/WG-Hub (fm+dw live); WAN `vlan100`=Liwest `90.146.33.177` · sw-id 4W04-URHT, MAC 04:F4:1C:B4:17:76 |
|
| **crs326-core** (CRS326, Technik UG) | **10.40.99.1** (VLAN99-SVI = L3-GW; same-subnet-Fallback `10.40.10.1`) · Identity `crs326-core` | RouterOS **7.24** · `admin`/`~/.secrets` (`CRS326_CORE_*`) · MikroMCP routerId `crs326-core` ✅ **live** (2026-08-16 verifiziert) · **TP15/TP21.1 ✅ 2026-08-08: PRODUKTIVER L3-Router** (ersetzt ap1) — Routing/DHCP (7 Server + 54 Leases)/DNS (**DoH zum CF-Gateway mit `verify-doh-cert=yes`**, TP23 Stufe 1 ✅ 2026-08-18; `servers=1.1.1.1` nur noch Bootstrap) · **NTP-Server für den Standort**/NAT/WG-Hub (fm+dw live); WAN `vlan100`=Liwest `90.146.33.177` · sw-id 4W04-URHT, MAC 04:F4:1C:B4:17:76 |
|
||||||
| hAP ax² #1 (ap1) | **10.40.99.11** (VLAN99) · Identity `ap1` | RouterOS 7.23.2 · `admin`/`~/.secrets` (`ROUTER_AP1_*`) · REST `http://10.40.99.11/rest` · MikroMCP `ap1` ✅ live · **TP3-Rebuild ✅ 2026-08-08: reiner Standalone-AP, KEIN CAPsMAN** — Uplink `ether1` (PoE-Port, `poe-out=off`) an crs326-core `ether15`; 6 SSIDs dirtyvader-main/-infra/-iot/-media/-untrusted/-guest, ch36/ch1; jede SSID mit `datapath` (TP3.1-Leck gefixt) · MAC D0:EA:11:4D:40:E0 · Config-Referenz `routeros/.secrets/ap1-prov-base.rsc` |
|
| hAP ax² #1 (ap1) | **10.40.99.11** (VLAN99) · Identity `ap1` | RouterOS **7.24** · `admin`/`~/.secrets` (`ROUTER_AP1_*`) · REST `http://10.40.99.11/rest` · MikroMCP `ap1` ✅ live · **TP28 ✅ 2026-08-17: reiner CAP** (Manager = `crs326-core`, `cap enabled=yes`, `discovery-interfaces=vlan99`) — Uplink `ether1` (PoE-Port, `poe-out=off`) an crs326-core `ether15`; SSIDs/Kanäle kommen vom Manager, ch36/ch1 · MAC D0:EA:11:4D:40:E0 · Config-Referenz `routeros/.secrets/ap1-prov-base.rsc` |
|
||||||
| hAP ax² #2 (ap2) | **10.40.99.12** (VLAN99) · Identity `ap2` | RouterOS 7.23.2 · `admin`/`~/.secrets` (`ROUTER_AP2_*`) · REST `http://10.40.99.12/rest` · MikroMCP `ap2` · **TP3-Rebuild ✅ 2026-08-08: reiner Standalone-AP** — Uplink `ether1` (PoE) an crs326-branch `ether24`; identisch zu ap1, ch149/ch11 · MAC D0:EA:11:4D:40:3A · Config `routeros/.secrets/ap2-prov-base.rsc` |
|
| hAP ax² #2 (ap2) | **10.40.99.12** (VLAN99) · Identity `ap2` | RouterOS **7.24** · `admin`/`~/.secrets` (`ROUTER_AP2_*`) · REST `http://10.40.99.12/rest` · MikroMCP `ap2` · **TP28 ✅ 2026-08-17: reiner CAP** — Uplink `ether1` (PoE) an crs326-branch `ether24`; ch44/ch11 (TP25: ch149 war unter ETSI leistungsbegrenzt) · MAC D0:EA:11:4D:40:3A · Config `routeros/.secrets/ap2-prov-base.rsc` |
|
||||||
| **🔑 Einheitliches Admin-PW (2026-08-08)** | alle 4 MikroTik (core/branch/ap1/ap2) | user `admin`, gleiches PW (`~/.secrets/credentials.env` → `ROUTER_*_PASS`/`CRS326_*_PASS`; „Überlebensversicherung", User-Vorgabe). Werks-Defaults ap1/ap2 damit obsolet. |
|
| **🔑 Einheitliches Admin-PW (2026-08-08)** | alle 4 MikroTik (core/branch/ap1/ap2) | user `admin`, gleiches PW (`~/.secrets/credentials.env` → `ROUTER_*_PASS`/`CRS326_*_PASS`; „Überlebensversicherung", User-Vorgabe). Werks-Defaults ap1/ap2 damit obsolet. |
|
||||||
| NAS (nas-bf, DS923) | 10.40.20.10 | SSH `adm.christoph@10.40.20.10` (kein PW nötig) · Docker (Portainer endpointId=14) |
|
| NAS (nas-bf, DS923) | 10.40.20.10 | SSH `adm.christoph@10.40.20.10` (kein PW nötig) · Docker (Portainer endpointId=14) |
|
||||||
| platform-pg (LXC 105, pve) | 10.40.20.20 | SSH via pve (`pct exec 105 --`) · **TP20 ✅ 2026-07-16: PG16, DB `nautobot`, Creds `postgres/.secrets`** |
|
| platform-pg (LXC 105, pve) | 10.40.20.20 | SSH via pve (`pct exec 105 --`) · **TP20 ✅ 2026-07-16: PG16, DB `nautobot`, Creds `postgres/.secrets`** |
|
||||||
@@ -70,10 +71,13 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
|
|||||||
- 📜 **~~ALLNET VLAN-DB (TP1)~~ — historisch.** Die VLAN-Semantik gilt weiter (**40=MEDIA, 50=UNTRUSTED**), die Portangaben (GE1/GE2/GE8) beziehen sich auf ein ausgebautes Gerät.
|
- 📜 **~~ALLNET VLAN-DB (TP1)~~ — historisch.** Die VLAN-Semantik gilt weiter (**40=MEDIA, 50=UNTRUSTED**), die Portangaben (GE1/GE2/GE8) beziehen sich auf ein ausgebautes Gerät.
|
||||||
- **ap2 hängt an `crs326-branch ether24`** (Trunk, native VLAN1 + tagged 10-99); **branch-Uplink `ether1` → `crs326-core ether8`** (korrigiert 2026-08-16 — die frühere Angabe „→ sw1 GE8" stammt aus der Zeit vor dem Core-Tausch; MAC-hart belegt in TP22 Schritt 5).
|
- **ap2 hängt an `crs326-branch ether24`** (Trunk, native VLAN1 + tagged 10-99); **branch-Uplink `ether1` → `crs326-core ether8`** (korrigiert 2026-08-16 — die frühere Angabe „→ sw1 GE8" stammt aus der Zeit vor dem Core-Tausch; MAC-hart belegt in TP22 Schritt 5).
|
||||||
- **Mesh = NEIN** (beide APs haben wired Trunk-Uplink → Loop-Risiko).
|
- **Mesh = NEIN** (beide APs haben wired Trunk-Uplink → Loop-Risiko).
|
||||||
- **Beide APs = Standalone mit `vlan-filtering=yes`, KEIN CAPsMAN (TP3-Rebuild ✅ 2026-08-08):** `datapath.vlan-id` landet nur mit vlan-filtering auf der Leitung. Nur Master-Radios wifi1/wifi2 sind Bridge-Ports (Slave-VAPs forwarden darüber) → **wifi1/wifi2 müssen tagged-Member je Client-VLAN sein**. Uplink=`ether1` (PoE), VLAN1 untagged=Fallback. Jede SSID-config braucht `datapath` (sonst egress ungetaggt in VLAN1 = das alte TP3.1-Leck). **Falle bei Neu-Provisionierung:** Werks-Inline-Overrides auf wifi1/wifi2 (`configuration.ssid=MikroTik-*`, `security.*`) überschreiben das verlinkte Profil → nach `/import` mit `!configuration.ssid !security.*` leeren. Configs `routeros/.secrets/ap{1,2}-prov-base.rsc`.
|
- **Beide APs = CAPs, Manager ist `crs326-core` (TP28 ✅ 2026-08-17).** Der Entscheid „kein CAPsMAN" von 2026-07-22 ist **revidiert**: er galt der Konstellation ap1=Manager+AP, in der ein Manager seine eigenen Radios nicht provisionieren kann — mit dem Core als Manager sind beide APs symmetrisch. Der Core braucht dafür **kein** `wifi-qcom`, `capsman` steckt im Basispaket.
|
||||||
|
- 🔴 **Messfalle: unter CAPsMAN führt der MANAGER die Tabellen.** `/interface/wifi/registration-table` und die `wireless`-Logs sind auf ap1/ap2 **leer**, obwohl das WLAN läuft. **Immer am Manager zählen.**
|
||||||
|
- 🔴 **Die CAPs finden den Manager per Layer-2-Discovery** (`discovery-interfaces=vlan99`, `current-caps-man-address` ist eine **MAC**, keine IP). Deshalb müssen **MNDP (udp/5678)** und **CAPWAP (udp/5246-5247)** in der `input`-Kette des Core erlaubt bleiben — sonst kommt das WLAN nach dem nächsten AP-Reboot nicht zurück, während laufende Sessions unauffällig weiterlaufen (Fund 2026-08-18, TP5 Etappe 4).
|
||||||
|
- **Local Forwarding ist keine Einstellung mehr:** im neuen `/interface/wifi` gibt es kein zentrales Forwarding, `datapath` existiert dort nicht.
|
||||||
- mgmt-VLAN-Wechsel am Switch = Lockout-Risiko: VLAN muss existieren + Port muss es tragen, in einem Schritt.
|
- mgmt-VLAN-Wechsel am Switch = Lockout-Risiko: VLAN muss existieren + Port muss es tragen, in einem Schritt.
|
||||||
- 📜 **~~Omada ES208G = Easy Managed~~ — gegenstandslos** (Gerät abgebaut 2026-07-23, Controller gelöscht).
|
- 📜 **~~Omada ES208G = Easy Managed~~ — gegenstandslos** (Gerät abgebaut 2026-07-23, Controller gelöscht).
|
||||||
- **L3-Router = `crs326-core` (TP21.1 ✅ 2026-08-08, ersetzt ap1).** Bridge vlan-filtering=yes; VLAN-SVIs `.1` je VLAN mit DHCP (7 Server / 54 Leases); DNS aktuell **plain `1.1.1.1`** (DoH-Cloudflare-Gateway-TODO, core hat kein CA). **ap1/ap2 sind NUR noch APs** — kein DHCP/DNS/NAT/Routing/WG dort. (Die frühere „TP4: ap1 ist L3-Router"-Zeile ist überholt.)
|
- **L3-Router = `crs326-core` (TP21.1 ✅ 2026-08-08, ersetzt ap1).** Bridge vlan-filtering=yes; VLAN-SVIs `.1` je VLAN mit DHCP (7 Server / 54 Leases); DNS über **DoH** zum CF-Gateway, `verify-doh-cert=yes` (TP23 Stufe 1 ✅ 2026-08-18). Die alte Notiz „core hat kein CA" war zu pessimistisch: es braucht kein Bundle, sondern **genau einen Root** (GTS Root R4, ~1 KB) — die Kette ist Leaf → GTS WE1 → R4. **Beide Firewall-Ketten enden seit 2026-08-18 mit `drop`** (TP5 E3/E4); `TP10-seal-lan` ist `disabled`, Mgmt-Input kommt nur noch aus VLAN10, von HA (`8728`), von Nautobot (`22`) und über `cf-mesh`. **ap1/ap2 sind NUR noch APs** — kein DHCP/DNS/NAT/Routing/WG dort. (Die frühere „TP4: ap1 ist L3-Router"-Zeile ist überholt.)
|
||||||
- **✅✅ Edge-Cutover (2026-07-01; Router-Umzug 2026-08-08): FritzBox ausgebaut, Arris im Bridge-Mode.** Liwest hat die FB6660 dauerhaft gegen ein Arris getauscht (physisch weg). WAN terminiert auf **`crs326-core vlan100`** (VLAN100-Transfer), core zieht die öffentliche Liwest-IP `90.146.33.177` → kein Double-NAT. **core = Public-Edge + WG-Hub** (fm/dw live), NICHT mehr ap1. Telefonie nicht weitergeführt. Runbook `routeros/wan-cutover-runbook.md` (ap1-Teile historisch).
|
- **✅✅ Edge-Cutover (2026-07-01; Router-Umzug 2026-08-08): FritzBox ausgebaut, Arris im Bridge-Mode.** Liwest hat die FB6660 dauerhaft gegen ein Arris getauscht (physisch weg). WAN terminiert auf **`crs326-core vlan100`** (VLAN100-Transfer), core zieht die öffentliche Liwest-IP `90.146.33.177` → kein Double-NAT. **core = Public-Edge + WG-Hub** (fm/dw live), NICHT mehr ap1. Telefonie nicht weitergeführt. Runbook `routeros/wan-cutover-runbook.md` (ap1-Teile historisch).
|
||||||
- **hAP `device-mode=home` (ap1/ap2): scheduler + fetch blockiert** (`not allowed by device-mode`) → AP-Provisionierung idempotent **ohne** Scheduler. **`[/ping]` gibt nil in 7.23**. REST je AP `http://10.40.99.11|12/rest` (Creds = `ROUTER_AP{1,2}` in `~/.claude.json`). **Der L3-Router crs326-core ist KEIN device-mode=home** → dort gehen scheduler/fetch (z.B. DDNS-Updater).
|
- **hAP `device-mode=home` (ap1/ap2): scheduler + fetch blockiert** (`not allowed by device-mode`) → AP-Provisionierung idempotent **ohne** Scheduler. **`[/ping]` gibt nil in 7.23**. REST je AP `http://10.40.99.11|12/rest` (Creds = `ROUTER_AP{1,2}` in `~/.claude.json`). **Der L3-Router crs326-core ist KEIN device-mode=home** → dort gehen scheduler/fetch (z.B. DDNS-Updater).
|
||||||
- **Erstzugriff Werks-hAP am CRS-Fabric:** Uplink `ether1` = Werks-WAN → `192.168.88.1` (LAN) darüber NICHT erreichbar. Weg: Gerät auf **LAN-Port (ether2)** patchen ODER **Core-Temp-Pfad** `192.168.88.2/24` auf core-`bridge` + srcnat masq `192.168.88.0/24`, dann scp+`/import` (danach Temp-Pfad + stale ARP `.88.1` entfernen). Winbox-Neighbors zeigt die APs NICHT (MNDP pro-VLAN, Mgmt auf vlan99) — kein L2-Fehler.
|
- **Erstzugriff Werks-hAP am CRS-Fabric:** Uplink `ether1` = Werks-WAN → `192.168.88.1` (LAN) darüber NICHT erreichbar. Weg: Gerät auf **LAN-Port (ether2)** patchen ODER **Core-Temp-Pfad** `192.168.88.2/24` auf core-`bridge` + srcnat masq `192.168.88.0/24`, dann scp+`/import` (danach Temp-Pfad + stale ARP `.88.1` entfernen). Winbox-Neighbors zeigt die APs NICHT (MNDP pro-VLAN, Mgmt auf vlan99) — kein L2-Fehler.
|
||||||
|
|||||||
98
docs/routerboot-firmware-klickanleitung.md
Normal file
98
docs/routerboot-firmware-klickanleitung.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# RouterBOOT-Firmware auf 7.24 nachziehen — Klickanleitung (WinBox)
|
||||||
|
|
||||||
|
**Stand 2026-08-18, live erhoben.** RouterOS ist auf allen vier Geräten bereits 7.24.
|
||||||
|
Zurück hängt nur der **Bootloader** (RouterBOOT):
|
||||||
|
|
||||||
|
| Gerät | IP | Modell | aktuell | Ziel |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `crs326-core` | 10.40.99.1 | CRS326-24G-2S+ | **7.19.5** | 7.24 |
|
||||||
|
| `crs326-branch` | 10.40.99.2 | CRS326-24G-2S+ | **7.19.5** | 7.24 |
|
||||||
|
| `ap1` | 10.40.99.11 | hAP ax² | **7.23.2** | 7.24 |
|
||||||
|
| `ap2` | 10.40.99.12 | hAP ax² | **7.23.2** | 7.24 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Warum das per Hand geht und nicht über die Automatik
|
||||||
|
|
||||||
|
`/system routerboard upgrade` **fragt interaktiv nach** („Do you really want to upgrade
|
||||||
|
firmware?"). Damit fällt es durch beide Wege raus, die dieses Netz sonst nutzt:
|
||||||
|
|
||||||
|
- **MikroMCP** blockt den Befehl per Deny-Policy (er schreibt den Bootloader).
|
||||||
|
- **Nautobot Golden Config** schickt die Zeile per Netmiko ab, bekommt den Prompt statt einer
|
||||||
|
Antwort und quittiert mit `E3001` und **leerer** Fehlermeldung. Am 2026-08-17 genau so
|
||||||
|
passiert — es wurde nichts geschrieben, aber auch nichts gemeldet.
|
||||||
|
|
||||||
|
Auf `core` und `branch` ginge ein Umweg über den Scheduler (dort läuft kein
|
||||||
|
`device-mode=home`). Auf **ap1/ap2 nicht** — dort ist der Scheduler gesperrt. Für vier
|
||||||
|
Geräte ist der Klickweg schlicht der ehrlichere.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Die Klicks (identisch auf jedem Gerät)
|
||||||
|
|
||||||
|
1. **WinBox öffnen** → Reiter **Neighbors** → Gerät in der Liste doppelklicken
|
||||||
|
(oder unter *Connect To* die IP aus der Tabelle oben eintippen).
|
||||||
|
Login `admin`, Passwort aus `~/.secrets` (auf allen vier gleich).
|
||||||
|
2. Links im Menü **System** → **RouterBOARD**.
|
||||||
|
3. Im Fenster stehen zwei Zeilen:
|
||||||
|
- `Current Firmware: 7.19.5` (bzw. `7.23.2`)
|
||||||
|
- `Upgrade Firmware: 7.24`
|
||||||
|
➡️ **Stehen beide auf 7.24, ist das Gerät fertig — Fenster zu, nächstes Gerät.**
|
||||||
|
4. Oben auf den Knopf **Upgrade** klicken.
|
||||||
|
5. Rückfrage **„Do you really want to upgrade firmware?"** → **Yes**.
|
||||||
|
6. Es erscheint sinngemäß *„Firmware upgraded, reboot for changes to take effect"*.
|
||||||
|
**Die Firmware ist damit geschrieben, aber noch nicht aktiv.**
|
||||||
|
7. Links im Menü **System** → **Reboot** → **Yes**.
|
||||||
|
8. Warten (CRS326 ~40 s, hAP ~60 s), neu verbinden, **System → RouterBOARD** öffnen:
|
||||||
|
`Current Firmware` muss jetzt **7.24** sein.
|
||||||
|
|
||||||
|
> **Schritt 7 nicht vergessen.** Ohne Reboot bleibt `Current Firmware` auf dem alten Wert,
|
||||||
|
> und beim nächsten Blick sieht es aus, als hätte der Upgrade nicht funktioniert.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reihenfolge — und was dabei jeweils ausfällt
|
||||||
|
|
||||||
|
Von harmlos nach heikel. Jedes Gerät erst abschließen (inkl. Reboot und Gegenprobe),
|
||||||
|
bevor das nächste drankommt.
|
||||||
|
|
||||||
|
| # | Gerät | Was während des Reboots weg ist | Dauer |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | **ap1** | WLAN im UG. Clients wechseln auf ap2, Roaming fängt das ab. | ~60 s |
|
||||||
|
| 2 | **ap2** | WLAN im OG, dazu kurz die Shellys. Sie kommen von selbst zurück. | ~60 s |
|
||||||
|
| 3 | **crs326-core** | ⚠️ **Alles**: Routing, DHCP, DNS, Internet, WireGuard, CAPsMAN-Manager. | ~40 s |
|
||||||
|
| 4 | **crs326-branch** | ⚠️ **Deine LAN-Verbindung** (dein Arbeitsplatz hängt daran) + NAS/Drucker/macmini. | ~40 s |
|
||||||
|
|
||||||
|
**branch bewusst zuletzt:** dein Rechner hängt per Kabel daran. Wenn dabei etwas schiefgeht,
|
||||||
|
sind alle anderen Geräte schon nachweislich oben — und der Fehler ist damit eingegrenzt.
|
||||||
|
|
||||||
|
**Beim Core:** WLAN und LAN laufen weiter (die APs sind CAPs und behalten ihre Konfiguration,
|
||||||
|
die Switches schalten Layer 2 unabhängig), aber es gibt für die Dauer des Reboots **kein DHCP,
|
||||||
|
kein DNS und kein Internet**. Kein guter Moment für ein Telefonat.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gegenprobe hinterher (statt Klicken)
|
||||||
|
|
||||||
|
Alle vier auf einmal, ohne WinBox:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/dev/bf-network-r6 && for s in "core:10.40.99.1:CRS326_CORE_PASS" "branch:10.40.99.2:CRS326_BRANCH_PASS" "ap1:10.40.99.11:ROUTER_AP1_PASS" "ap2:10.40.99.12:ROUTER_AP2_PASS"; do n=${s%%:*}; r=${s#*:}; ip=${r%%:*}; v=${r##*:}; p=$(grep -E "^(export )?$v=" ~/.secrets/credentials.env | head -1 | sed -E "s/^(export )?$v=//" | tr -d "\"'"); curl -s -u "admin:$p" --max-time 8 "http://$ip/rest/system/routerboard" | python3 -c "import json,sys;d=json.load(sys.stdin);print(f' $n current={d.get(\"current-firmware\")} upgrade={d.get(\"upgrade-firmware\")}')"; done
|
||||||
|
```
|
||||||
|
|
||||||
|
**Soll:** bei allen vier `current=7.24 upgrade=7.24`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wenn etwas klemmt
|
||||||
|
|
||||||
|
- **Gerät kommt nach dem Reboot nicht zurück** → 2–3 Minuten geben (RouterBOOT prüft nach
|
||||||
|
einem Firmware-Wechsel beim ersten Start mehr als sonst). Danach: Strom aus/an.
|
||||||
|
- **`Current Firmware` bleibt alt** → Reboot wurde übersprungen, Schritt 7 nachholen.
|
||||||
|
- **Kein `Upgrade`-Knopf sichtbar** → das Gerät ist bereits aktuell.
|
||||||
|
- **Netz nach dem Core-Reboot still** → erst prüfen, ob es wirklich am Core liegt:
|
||||||
|
`ping 10.40.99.1`. Antwortet er, ist Layer 3 zurück und der Rest hängt an DHCP-Leases,
|
||||||
|
die sich von selbst erneuern.
|
||||||
|
|
||||||
|
⚠️ **Nicht während des Vorgangs** parallel Golden-Config-Deploys laufen lassen — ein Reboot
|
||||||
|
mitten im Netmiko-Push hinterlässt einen Teil-Zustand (bekannte TP22-Falle).
|
||||||
@@ -32,7 +32,13 @@ DEVICE = "crs326-core"
|
|||||||
SECRETS = pathlib.Path.home() / ".secrets" / "credentials.env"
|
SECRETS = pathlib.Path.home() / ".secrets" / "credentials.env"
|
||||||
|
|
||||||
# Felder, die RouterOS im Export NICHT schreibt (Laufzeit-/Interndaten).
|
# Felder, die RouterOS im Export NICHT schreibt (Laufzeit-/Interndaten).
|
||||||
SKIP = {".id", "dynamic", "invalid", "bytes", "packets", "creation-time"}
|
# `hw-offload` gehoert dazu (2026-08-18 aufgeschlagen): die REST-API meldet es
|
||||||
|
# auf der defconf-fasttrack-Regel als true, `/ip firewall filter export` laesst
|
||||||
|
# es weg -- am Geraet gegengeprueft. Ohne diesen Eintrag meldet die Compliance
|
||||||
|
# ewige Falsch-Drift auf genau dieser einen Regel. Gleiche Klasse wie die
|
||||||
|
# `disabled=false`- und Boolean-Faelle weiter unten.
|
||||||
|
SKIP = {".id", "dynamic", "invalid", "bytes", "packets", "creation-time",
|
||||||
|
"hw-offload"}
|
||||||
|
|
||||||
|
|
||||||
def secret(key):
|
def secret(key):
|
||||||
|
|||||||
@@ -20,12 +20,16 @@
|
|||||||
# winbox war auf ALLEN vier unbeschraenkt.
|
# winbox war auf ALLEN vier unbeschraenkt.
|
||||||
# ⚠️ Lockout-Regel: 10.40.0.0/16 (LAN) UND 100.96.0.0/12 (Mesh) muessen beide drin sein —
|
# ⚠️ Lockout-Regel: 10.40.0.0/16 (LAN) UND 100.96.0.0/12 (Mesh) muessen beide drin sein —
|
||||||
# das sind die zwei Wege, ueber die dieses Netz administriert wird. Nie einen davon kappen.
|
# das sind die zwei Wege, ueber die dieses Netz administriert wird. Nie einen davon kappen.
|
||||||
|
# ⚠️ Attribut heisst `available-from`, NICHT `address` (korrigiert 2026-08-18): RouterOS
|
||||||
|
# 7.23/7.24 exportiert `available-from=`, das Template schrieb `address=`. Ergebnis waren
|
||||||
|
# vier Dauer-Drifts (ap1/ap2/branch/core), bei denen das GERAET recht hatte und das Soll
|
||||||
|
# falsch war. Beim Push haette `address=` auf 7.24 zudem auflaufen koennen.
|
||||||
/ip service set ftp disabled=yes
|
/ip service set ftp disabled=yes
|
||||||
/ip service set ssh address=10.40.0.0/16,100.96.0.0/12
|
/ip service set ssh available-from=10.40.0.0/16,100.96.0.0/12
|
||||||
/ip service set telnet disabled=yes
|
/ip service set telnet disabled=yes
|
||||||
/ip service set www address=10.40.0.0/16,100.96.0.0/12
|
/ip service set www available-from=10.40.0.0/16,100.96.0.0/12
|
||||||
/ip service set winbox address=10.40.0.0/16,100.96.0.0/12
|
/ip service set winbox available-from=10.40.0.0/16,100.96.0.0/12
|
||||||
/ip service set api address=10.40.0.0/16,100.96.0.0/12
|
/ip service set api available-from=10.40.0.0/16,100.96.0.0/12
|
||||||
/ip service set api-ssl disabled=yes
|
/ip service set api-ssl disabled=yes
|
||||||
|
|
||||||
{% if obj.name == "crs326-core" %}
|
{% if obj.name == "crs326-core" %}
|
||||||
@@ -124,9 +128,19 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
/ip dhcp-server option add code=6 name="dns 1.1.1.1" value=0x01010101
|
/ip dhcp-server option add code=6 name="dns 1.1.1.1" value=0x01010101
|
||||||
|
|
||||||
# [6] DNS — Upstream aktuell PLAIN 1.1.1.1. DoH-Cloudflare-Gateway ist offener TODO
|
# [6] DNS — DoH zum Cloudflare-Gateway, MIT Zertifikatspruefung (TP23 Stufe 1,
|
||||||
# (core hat kein CA-Bundle -> verify-doh-cert nicht moeglich), s. TP21.1.
|
# scharf seit 2026-08-18; schliesst TP21.1 TODO 1).
|
||||||
/ip dns set allow-remote-requests=yes mdns-repeat-ifaces=vlan10,vlan20,vlan40,vlan30,vlan90 servers=1.1.1.1
|
# `servers=1.1.1.1` BLEIBT als Bootstrap stehen: RouterOS loest den
|
||||||
|
# DoH-Hostnamen selbst darueber auf, sonst Henne-Ei. Alles andere geht
|
||||||
|
# ueber DoH.
|
||||||
|
# Die frueher hier notierte Begruendung "core hat kein CA-Bundle" war zu
|
||||||
|
# pessimistisch: es braucht kein Bundle, sondern genau EINEN Root. Die Kette
|
||||||
|
# ist Leaf -> GTS WE1 -> GTS Root R4, importiert ist nur R4 (~1 KB, gueltig
|
||||||
|
# bis 2036) — entscheidend bei 2,8 MB freiem Flash.
|
||||||
|
# Der Import selbst steht bewusst NICHT im Template: er braucht die Datei
|
||||||
|
# auf dem Geraet und ist ein einmaliger Bootstrap, kein Sollzustand.
|
||||||
|
# Artefakt: routeros/tp23-stufe1-doh-core.rsc
|
||||||
|
/ip dns set allow-remote-requests=yes mdns-repeat-ifaces=vlan10,vlan20,vlan40,vlan30,vlan90 servers=1.1.1.1 use-doh-server=https://px35ynlol3.cloudflare-gateway.com/dns-query verify-doh-cert=yes
|
||||||
|
|
||||||
# Kanonischer Mgmt-Nummernplan (User-Bestaetigung 2026-08-13, verbindlich):
|
# Kanonischer Mgmt-Nummernplan (User-Bestaetigung 2026-08-13, verbindlich):
|
||||||
# core .99.1 | branch .99.2 | ap1 .99.11 | ap2 .99.12
|
# core .99.1 | branch .99.2 | ap1 .99.11 | ap2 .99.12
|
||||||
|
|||||||
5
routeros/tp19-ntp-branch-client.rsc
Normal file
5
routeros/tp19-ntp-branch-client.rsc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# NTP-Client auf crs326-branch nachziehen. Er hatte GAR KEINEN Server
|
||||||
|
# eingetragen (status=stopped) — die Uhr stimmte nur zufaellig noch.
|
||||||
|
# Zeitquelle ist der Core (s. routeros/tp19-ntp-core-als-zeitquelle.rsc).
|
||||||
|
:do { /system ntp client set enabled=yes servers=10.40.99.1 } on-error={ :log info "tp19ntp: branch warf" }
|
||||||
|
:log info ("tp19ntp: branch status=" . [/system ntp client get status])
|
||||||
34
routeros/tp19-ntp-core-als-zeitquelle.rsc
Normal file
34
routeros/tp19-ntp-core-als-zeitquelle.rsc
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# NTP: den Core zur Zeitquelle des Standorts machen.
|
||||||
|
#
|
||||||
|
# BEFUND (2026-08-18, beim TP19-Abschluss gefunden):
|
||||||
|
# ap1 ntp client -> 10.40.99.1, status=waiting, Uhr zufaellig noch richtig
|
||||||
|
# ap2 ntp client -> 10.40.99.1, status=waiting, Uhr **17 Stunden nach**
|
||||||
|
# branch ntp client -> gar keiner, status=stopped
|
||||||
|
# core /system ntp server = enabled:no
|
||||||
|
# Alle drei fragen also einen Zeitserver, den es nicht gibt ("waiting" heisst
|
||||||
|
# genau das). ap2 ist nur der erste, der sichtbar weggelaufen ist — die anderen
|
||||||
|
# folgen.
|
||||||
|
#
|
||||||
|
# WARUM DAS MEHR ALS KOSMETIK IST: Geraete-Logs sind das Hauptwerkzeug in diesem
|
||||||
|
# Projekt (TP5 lebt vom Kollektor). Beim Pfadbeweis heute nacht hat ap2 einen
|
||||||
|
# Logeintrag von 04:57 als "2026-08-17 12:19" gestempelt — eine Korrelation
|
||||||
|
# ueber mehrere Geraete ist damit wertlos.
|
||||||
|
#
|
||||||
|
# WEG: der Core hat als einziger eine verlaessliche Zeit (WAN + DoH). Er wird
|
||||||
|
# Server, die drei anderen bleiben/werden Clients auf 10.40.99.1. Kein Geraet
|
||||||
|
# braucht dafuer Internet.
|
||||||
|
#
|
||||||
|
# ⚠️ Die input-Regel ist Pflicht: seit Etappe 4 endet `input` mit einem Drop.
|
||||||
|
# Ohne sie waere der NTP-Server eingeschaltet und trotzdem unerreichbar —
|
||||||
|
# derselbe stille Fehlschlag wie bisher, nur eine Ebene tiefer.
|
||||||
|
#
|
||||||
|
# Push: python3 nautobot/gc-manual-plan.py --device crs326-core \
|
||||||
|
# --commands-file routeros/tp19-ntp-core-als-zeitquelle.rsc \
|
||||||
|
# --change-id TP19-NTP --deploy \
|
||||||
|
# --assert '/system/ntp/server|enabled=true'
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
:do { /system ntp server set enabled=yes } on-error={ :log info "tp19ntp: 01 server warf" }
|
||||||
|
:do { :if ([:len [/ip firewall filter find comment="TP5-E4: ntp"]] = 0) do={ /ip firewall filter add chain=input action=accept in-interface-list=LAN protocol=udp dst-port=123 comment="TP5-E4: ntp" place-before=[/ip firewall filter find comment="TP5: input log-only"] } } on-error={ :log info "tp19ntp: 02 fw warf" }
|
||||||
|
|
||||||
|
:log info ("tp19ntp: ENDE server-enabled=" . [:tostr [/system ntp server get enabled]] . " fw-regel=" . [:tostr [:len [/ip firewall filter find comment="TP5-E4: ntp"]]])
|
||||||
14
routeros/tp5-etappe3-autorevert-abbestellen.rsc
Normal file
14
routeros/tp5-etappe3-autorevert-abbestellen.rsc
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# TP5 Etappe 3 — Auto-Revert abbestellen.
|
||||||
|
#
|
||||||
|
# Der Scheduler aus tp5-etappe3-drop.rsc haette den Drop nach 10 Minuten selbst
|
||||||
|
# wieder abgeschaltet. Die Abnahme ist durch, also wird er entfernt und der
|
||||||
|
# Drop bleibt stehen. Abnahme am 2026-08-18 (Drop live):
|
||||||
|
# INFRA->IOT Shelly .30.211:80 = 200
|
||||||
|
# INFRA->WAN cloudflare.com = 301
|
||||||
|
# INFRA->MAIN MacBook = erreichbar
|
||||||
|
# INFRA->MGMT branch:22 von pve = ZU (korrekt: pve ist keine Mgmt-Quelle)
|
||||||
|
# GC-Deploy nautobot-worker -> ap2:22 = SUCCESS (der Pfadbeweis)
|
||||||
|
# Gedroppt wurden in der Testphase 11 Pakete — ausschliesslich die eigene
|
||||||
|
# pve->branch:22-Sonde.
|
||||||
|
:do { /system scheduler remove [find name="tp5autorevert"] } on-error={ :log info "tp5e3: abbestellen warf" }
|
||||||
|
:log info ("tp5e3: AUTO-REVERT entfernt, drop-disabled=" . [:tostr [/ip firewall filter get [find comment="TP5: deny-by-default"] disabled]])
|
||||||
13
routeros/tp5-etappe4-autorevert-abbestellen.rsc
Normal file
13
routeros/tp5-etappe4-autorevert-abbestellen.rsc
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# TP5 Etappe 4 — Auto-Revert abbestellen. Abnahme 2026-08-18 (input-Drop live):
|
||||||
|
# DNS aus VLAN20 an den Core core.bf.lan -> 10.40.99.1, heise.de -> 193.99.144.80
|
||||||
|
# AGH unveraendert nas.bf.lan -> 10.40.20.10
|
||||||
|
# MAIN->core admin 57 Pakete (MikroMCP/SSH laufen weiter)
|
||||||
|
# HA->core api 3 Pakete
|
||||||
|
# Die 5 mDNS-input-Regeln erstmals scharf: vlan30=87, vlan20=13 Pakete
|
||||||
|
# (standen seit dem Bau am 2026-08-14 auf 0)
|
||||||
|
# CAPsMAN ap1 + ap2 state=Ok
|
||||||
|
# Gedroppt wurde ausschliesslich Broadcast-Rauschen, fuer das der Core nie
|
||||||
|
# zustaendig war: MNDP (inzwischen explizit erlaubt), NetBIOS 137/138 aus
|
||||||
|
# VLAN20, SSDP-Announcements einer Sonos aus VLAN40.
|
||||||
|
:do { /system scheduler remove [find name="tp5e4autorevert"] } on-error={ :log info "tp5e4: abbestellen warf" }
|
||||||
|
:log info ("tp5e4: AUTO-REVERT entfernt, input-drop-disabled=" . [:tostr [/ip firewall filter get [find comment="TP5: input deny-by-default"] disabled]] . " seal-lan-disabled=" . [:tostr [/ip firewall filter get [find comment="TP10-seal-lan"] disabled]])
|
||||||
32
routeros/tp5-etappe4-nachtrag-discovery.rsc
Normal file
32
routeros/tp5-etappe4-nachtrag-discovery.rsc
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# TP5 Etappe 4 — NACHTRAG: Discovery-Protokolle in den input lassen.
|
||||||
|
#
|
||||||
|
# BEFUND (2026-08-18, unmittelbar nach dem input-Drop):
|
||||||
|
# Die input-Log-Regel fing MNDP-Broadcasts (udp/5678) von crs326-branch
|
||||||
|
# (04:F4:1C:B4:15:58), ap1 (D0:EA:11:4D:40:E0/E1) und ap2 (D0:EA:11:4D:40:39/3A).
|
||||||
|
#
|
||||||
|
# WARUM DAS NICHT HARMLOS IST:
|
||||||
|
# `/interface/wifi/cap` auf ap1 zeigt
|
||||||
|
# discovery-interfaces: vlan99
|
||||||
|
# current-caps-man-address: 04:F4:1C:B4:17:76%vlan99
|
||||||
|
# — eine MAC, keine IP. Die CAPs finden ihren Manager also per Layer-2-Discovery
|
||||||
|
# auf vlan99, nicht ueber eine konfigurierte Adresse. Ein Drop dieser Pakete
|
||||||
|
# bricht die Manager-Findung. Die BESTEHENDEN CAPWAP-Sitzungen laufen weiter
|
||||||
|
# (sie sind established und werden von TP10-seal-est akzeptiert), das Problem
|
||||||
|
# schlaegt also erst beim naechsten AP- oder Manager-Neustart zu — genau die
|
||||||
|
# Sorte Spaetschaden, die man im Log sehen und sofort schliessen will.
|
||||||
|
#
|
||||||
|
# Sicherheitlich billig: MNDP ist link-lokal (Broadcast, verlaesst das Segment
|
||||||
|
# nicht), CAPWAP wird auf vlan99 begrenzt.
|
||||||
|
#
|
||||||
|
# ⚠️ place-before ist Pflicht: ein blankes `add` haengt hinter den Drop und
|
||||||
|
# waere wirkungslos.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# MNDP. Aus der LAN-Liste, weil es auch die Winbox-Neighbors-Anzeige speist und
|
||||||
|
# als Broadcast ohnehin nicht routbar ist.
|
||||||
|
:do { :if ([:len [/ip firewall filter find comment="TP5-E4: MNDP discovery"]] = 0) do={ /ip firewall filter add chain=input action=accept in-interface-list=LAN protocol=udp dst-port=5678 comment="TP5-E4: MNDP discovery" place-before=[/ip firewall filter find comment="TP5: input log-only"] } } on-error={ :log info "tp5e4n: 01 mndp warf" }
|
||||||
|
|
||||||
|
# CAPsMAN/CAPWAP, eng auf das Mgmt-VLAN begrenzt.
|
||||||
|
:do { :if ([:len [/ip firewall filter find comment="TP5-E4: CAPsMAN capwap"]] = 0) do={ /ip firewall filter add chain=input action=accept in-interface=vlan99 protocol=udp dst-port=5246,5247 comment="TP5-E4: CAPsMAN capwap" place-before=[/ip firewall filter find comment="TP5: input log-only"] } } on-error={ :log info "tp5e4n: 02 capwap warf" }
|
||||||
|
|
||||||
|
:log info ("tp5e4n: ENDE mndp=" . [:tostr [:len [/ip firewall filter find comment="TP5-E4: MNDP discovery"]]] . " capwap=" . [:tostr [:len [/ip firewall filter find comment="TP5-E4: CAPsMAN capwap"]]])
|
||||||
Reference in New Issue
Block a user