TP5 Etappe 1: Log-Lauf live auf crs326-core
Log-only-Regel am Ende der forward-Kette (blockiert nichts) plus Syslog- Kollektor, ausgerollt ueber Nautobot GC als manual Config Plans. - routeros/tp5-etappe1-log-lauf.rsc: der ausgerollte Endzustand + die am Geraet belegten Lehren aus dem Rollout - nautobot/gc-manual-plan.py: Push-Werkzeug (assertet plan.device, liest Plan-Status statt Job-Status, strippt Kommentarzeilen) Zwei Korrekturen an bisherigen Annahmen: - Ein gescheiterter Netmiko-Deploy hinterlaesst einen TEIL-Zustand. Die TP22-Notiz "sauberer Fehlschlag" galt dem NAPALM-Weg. - Bindestriche in name= werden von RouterOS abgelehnt, Quoten hilft nicht. Die zuerst notierte target=/remote=-Erklaerung war falsch und ist raus. Die Log-Regel steht auf out-interface-list="!WAN": bare fing sie auch allen Internet-Verkehr. LAN->WAN ist eine garantierte Whitelist-Zeile, also Rauschen - und ein Merkposten fuer Etappe 3, wo der Drop aus demselben Grund nicht bare stehen darf. D2 entschieden: iPhone .30.201 wird ins MAIN-SSID umgehaengt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -89,7 +89,7 @@ Beispiel: `INFRA→MEDIA` hat 178.142 Pakete auf dem Zähler, stand aber im Snap
|
||||
| # | Frage | Vorschlag |
|
||||
|---|---|---|
|
||||
| **D1** | MAIN→INFRA: welche Dienste? | Beobachtet: NAS `6690`, pve-mcp `3000`, macmini `49152`, `3722`. Vorschlag: **erst mit dem Log-Lauf (Etappe 1) vervollständigen**, dann Whitelist — nicht jetzt raten. |
|
||||
| **D2** | iPhone `.30.201` in IOT | Ins MAIN-SSID holen (sauber) **oder** bewusst als Ausnahme dulden. Empfehlung: umhängen. |
|
||||
| **D2** | ~~iPhone `.30.201` in IOT~~ | ✅ **ENTSCHIEDEN (2026-08-14): ins MAIN-SSID umhängen.** Hands-on bei Christoph (SSID wechseln + `dirtyvader-iot` vergessen lassen). Beleg, dass es dasselbe Telefon ist: die statische Reservierung `10.40.10.196` „iPhone" trägt eine *andere* private MAC — iOS vergibt **pro SSID** eine eigene Private Address. Genau darum wäre eine Whitelist auf `.30.201` instabil. |
|
||||
| **D3** | ~~ICMP-Sweep `.10.82`→IOT~~ | ✅ **ENTSCHIEDEN (2026-08-14): `lanscan.app`, Ad-hoc vom Arbeitsplatz.** Keine Dauerregel — läuft über die **JIT-Admin-Gruppe** (selbstverfallend). Deckt sich mit D4. |
|
||||
| **D4** | Wer darf auf VLAN99-Mgmt? | Vorschlag: nur MAIN (`vlan10`), Rest drop. `seal-lan` entsprechend verengen. |
|
||||
| **D5** | IOT→INFRA-Whitelist | Doku nennt MQTT 1883/8883, HA-API, Influx 8086. Beobachtet real: **`8123` (HA), `5540/udp` (Matter)**. Vorschlag: die beobachteten + MQTT. |
|
||||
@@ -104,19 +104,69 @@ Beispiel: `INFRA→MEDIA` hat 178.142 Pakete auf dem Zähler, stand aber im Snap
|
||||
> Vor **jedem** Push `/system backup` auf dem Core (Regel 3). Und: **nur die Gegenprüfung am Gerät zählt**,
|
||||
> Job- und Plan-Status sind kein Wirksamkeitsnachweis (zweimal belegt, TP21.1/TP22).
|
||||
|
||||
### Etappe 1 — Log-Lauf (blockiert nichts, Dauer: einige Tage)
|
||||
#### Push-Werkzeug + Fallen (aus dem Etappe-1-Rollout, 2026-08-14 am Gerät belegt)
|
||||
|
||||
Eine einzige Regel **ans Ende von `forward`**, `action=log` statt `drop`:
|
||||
Werkzeug: `nautobot/gc-manual-plan.py --device <name> --commands-file <datei> --change-id <id> [--dry-run|--deploy]`.
|
||||
Es legt den manual Plan an, prüft `plan.device` gegen den Namen, gibt frei, deployt und liest
|
||||
**den Plan-Status** zurück (nicht den Job-Status). Kommentar-/Leerzeilen werden abgestreift.
|
||||
|
||||
1. 🔴 **Bindestriche in `name=` werden abgelehnt.** `add name="tp5-remote"` und `add name="tp5-abc"`
|
||||
werfen, `add name="tp5syslog"` geht — **Quoten hilft nicht.** Das hat vier Deploys gekostet, weil die
|
||||
naheliegende Erklärung („`remote=` darf nicht ins selbe `add` wie `target=remote`") *falsch* war:
|
||||
`set remote=… remote-port=…` in einem Statement läuft anstandslos. Bei neuen benannten Objekten
|
||||
also **Namen ohne Bindestrich** wählen, oder das Gegenteil erst beweisen.
|
||||
2. 🔴 **Ein gescheiterter Netmiko-Deploy hinterlässt einen TEIL-Zustand.** Die TP22-Notiz
|
||||
„gescheiterter Deploy = sauberer Fehlschlag" galt dem **NAPALM**-Weg, der scheiterte, *bevor* er das
|
||||
Gerät anfasste. Netmiko schickt Zeile für Zeile und lässt Abgesetztes stehen: der erste Push hier
|
||||
hinterließ Zeile 3+4 ohne 1+2. **Nach jedem Fehlschlag den Ist-Stand am Gerät prüfen.**
|
||||
3. **Keine `print`-Zeilen in einen Config Plan.** Ein `/system identity print` als Kanarienzeile hat die
|
||||
unmittelbar folgende Zeile verschluckt und eine Fehldiagnose erzeugt.
|
||||
4. **Selbstprotokollierende Pläne sind die Diagnosemethode.** Der Deploy-Job liefert nur
|
||||
`E1028: found bad/failed/failure in output` und zeigt den Geräte-Output **nicht**. Jedes Kommando in
|
||||
`:do {…} on-error={ :log info "…" }` wickeln und danach eine Zählzeile
|
||||
`:log info ("… count=" . [:tostr [:len [… find …]]])` setzen — anschließend per `get_log` zeilengenau
|
||||
auslesen. Damit ist Root-Cause-Analyse **ohne Direkt-Write** möglich.
|
||||
|
||||
### Etappe 1 — Log-Lauf (blockiert nichts, Dauer: einige Tage) ▸ ✅ **AUSGEROLLT 2026-08-14, läuft**
|
||||
|
||||
Ausgerollt über Nautobot GC (manual Config Plans, `nautobot/gc-manual-plan.py`), Quelle
|
||||
`routeros/tp5-etappe1-log-lauf.rsc`. Auf dem Gerät:
|
||||
|
||||
```
|
||||
/ip firewall filter add chain=forward action=log log-prefix="TP5-WOULD-DROP" comment="TP5: log-only, Vorstufe zum deny-by-default"
|
||||
/ip firewall filter add chain=forward action=log log-prefix="TP5-WOULD-DROP" \
|
||||
comment="TP5: log-only, Vorstufe zum deny-by-default" out-interface-list="!WAN"
|
||||
```
|
||||
|
||||
Das protokolliert exakt die Pakete, die der spätere Drop treffen würde — inklusive der Dinge, an die
|
||||
niemand denkt (Drucker-Discovery, Backup-Jobs, ein Gerät, das nur einmal pro Woche funkt). **Diese Liste
|
||||
ist die Whitelist**, nicht eine am Schreibtisch ausgedachte. Danach D1/D3/D5 final beantworten.
|
||||
ist die Whitelist**, nicht eine am Schreibtisch ausgedachte. Danach D1/D5 final beantworten.
|
||||
|
||||
⚠️ Log-Ziel vorher setzen (`/system logging`), sonst läuft nur der Speicher-Ringpuffer mit.
|
||||
**Log-Ziel steht:** syslog-ng-Container `tp5-syslog` auf dem Docker-LXC, **`10.40.20.18:514`**,
|
||||
Dateien unter `/opt/tp5-syslog/log/` (`tp5-would-drop.log` gefiltert + Host-Dateien).
|
||||
Auf dem Core: Action `tp5syslog` + `logging add topics=firewall action=tp5syslog`.
|
||||
Disk-Logging auf dem Core scheidet aus (**nur ~3 MB freier Flash**), der Memory-Ring (1000 Zeilen)
|
||||
wickelt sich in Minuten um. `firewall` ist aus dem Memory-Ring genommen (`topics=info,!firewall`),
|
||||
damit der On-Box-Log während des mehrtägigen Laufs für andere Fehlersuche brauchbar bleibt —
|
||||
**am Ende von Etappe 1 auf `topics=info` zurückbauen.**
|
||||
⚠️ Der LXC hat nur ~2,5 GB frei; `/usr/local/bin/tp5-log-guard.sh` (Cron, alle 10 min) kappt bei 500 MB
|
||||
je Datei per Truncate-in-place. Ein vollgelaufenes Dateisystem risse dort auch adguard/cloudflared mit.
|
||||
|
||||
#### 🔴 `out-interface-list="!WAN"` — warum die Regel nicht bare steht
|
||||
|
||||
Bare gefasst fing sie **auch den gesamten Internet-Verkehr** (`out:vlan100`): in einer ruhigen Minute
|
||||
242 Zeilen/min, davon ¼ WAN-bound, unter Last deutlich mehr. LAN→WAN ist aber eine **garantierte**
|
||||
Whitelist-Zeile — ohne sie hat kein VLAN Internet, auch die „Internet-only"-VLANs 50/90 nicht.
|
||||
Es wäre also Rauschen genau in der Matrix, die Etappe 2 ableiten soll.
|
||||
|
||||
**Merkposten für Etappe 3:** der Drop darf aus demselben Grund **nicht** bare ans Kettenende —
|
||||
`accept out-interface-list=WAN` gehört davor, sonst ist das ganze Haus offline. Diese Zeile ist
|
||||
bekannt und braucht keinen Beleg aus dem Log.
|
||||
|
||||
#### Auswertung
|
||||
|
||||
```bash
|
||||
ssh root@10.40.20.100 'pct exec 400 -- grep -o "in:vlan[0-9]* out:[a-z0-9]*" /opt/tp5-syslog/log/tp5-would-drop.log | sort | uniq -c | sort -rn'
|
||||
```
|
||||
|
||||
### Etappe 2 — Whitelists bauen (noch immer ohne Drop)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user