Commit Graph

142 Commits

Author SHA1 Message Date
da452ce1f3 TP23 Stufe 1 (DoH) + TP5 Etappe-2-Nachtrag ausgerollt, Etappe-3-Drop vorbereitet
Drei Skripte aus der Folgesession. Stand am Geraet zum Commit-Zeitpunkt
(per REST gegengeprueft, nicht aus den Dateikoepfen abgeschrieben):

- tp23-stufe1-doh-core.rsc  -> LIVE. use-doh-server auf den
  Cloudflare-Gateway-Resolver, verify-doh-cert=true. Nur der GTS Root R4
  importiert statt eines Bundles: der Core hat ~2,8 MB freien Flash, und die
  Kette endet nachweislich dort. Der Root wurde per SFTP hochgeladen, nicht
  per fetch geholt -- fetch haette check-certificate=no gebraucht und damit
  genau die Pruefung ausgehebelt, die hier aufgebaut wird.
  Schliesst zugleich TP21.1 TODO 1.

- tp5-etappe2-nachtrag.rsc  -> LIVE. 17 TP5-E2-Whitelists (11 + 6).
  Vier Luecken, die der Kollektor ueber dreieinhalb Stunden gezeigt hat:
  Matter (udp/5540, 92 der 119 Zeilen -- die E2-Regel war protocol=tcp und
  liess Matter komplett durchfallen), der Nautobot-Deploy-Pfad (kommt von
  .20.31 = worker, nicht von .20.30 = web; jetzt als address-list, weil der
  scheduler dieselben Jobs faehrt), und zwei Rueckwege aus abgelaufenen
  Conntrack-Eintraegen. Dazu eine Vorratsregel fuer AdGuard, damit das
  spaetere DNS-Umstellen ein reiner DHCP-Change bleibt.

  Korrigiert meine Aussage vom Vortag: "die Log-Regel ist verstummt" beruhte
  auf einem 70-Sekunden-Fenster und war so nicht haltbar. Genau deshalb
  verlangt das Runbook ein mehrtaegiges Fenster.

- tp5-etappe3-drop.rsc  -> VORBEREITET, NICHT AUSGEROLLT. Kein Drop und kein
  Scheduler auf dem Geraet. Der Auto-Revert steht im Skript bewusst VOR dem
  Drop, sonst gibt es ein Fenster ohne Sicherung; der Drop kommt HINTER die
  Log-Regel, damit der Kollektor weiter sieht, was gefressen wird.

Gate fuer Etappe 3: die Log-Regel steht aktuell auf 0 Paketen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 04:52:40 +02:00
5fd8d4edb1 TP28 dokumentiert: CAPsMAN-Cutover durch, zwei Messfallen festgehalten
Der Cutover ist durch (34 Clients, iot=27, beide CAPs Ok, Roaming belegt).
Festgehalten sind vor allem die zwei Fallen, die mich Zeit und Christoph das
halbe IoT-Netz gekostet haben:

1. Unter CAPsMAN fuehrt der MANAGER die registration-table und die
   wireless-Logs, nicht der CAP. Auf ap1/ap2 sind beide leer, obwohl das WLAN
   laeuft — ich habe daraus zweimal faelschlich 'WLAN ist unten' geschlossen.

2. Drei uebereinstimmende .rsc-Dateien sind nicht drei Belege, wenn sie aus
   demselben Bring-up stammen. Genau daran habe ich wlan-psks.env fuer
   veraltet gehalten und ueberschrieben. Die Passphrasen sind am Geraet per
   REST lesbar — das ist der Weg, nicht der Dateivergleich.

Offen: das GC-Modell beschreibt weiter Standalone-APs; die 76/76 ist stale
(13:55 gemessen, Cutover 18:05). wifi-*-Features muessen auf den Core.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:41:57 +02:00
8945f9ef53 TP28: WLAN laeuft ueber CAPsMAN auf crs326-core — beide APs sind reine CAPs
Der Methodenwechsel ist vollzogen. Beide hAP ax2 sind CAPs, die gesamte
WLAN-Konfiguration liegt auf dem Core: 4 Kanaele, 6 Datapaths, 6 Security,
2 Steering, 9 Configurations, 4 Provisioning-Regeln je radio-mac.

Warum es diesmal traegt, obwohl CAPsMAN 2026-07-22 abgeschafft wurde: damals
war ap1 Manager UND AP, und ein Manager kann seine eigenen Radios nicht per
CAPsMAN provisionieren — genau diese Asymmetrie war die Ursache von TP3.1.
Mit dem Core als Manager sind beide APs symmetrisch. Der Core braucht dafuer
kein wifi-qcom: das capsman-Menue steckt im Basis-routeros, die 3,35 MB
freier Flash sind irrelevant.

Verifiziert am Geraet: beide remote-caps "Ok", alle 7 dynamischen VAPs je AP
mit korrekter SSID und VLAN, Kanaele exakt wie in TP25 gemessen (ap1
5180/ax/Ce/I + 2412/ax, ap2 5220/ax/Ce/I + 2462/ax), Bridge-Ports mit
richtigen PVIDs. "traffic processing on CAP" bestaetigt Local-Forwarding —
im neuen /interface/wifi gibt es ohnehin kein zentrales Forwarding mehr,
die datapath-Property existiert deshalb nicht.

ft-over-ds=yes ist jetzt aktiv (unter CAPsMAN erstmals verfuegbar), und
dirtyvader-guest hat eigenes Steering mit neighbor-group=bf-guest — nicht
bf-main mitbenutzt, sonst meldet 802.11k Gast-Clients BSSIDs einer SSID,
auf die sie nicht assoziieren koennen.

🔴 routeros/.secrets/wlan-psks.env war fuer infra/iot/untrusted VERALTET.
Die laufenden PSKs standen in ap1-prov-base.rsc. Mit den Datei-Werten
konnten die Shellys sich nicht mehr anmelden. Datei auf den laufenden Stand
korrigiert, PSKs auf dem Manager nachgezogen. Wer die Datei blind als
Wahrheit nimmt, sperrt das halbe IoT-Netz aus.

🔴 Eigener Messfehler, festhalten: /interface/wifi/registration-table auf dem
CAP zeigt unter CAPsMAN NICHTS. Die Registrierungen fuehrt der MANAGER.
Ich habe daraus faelschlich "WLAN ist unten" geschlossen, waehrend Christophs
Geraete mit vollem Ausschlag verbunden waren. Ab jetzt nur noch am Manager
zaehlen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:25:25 +02:00
2103774d1a TP26: /ip firewall filter ist drift-ueberwacht — 76/76, TP5 Etappe 3 entblockt
Bis heute gab es nur ip-firewall-nat. "72/72 compliant" sagte ueber die
Firewall gar nichts — und TP5 Etappe 3 wollte dort einen Deny-by-default
setzen, der dann als einzige Regel im Netz unbeobachtet gewesen waere.

Umsetzung datengetrieben statt als Templatezeilen: die 36 Regeln liegen in
local_config_context_data.firewall_filter, das Template rendert sie nur.
36 Regeln fest ins Jinja zu schreiben hiesse, dass jede TP5-Etappe einen
Template-Edit braucht — genau die Reibung, wegen der die Governance in
Verruf geraten ist. Neue Regel = ein Listeneintrag.

ingest-core-firewall.py ist ein RE-BASELINE-Werkzeug, kein Sync: es erklaert
den Ist-Stand zum Soll und macht blind ausgefuehrt die Drift-Erkennung
wertlos. Darum nur nach einer bewusst verifizierten Aenderung laufen lassen.

Drei Formatfallen beim Nachbau des /export-Formats, alle durch Vergleich mit
dem echten Geraete-Export bzw. durch die neue Rule selbst gefunden:
- REST liefert Booleans als STRINGS. `if rule.get("dynamic")` ist fuer
  "false" wahr und filterte erst alle 36 Regeln weg (0 statt 36).
- REST sagt hw-offload=true, /export schreibt yes. Und "!" bzw. Kommas
  werden NICHT gequotet (connection-nat-state=!dstnat, dst-port=8123,1883).
  Quoting nur bei Leerzeichen.
- /export laesst Default-Werte weg: `disabled=no` steht nie drin,
  `disabled=yes` dagegen schon. Das schlug beim ersten Lauf der neuen Rule
  als 75/76 auf — die Rule hat ihren Zweck damit sofort erfuellt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 15:55:57 +02:00
b1ddd3574d TP26: defconf-Firewall auf beiden APs abgeraeumt — --assert hat zwei Fehlschlaege gefangen
11 statische Werksregeln je AP entfernt (input-seal, fasttrack, ipsec, sogar
"accept to local loopback (for CAPsMAN)"). Ein reiner AP routet nicht; die
Regeln waren inert. Mgmt haengt an /ip service (TP16.1), nicht an der
input-Kette — kein Lockout-Risiko. ap2 danach: 2 Radios running, 7 Clients.

Der eigentliche Wert dieser Session steckt in den zwei Fehlschlaegen davor,
die --assert bei seinem ERSTEN echten Einsatz gefangen hat. Beide meldeten
"Plan-Status: Completed":

1. `remove [find]` erfasst die DYNAMISCHE Fasttrack-Dummy-Regel mit. RouterOS
   verweigert deren Entfernung, das ganze Kommando wirft, es wird NICHTS
   entfernt. Log: "tp26: remove warf".

2. Der naheliegende Fix `[find !dynamic]` ist ein SYNTAXFEHLER — korrekt ist
   `[find where !dynamic]`. Und Syntaxfehler schlagen beim Parsen zu:
   `:do {} on-error={}` faengt sie NICHT, der Handler laeuft nie. Symptom
   deshalb besonders tueckisch — kein Fehler im Log, keine Wirkung,
   Plan "Completed". Merkregel: on-error schuetzt vor Laufzeitfehlern,
   nicht vor Tippfehlern.

Ohne --assert waeren beide unbemerkt geblieben. Genau der Fehlermodus, den
Christoph mit "einstellungen werden nicht uebernommen, dir faellt das nicht
mal auf" benannt hat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 15:48:23 +02:00
2f102b48de gc-manual-plan: --assert prueft die Wirkung am Geraet, nicht den Plan-Status
"Plan-Status: Completed" sagt nur, dass die Zeilen abgesetzt wurden. Am
2026-08-17 blieb ein `/interface/wifi/set ... !channel` wirkungslos ohne zu
werfen, und das Selbstprotokoll meldete trotzdem Erfolg — weil es das Profil
las, waehrend der Interface-Inline-Override gewann. Die Abnahme haengt seither
daran, dass jemand daran denkt nachzusehen. Das ist kein Mechanismus.

--assert prueft nach dem Deploy per RouterOS-REST am Geraet und bricht laut ab:

  --assert '/ip/firewall/filter|count=0'
  --assert '/interface/wifi?name=wifi1|channel.width=20/40mhz'
  --assert 'cmd:/interface/wifi/monitor?numbers=wifi1&once=|channel=5180/ax/Ce/I'

Format [cmd:]<pfad>[?query]|<feld-oder-count>=<erwartet>, mehrfach angebbar.
GET fuers Lesen, cmd: fuer POST-Kommandos wie monitor. Trenner ist |, nicht :,
weil MAC-Adressen in Werten Doppelpunkte haben.

Dokumentierte Regel dazu: bei Funkaenderungen muss die Assertion monitor lesen,
NIE das Profil — print detail zeigt aufgeloeste Werte, export die rohen, nur
monitor das, was auf der Luft ist. Genau diese Verwechslung war der Fehler.

Mgmt-IP kommt aus Nautobot (primary_ip4) statt hartkodiert. Passwoerter aus
$ENV, sonst aus ~/.secrets/credentials.env — mit eigenem KEY=VALUE-Parser, weil
die Datei WireGuard-[Interface]-Bloecke enthaelt, an denen `set -a; . datei` in
zsh still abbricht und alle Zeilen danach verschluckt. Fehlerausgaben
redacten das Passwort.

Getestet: count-GET, field-GET mit Query, monitor-POST (inkl. tx-power=18) und
der Fehlerfall, der korrekt abbricht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 15:44:13 +02:00
23c63d435d TP25: dirtyvader-infra offline, Firewall-Filter-Compliance vermessen
-infra auf beiden APs und beiden Baendern disabled (User-Entscheid). Am Geraet
gegengeprueft: aktive-vaps 11 -> 9, w2infra/w5infra disabled=true auf ap1+ap2.
sec-/dp-/cfg-infra bleiben stehen, die Zone ist ohne Neuaufbau reaktivierbar.

Zur Rueckfrage "hidden statt disabled?": Verstecken spart KEINE Airtime. Eine
versteckte SSID sendet ihr Beacon weiter, sie laesst nur das SSID-Feld leer.
Airtime spart ausschliesslich das Abschalten der VAP.

Reconnaissance fuer die /ip firewall filter Compliance-Rule: core 25 Regeln,
branch 0, ap1+ap2 je 12 defconf-Reste (inert, inkl. "accept to local loopback
(for CAPsMAN)"). Zwei Entscheidungen vor dem Template-Bau festgehalten —
AP-Defconf abraeumen vs. als Soll schreiben, und branch als leer rendern.
Ohne die meldet die Rule sofort flaechendeckend Drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 15:14:40 +02:00
77553c94af TP25: Drift-Luecke geschlossen (72/72) — und zwei fehlende Compliance-Sektionen aufgedeckt
Die neuen Funkparameter stehen jetzt in der SoT, nicht nur auf dem Geraet:
radios[5g].width 20/40/80mhz -> 20/40mhz, DEVICE_CHANNELS[ap2][5g] 149 -> 44.
Config-Context gepatcht, dann Backup -> Intended -> Compliance: 72/72, keine
Drifts. Ein kuenftiger Deploy kann die Fixes damit nicht zurueckdrehen.

Bemerkenswert: width fuer 2,4 GHz stand im Config-Context die ganze Zeit
korrekt auf 20mhz. Die SoT war richtig, das Geraet hat sie nicht befolgt —
der Beweis, dass das Problem der Inline-Override war und nicht die Datenlage.

Beim Nachpruefen, ob "72/72" die Funkparameter ueberhaupt abdeckt, sind zwei
Luecken aufgefallen (18 Compliance-Rules abgefragt):

- /interface wifi (Interface-Sektion) hat KEINE Rule. Die fuenf wifi-*-Features
  decken nur die Profilobjekte ab. Die Inline-Overrides leben in der
  Interface-Sektion — deshalb blieben Fund A und D seit 2026-08-08 unentdeckt,
  waehrend die Flotte durchgehend "compliant" meldete.

- /ip firewall filter hat KEINE Rule, es gibt nur ip-firewall-nat. Die
  TP5-Zeile "laeuft ueber ip-firewall-*-Features aus TP22" war damit
  irreführend. Die 11 Etappe-2-Regeln und der kommende Deny-by-default sind
  nicht drift-ueberwacht; "72/72" sagt ueber die Firewall nichts aus.
  -> als Vorbedingung fuer TP5 Etappe 3 eingetragen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 15:01:00 +02:00
14aa4f3142 TP5 Etappe 2 ausgerollt + TP25/TP16.3 angelegt, TP25 Schritte 1-3 durch
TP5 Etappe 2: 11 Whitelist-Regeln auf crs326-core, abgeleitet aus 43.027
Logzeilen (21 h) statt geraten. D1 = MAIN->INFRA pauschal, D4 = MGMT named
sources (HA:8728, Nautobot:22, MAIN, cf-mesh), D5 = 8123 + MQTT.
Log-Regel ist im Moment des Deploys verstummt; Zaehler steht. Etappe 3 bleibt
gated auf ein mehrtaegiges stilles Fenster + D2 (iPhone aus dem IOT-SSID).

TP25 neu — WLAN-Stabilisierung, Sammel-TP fuer Christophs Beobachtungen 1-6.
Schritte 1-3 durch, alles am Geraet gegengeprueft:
- w2-iot trug einen channel.*-Override auf einem Slave-VAP (auf ap1 sogar
  2ghz-n gegen einen 2ghz-ax-Master) -> Mechanismus hinter "-iot mal da,
  mal nicht". Danach auf beiden APs BR/running.
- 2,4 GHz lief auf 40 MHz, obwohl ch-2g width=20mhz sagt: ein Inline-Override
  auf wifi2 gewinnt gegen das Profil. Jetzt 20 MHz, ap1 ch1 / ap2 ch11.
- ap2s 5-GHz-Radio sendete mit 9 dBm, jetzt 18. Beide APs 40 MHz,
  ueberlappungsfrei (5170-5210 / 5210-5250).

Drei Korrekturen an eigenen Annahmen:
- Die 9 dBm sind NICHT das ETSI-Band C. Der Wechsel ins Indoor-Band liess sie
  bei 9; erst die Breite brachte 18. "80 MHz generell" traegt auch nicht,
  ap1 fuhr 80 MHz mit 18. Mechanismus offen, Hypothese + Test in TP25.
- `!channel` loescht Inline-Overrides nicht, nur !channel.width einzeln.
- Frequenz vor Breite zu aendern hat ap2 kurzzeitig in denselben 80-MHz-Block
  wie ap1 geschoben. Breite VOR Frequenz.

Die ch149-Notiz ist bis 03f328f (2026-06-18) zurueckverfolgt: geloest wurde
Co-Channel, nicht DFS. "non-DFS" war nachtraeglich mitgeschriebene Begruendung
fuer das FCC-Standardpaar 36/149, keine geprueft Anforderung. Und
skip-dfs-channels=10min-cac schliesst DFS gar nicht aus, nur das
Wetterradar-Band -> 5500-5700 liegt als Reservekanalraum brach.

TP16.3 neu — cloudflared-Reduktion: der Mesh IST schon der private Datenpfad
(137 Zeilen im TP5-Log belegen es), Container braucht nur der oeffentliche
Ingress. Mesh-Hostname-Routes fuer public hostnames sind Egress, nicht
Publishing — Verwechslungsfalle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 14:44:40 +02:00
a78f385479 Merge branch 'tp5-etappe1-log-lauf'
# Conflicts:
#	docs/teilprojekte.md
2026-08-17 14:35:26 +02:00
d68e82d9ae TP16.1 Nachlauf: Mgmt-ACL via GC auf alle 4 Geraete (72/72), CF-Schalter entschieden
Neue Compliance-Feature ip-service (17->18 Regeln, 68->72 Checks). Sollzustand
einheitlich im Template: ssh/www/winbox/api = 10.40.0.0/16,100.96.0.0/12;
ftp/telnet/api-ssl disabled. Deploy gestaffelt (ap2 zuerst, am Geraet
gegengeprueft), Job liegt als 'mgmt-acl' in gc-configplan.py.

Befund war invertiert: branch/ap1/ap2 hatten GAR KEINE Address-Beschraenkung
und waren laengst per Mesh erreichbar; winbox war auf allen vier offen. Aus dem
Erreichbarkeits-Fix wurde eine Haertung. ftp/telnet/api-ssl dabei abgeschaltet.

CF-Schalter 'Allow all Cloudflare One traffic to reach enrolled devices':
recherchiert, bleibt AUS - er oeffnet die Client<->Client-Richtung, unsere laeuft
ohne ihn. Kein API-Feld, CF-Docs widersprechen sich (Profil- vs. globale
Einstellung).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 12:55:03 +02:00
63851ad0ad TP16.1 ABGESCHLOSSEN: privater Zugang via natives WireGuard, ICMP repariert
4.5 Abnahme bestanden: 0% Ping-Loss auf alle BF-VLANs (vorher 100%), TCP mit
echtem Datenfluss ok, FQDN-Smoke beweist cloudflared-Public-Teil unberuehrt.
4.6 Auflage #4 erfuellt: Ist-Stand als intended config nach Nautobot,
65/68 -> Template ergaenzt -> 68/68 keine Drifts.

Zentrale Falle dokumentiert: /ip service address=10.40.0.0/16 sperrt das
Router-Mgmt aus der Mesh-Range 100.96.0.0/12 aus - Ping geht, SSH/REST/MikroMCP
sterben. Fuer branch/ap1/ap2 noch offen. Und: nc -z ueber WARP ist kein
Reachability-Beweis, der CF-Proxy terminiert den Handshake.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 12:28:03 +02:00
44c1fbcca8 TP16.1 4.1-4.4 durch: Mesh-Tunnel steht auf crs326-core
Prereqs: use_zt_virtual_ip=true, Device-Profil 'Cloudflare Mesh', Split-Tunnel
auf beiden Profilen (100.64/10 -> /11 + 100.112/12).
Geraet: cf-mesh, 100.96.0.6/32, Peer 162.159.193.2:2408, Handshake steht,
Route 100.96.0.0/12 aktiv. Backup vorher (Auflage #4).
4.4 Weg A hat funktioniert - vnet-Gotcha trat NICHT ein.

Zwei Werkzeug-Fallen dokumentiert: MikroMCP manage_wireguard_interface kann
keinen Privkey annehmen (CF liefert ihn aber), und manage_wireguard_peer
verarbeitet endpoint 'IP:Port' falsch (endpoint-port=0 -> kein Handshake).

Offen: Dashboard-only-Schalter 'Allow all Cloudflare One traffic to reach
enrolled devices' + Ping-Abnahme 4.5.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 12:08:36 +02:00
7388cc8388 TP16.1 4.0 DURCH: Mesh-Node bf-core-mesh angelegt, Free-Plan-Gate offen
POST /warp_connector erfolgreich -> d1da7c8a-... Der LXC-Fallback ist vom Tisch.
Blocker war der Token, nicht der Plan: alter User-Token hatte 2 fehlende
Permissions, ersetzt durch account-owned Token (gueltig bis 2027-01-09).
Zwei Fallen dokumentiert: account-owned Tokens verifizieren an
/accounts/{id}/tokens/verify (am /user-Pfad melden sie faelschlich
'Invalid API Token'), und Zone-Permissions brauchen eine eigene Policy-Zeile
('Account tag in access policy must match tag in request uri').
Verifiziertes Permission-Set inkl. IDs in 4.0. Am Geraet weiterhin nichts angefasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 11:58:51 +02:00
52e79c427c TP16.1 Scharfschalten: Plan-Probe gescheitert (Token-Scope) — Blocker vollstaendig vermessen
POST /warp_connector -> 10000/403, identisch zu 2026-07-17. Neu: Gegenproben
zeigen, dass auch 4.1 blockiert ist (devices/settings GET 403) — es fehlen ZWEI
Permissions, nicht eine. MCP-Read-Gegenprobe belegt: Account kann es, Token darf
nicht -> Free-Plan-Frage bleibt offen. Am Geraet wurde nichts angefasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 20:06:36 +02:00
bb2c87c68e Compliance 68/68 + TP24 (USV) ausgeloest + Doku auf den Stand nach dem Core-Cutover
Zwei Straenge, die sich dieselben Dateien teilen — deshalb ein Commit.

1) COMPLIANCE-DRIFTS BESEITIGT (User: "beseitige autonom alle") -> 68/68, 0 Drifts

Entfernt wurden die 4 verbliebenen `extra`-Drifts (der fuenfte, core 10.40.41.211,
war schon ueber TP19-vlan1-core-address gefallen):
- ap1 + ap2: Werks-defconf `/ip dns static router.lan -> 192.168.88.1`. Auf beiden
  APs der einzige statische Eintrag, die IP existiert im Netz nicht. Der Core hat
  sein eigenes, korrektes router.lan -> 10.40.99.1 (im Template, compliant).
- crs326-branch: Bring-up-Rest SVI vlan10 + 10.40.10.2, Adresse zuerst.

Richtung bewusst "am Geraet entfernen" statt "ins Template aufnehmen" — genau so
steht es seit 2026-08-13 im Switch-Zweig des Templates. Der frueher notierte
Vorbehalt "potenzielle Rettungspfade" ist per User-Entscheid aufgehoben; der
Mgmt-Fallback aus VLAN10 auf dem branch entfaellt damit (Rueckweg = MAC-Winbox am
selben Draht).

Weg: 3 manuelle GC-ConfigPlans, kein Direkt-Write. Vorher /system backup je Geraet.
Deploy gestaffelt — erst die APs, am Geraet gegengeprueft, dann branch.

Verifikation am GERAET, nicht am Job: DNS-Statics total=0 bei unveraenderten 28
bzw. 3 WLAN-Clients; branch nur noch vlan99 + 10.40.99.2/24; Ping vom Core 4/4.
Entscheidende Gegenprobe: /interface bridge vlan/export byte-identisch — `bridge`
steht dort statisch als tagged-Member von VLAN10, das Entfernen des SVI hat also
weder Traffic-Wirkung noch neuen Drift. Danach Backup -> Intended -> Compliance,
alle 4 Geraete mit frischem Success-Datum.

Neue API-Falle, die erklaert warum es bisher kein Skript gab:
POST /plugins/golden-config/config-plan/ ist 405 — das ViewSet ist read-only.
ConfigPlans entstehen nur ueber den Job "Generate Config Plans" (plan_type=manual
+ commands-TextVar). plan_type=missing erzeugt ausserdem nur add-Zeilen, also muss
alles Entfernende zwangslaeufig ein manueller Plan sein.

Neu: nautobot/gc-configplan.py — loest Device-UUIDs einzeln per Name auf und
assertet plan.device UND config_set gegen das Ziel (die alphabetische
Sortier-Falle aus TP21.1 kann damit nicht wiederkommen), verweigert config_sets
mit <<REDACTED>> (Regel 1) und print-Zeilen, kann gestaffelt deployen
(--deploy-ids) und kapselt Backup -> Intended -> Compliance (--refresh-compliance).
Dry-Run ist Default.

2) TP16.1: GATE OFFEN, Runbook ausfuehrungsreif, Governance-Ausnahme #4

Die Bedingung "gated bis TP21 den CRS326 abdeckt" ist seit der Adoption am
2026-08-13 erfuellt. §3 neu gemessen, §4.3 von Platzhalter auf echte Werte.
Die letzte inhaltliche Unbekannte hat sich erledigt: "Rueckweg-Routing TBD" —
der Core IST L3-Gateway aller VLANs, es braucht keine Zusatzroute. wg-hub liegt
auf demselben Geraet und ist damit direktes Vorbild statt fernes Muster.

Klarstellung, weil leicht zu verwechseln: das Mesh ersetzt die Tunnel NICHT. Es
loest nur den privaten Zugang (10.40.0.0/16 per IP, inkl. ICMP); die oeffentlichen
FQDNs bleiben auf cloudflared. Relevant dabei: die Route 10.40.0.0/16 zeigt auf
bf-pve — und der faehrt derzeit nur einen Connector.

Ausnahme #4 (User 2026-08-16): die WG-Zeilen des Mesh-Bring-ups auf crs326-core
duerfen direkt gesetzt werden. Grund ist strukturell, nicht bequem — TP22-Regel 1
schliesst jede <<REDACTED>>-Sektion vom Push aus, ein Privkey ist ueber Golden
Config gar nicht deploybar. Auflage: Backup vorher, intended config danach zurueck
nach Nautobot. Scope: nur dieser Bring-up.

Damit das ein einmaliger Bootstrap bleibt, ist das Secret-Handling-Design
dokumentiert: ein privater Schluessel ist Geraete-Identitaet, keine Konfiguration
(wie ein SSH-Hostkey). Der private Teil entsteht am Geraet und geht nie weg, nur
der oeffentliche kommt in die SoT und wird in die Peer-Configs gerendert.
Stufe 2 (nautobot-secrets-providers + Vault) lohnt bei 4 Geraeten und einem Key
nicht. Nebenbefund: die WG-Peers fm/dw stehen mit hartkodierten public-keys im
Jinja-Template — Public Keys sind Daten, keine Templatezeilen.

3) TP24 — USV aus TP15 herausgeloest (User-Entscheid)

Die DC-USV war der letzte offene Rest in TP15 und hat mit Switching/Routing
sachlich nichts zu tun (eigene Einkaufs-, Verkabelungs- und Elektrik-Logik).
TP15 ist damit inhaltlich zu. TP24 traegt jetzt 48V-Bus, MeanWell/LiFePO4,
Laufzeiten, DC-Eingangs-Tabelle und die 5 offenen Entscheidungen — darunter neu
die Standortfrage, die sich durch den Core-Umzug ins UG neu stellt.

4) DOKU-AUFRAEUM-SESSION A-E abgearbeitet

- Ist-Stand-Block neu geschrieben, live gegen die Geraete geprueft. Alte Fassung
  als ausklappbare Historie, ⚠️-Provisorium entfernt.
- Reihenfolge-Abschnitt auf den echten Rest-Pfad TP5 -> TP6 eingedampft (Punkt 3
  sagte noch "Jetzt: Omada-PVID-Fix").
- Stale ap1-als-Router-Aussagen in TP3/TP4/TP15/TP16.1/TP21/TP-R korrigiert —
  fortgeschrieben, nicht ueberschrieben.
- CLAUDE.md: Mac mini .41.167 -> .20.167 (war stale, live per ARP bestaetigt),
  branch-Uplink "sw1 GE8" -> "core ether8", ALLNET-/Omada-Gotchas als Historie.
- switch/ als Archiv gekennzeichnet (Geraet ausgebaut, Runner nicht ausfuehrbar).
- omada-mcp + CF-Ingress live gegengeprueft: beides sauber, Punkt abgehakt.

Nebenbefund, eingetragen aber nicht angefasst: das CF-Tunnel-HA ist degradiert
(bf-nas und bf-pve mit je nur einem Connector), und vier tote Alt-Tunnel tragen
VLAN1-Origins — darunter die Aufloesung des "unidentifizierten VLAN1-Geraets
.41.133" aus TP19 (es ist das coolify-Origin).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 19:28:50 +02:00
0396321560 NAS: hms-mqtt stillgelegt (restart=always -> no)
Der Container war bereits beendet; entscheidend war die Restart-Policy.
Mit `always` waere er beim naechsten Daemon-Neustart wiedergekommen, ein
blosses `docker stop` haette also nicht gehalten.

Nebenbefund, nicht von mir ausgeloest: grafana, drawio-server und hms-mqtt
wurden am 2026-08-16 um 17:14:54-17:15:06 CEST innerhalb von zwoelf
Sekunden per Signal beendet (grafana exit 0 mit "System signal:
terminated", drawio-server 143, hms-mqtt 137). Kein OOM, Speicher frei,
restarts=0. Folge: das Prometheus-Ziel grafana steht auf down, n8n und
prometheus weiter up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 17:39:25 +02:00
415be1ed24 TP5 Etappe 1: Sammelphase laeuft, VLAN1-Rueckbau abgenommen
Abnahme bestanden: out:bridge = 0 ueber ein 10-Minuten-Fenster (Logdatei
vorher geleert). Vorher waren vlan20 -> bridge 76 % des gesamten
Inter-VLAN-Verkehrs; die Rate fiel von ~166 auf ~34 Zeilen/min.

Beobachtete Matrix (339 Zeilen / 10 min) als Arbeitsmaterial fuer Etappe 2
festgehalten. Zwei Befunde daraus:

- D4 ist belegt statt geschaetzt: der Management-Pfad ist HA (10.40.20.105),
  das ueber seine mikrotik-Integrationen 8728 auf branch/ap1 pollt (je 67x).
  Ohne Whitelist sperrt der spaetere Drop die Netzverwaltung aus.
- Neuer Merkposten: same-VLAN-Verkehr erreicht die forward-Kette —
  vlan10 -> vlan10 unicast mDNS, erzeugt vom mDNS-Repeater auf dem Core.
  Harmlos, aber ein blanker Drop wuerde Discovery innerhalb von MAIN
  beschaedigen.

Damit sind drei Whitelist-Zeilen bekannt, bevor Etappe 2 beginnt:
LAN->WAN, der Mgmt-Pfad, und same-VLAN-mDNS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 17:34:06 +02:00
49f2bfd98f NAS: Container-Manager-Neustart — Haenger weg, Portainer-Integration bleibt offen
synopkg stop/start ContainerManager auf nas-bf. Alle 14 Container aus der
Baseline sind zurueck, zusaetzlich kam hms-mqtt hoch (Restart-Policy, lief
vorher nicht).

Der Neustart hat den Haenger behoben: `docker system df` beendet sich wieder
(vorher rc=124 nach Ausgabe der Tabelle). Er reicht aber nicht — der Aufruf
bleibt mit 33s bis ueber 120s weit ueber dem pyportainer-Timeout, die
HA-Integration bleibt auf setup_retry.

Gemessen, wo die Zeit hingeht: images -q 84ms, ps -aq 95ms, volume ls 65ms,
system df 33-92+s. Also vollstaendig in der Groessenberechnung (Durchlauf der
overlay2-/Volume-Verzeichnisse auf NAS-Platten) — Plattformnachteil, kein
Defekt.

Aussichtsreichster Weg dokumentiert: eigener Portainer-Benutzer fuer HA ohne
Zugriff auf ep14. Zwei widerlegte Zwischenthesen sind als solche festgehalten
(odroid-m1 war es nicht; es ist kein Groessenproblem).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 18:57:04 +02:00
39e92d336d TP19: VLAN1-Adressen abgeraeumt (pve .41.100, core .41.211), Prometheus bereinigt
pve: /etc/network/interfaces vmbr0 von inet static auf inet manual, Adresse
raus, angewendet per `ip addr del` ohne ifreload -a. Alle 9 Gaeste weiter
running, Storage aktiv, nur noch vmbr0.20 traegt eine IP.

core: 10.40.41.211 ueber Nautobot GC entfernt. Mgmt .99.1 + 10.40.10.1
intakt, Compliance 17/17 gruen — der letzte offene Drift ist damit weg.

Prometheus: der pauschale 41->20-Ersatz war eine Falle. Gemessen statt
angenommen — nur grafana und n8n liefern echte Metriken. gitea hat /metrics
nicht aktiviert, vaultwarden gibt 404, portainer /api/status liefert JSON
statt Prometheus-Format, node/alertmanager/qdrant sind exited, pihole ist
abgewaehlt. 8 Jobs + alerting-Block auskommentiert, 3 Ziele aktiv und up.

Zwei Korrekturen an eigenen Aussagen:
- Die tote Portainer-Umgebung odroid-m1 war NICHT die Ursache des
  HA-Hangs. Sie ist entfernt, das Symptom blieb. Echte Ursache laut
  HA-Debug-Log: `docker system df` auf ep14 kommt nicht zurueck.
- Auf der NAS ist prometheus.yml fuer den Login-User nicht schreibbar
  (65534:65534, Verzeichnis gehoert adm.christoph). Zwei `cat >`-Pushes
  sind still gescheitert. Schreiben nur per sudo tee + md5sum-Gegenprobe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 18:40:15 +02:00
10d93e6214 TP5 Etappe 1 pausiert + VLAN1-Restliste aus dem Log-Lauf
Etappe 1 ist aufgebaut und verifiziert, wird aber vor der Sammelphase
pausiert (User-Entscheid): 76 % des beobachteten Inter-VLAN-Verkehrs waren
.41.x-Altlasten. Eine Whitelist daraus haette nach dem Aufraeumen nicht
mehr gegolten.

- Log-Regel disabled=yes, Memory-Logging zurueck auf topics=info
- Kollektor + Logging-Action bleiben stehen -> Wiederaufnahme = zwei Zeilen
  (routeros/tp5-etappe1-pause.rsc dokumentiert beide Richtungen)
- D2 vollzogen: iPhone im MAIN-SSID, .30.201 im ARP auf failed

TP19 bekommt die konkrete Restliste, die der Log-Lauf sichtbar gemacht hat:
prometheus (.20.151) scrapet 10 tote 10.40.41.x-Ziele, .20.105 zieht auf
pve unter der alten .41.100. Umzugsregel 41->20 bei gleichem letzten Oktett.

Der gemeldete Timeout auf .20.100:8006 ist KEIN Firewall-/Portproblem:
pveproxy lauscht auf *:8006, pve-firewall disabled, HTTP 200 in 0,06 s aus
VLAN10 und VLAN20. Notiert ist auch die Fehlerquelle meines ersten Tests -
`timeout` existiert auf macOS nicht und meldet falsch-negativ.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 18:02:51 +02:00
bf07c642f7 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>
2026-08-14 17:30:15 +02:00
f31172e4d9 TP5-Runbook: D3 entschieden (ICMP-Sweep = lanscan.app, gehoert in die JIT-Gruppe)
Der Dauersweep von .10.82 auf alle Shellys ist lanscan.app — ein Ad-hoc-Scan vom
Arbeitsplatz, kein Dienst. Also keine permanente MAIN->IOT-ICMP-Regel, sondern
Teil der selbstverfallenden JIT-Admin-Gruppe (deckt sich mit D4).

Hinweis fuer den Log-Lauf ergaenzt: der Scan erzeugt sonst Rauschen in Etappe 1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 16:38:29 +02:00
3113218212 TP16.2: vw bleibt bypass (harter Constraint) — Haertung ohne Client-Bruch
User-Constraint 2026-08-14: vw wird NICHT WARP-/Access-geschuetzt, dauerhaft.
Begruendung ist technisch, nicht Bequemlichkeit — die Bitwarden-Clients koennen
den interaktiven Access-Login nicht (dasselbe Muster wie der 400er der
HA-Companion-App). Ein Passwortmanager hinter einem Client, den man im Notfall
nicht installieren kann, ist ein Aussperr-Risiko gegen den eigenen Schluesselbund.
Die TP16-Schritt-5-Absicht "vw von bypass auf geschuetzt heben" ist gestrichen.

Neu: TP16.2 — Haertung aller bypass-Dienste (vw, hass, gitea) in Schichten:
- Schicht 0 (vorhanden): keine offenen Ports, alles ueber CF-Tunnel.
- Schicht 1: Access nur auf /admin* als eigene, spezifischere Application —
  CF wertet die spezifischste App zuerst. Das Admin-Panel wird nur per Browser
  bedient, die Client-Pfade (/api, /identity) bleiben bypass. Kein Client bricht.
- Schicht 2: App-eigene Limits (Vaultwarden LOGIN_RATELIMIT_* sind default an),
  Signups aus, 2FA erzwingen; HA ip_ban_enabled.
- Schicht 3: CF WAF/Rate-Limiting gezielt auf die Login-Endpunkte.
- Schicht 4: CrowdSec/fail2ban mit CF-Bouncer — Bans an der Edge, alle Dienste.

Knackpunkt und Schritt 1: hinter dem Tunnel sieht die App nur die IP des
cloudflared-Containers. Jede IP-Sperre bannt sonst den Tunnel statt den
Angreifer = Selbstaussperrung. Genau dieser Defekt ist schon offen (HA
trusted_proxies fehlen .20.10/.20.167) — X-Forwarded-For/CF-Connecting-IP
sauber durchreichen ist Voraussetzung fuer Schicht 2-4.

Nebeneffekt: TP23s Managed-Networks-Weg ist entlastet — vw verlangt nie
Device-Identity, "WARP zuhause aus" kollidiert nicht mehr mit dem Access-Strang.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 16:32:42 +02:00
4443155627 TP23 angelegt (DNS-Policy & Self-Service), TP7.1 in TP5 gezogen, cudy-Leak erledigt
TP23 — DNS-Policy & Self-Service-Ausnahmen (neu, Konzept entschieden):
- Architektur: Filterliste bleibt zentral bei Cloudflare, lokal nur die Diffs.
  Kein RAM-Thema auf dem Core, eine Policy-Quelle, gleiche Regeln zuhause wie
  unterwegs.
- Resolver-Wahl AdGuard Home (laeuft schon). Pi-hole disqualifiziert: spricht
  kein DoH (braeuchte cloudflared-Sidecar) + belegter v5->v6-Bruch. Technitium
  als dokumentierte Alternative.
- AGHs fehlendes Gruppen-Objekt ist hier unkritisch: Clients per CIDR = ein
  VLAN ist eine Gruppe. Die Segmentierung ist bereits die Policy-Grenze.
- WARP im LAN via Managed Networks abschaltbar (Beacon auf NAS/pve); loest die
  ICMP-Falle vom 2026-08-13. Side effect dokumentiert: kollidiert mit dem
  offenen TP16-Schritt 5 (vw von bypass auf WARP-geschuetzt).
- 802.1X loest die IoT-Identitaet NICHT (kein Supplicant, MAB ist wieder MAC)
  -> TP8 bleibt Sicherheitsthema, nicht DNS-Identitaetsquelle.
- Reihenfolge-Regel: TP5 darf die DNS-Bypass-Sperre erst schliessen, wenn die
  Ausnahme-Oberflaeche steht — der bisherige Workaround "Client auf 1.1.1.1"
  IST dieser Bypass.

Weitere Korrekturen:
- TP7.1 (SSDP-Reflector) aus "vorgemerkt" in das TP5-Paket gezogen: iOS-App und
  HA finden die Sonos, nur die macOS-Desktop-App nicht — SSDP quert die
  VLAN-Grenze nicht. Kein Firewall-Problem, die Regel ist laengst offen.
- Ziel-Absatz (c): cudy1-VLAN1-Leak erledigt (core ether11 ohne Link,
  Nautobot Offline). (b): st-main rrm/wnm ist seit TP3.3 kein Provisorium mehr,
  sondern Teil der Golden Config.
- TP7: mdns-repeat-ifaces auf den Live-Stand des Core nachgezogen (ohne
  bridge — mit dem VLAN1-Retirement erwartbar, war nie dokumentiert).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 16:25:36 +02:00
cbef32ca11 TP5-Session vorbereitet + Statuskorrekturen (TV-Beweis, TP19.1, Ist-Stand)
TP5 (Deny-by-default) ist nach TP22 der kritische Pfad und jetzt einsatzbereit
vorbereitet — auf Live-Erhebung von crs326-core statt aus der Doku.

Neu:
- docs/tp5-deny-by-default-runbook.md: Ist-Stand forward/input/NAT/Interface-
  Listen, Inter-VLAN-Flow-Matrix aus conntrack + Countern, offene Entscheidungen
  D1–D6, 4 Etappen (Etappe 1 = reiner Log-Lauf ohne Blockierung), Rollback.
- docs/doku-cleanup-session.md: Arbeitsliste A–E für die Aufräum-Session
  (Ist-Stand-Block, Reihenfolge-Liste, stale "ap1 = Router"/CAPsMAN-Aussagen).

Statuskorrekturen in teilprojekte.md:
- TP21.1 Punkt 4: TV-End-to-End-Beweis erbracht (Ping 5/5, MAC auf ether4/VID40
  gelernt, RX 1.338 -> 6.909 Pakete). Das Kabel-Follow-up entfaellt — geloest
  wurde am Port, nicht am Kabel.
- TP19.1: WIP -> erledigt (ap2 seit TP3-Rebuild auf .99.12, sw1/sw2 ausgebaut
  und in Nautobot Decommissioned).
- TP5: Holes + WAN-Seal auf crs326-core re-verifiziert — die Verifikation vom
  2026-07-02 galt ap1, das seit 2026-08-08 Werksreset ist. Befund: die 5
  mDNS-Input-Regeln sind hinter TP10-seal-lan wirkungslos (0 Pakete).
- Ist-Stand-Block als Historie markiert, "Naechster Schritt" auf TP5 -> TP6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 16:19:00 +02:00
e17e45db91 TP22 abgeschlossen + WLAN-Roaming repariert (802.11k/v)
TP22 Schritt 5 — Datenmodell as-built aus dem Geraet erhoben (bridge/port,
bridge/vlan, bridge/host + ARP/Leases), nicht aus der Doku:
- crs326-core von 5 auf 26 Ports; 3 waren "GEPLANT (tentativ)", ether1 zeigte
  noch auf das tote sw1 #12
- Standort-Fehler: crs326-branch + ap2 standen auf Technik UG, real Technik OG
- sw1/sw2/cudy2 -> Decommissioned (Endzustand), cudy1 -> Offline;
  sw1-Duplikat-Ports (gi*) entfernt
- Schritt 4 entschieden: keine Secret-Injection (Governance-Regel 1 deckt es ab)

TP21.1/4 — core ether4 geklaert und behoben: dort haengt das Wohnzimmer-
Sideboard. Der Port war als ap1-Trunk vorkonfiguriert, pvid=40 nahm untagged an
(Upstream ok), Egress war tagged -> TV bekam nichts. Diagnose ueber TX/RX-
Asymmetrie + ARP failed bei frischem bound-Lease (ein bound-Lease beweist nur
den Upstream: INIT-REBOOT-REQUEST braucht kein ACK). Auf untagged VLAN40
gezogen, Kabel bleibt auf Port 4 (Patchfeld-Nummerierung ist Infrastruktur).

TP3.3 — Steering-Regression aus dem TP3-Rebuild behoben: /interface wifi
steering war auf BEIDEN APs leer. 802.11r/FT macht die Uebergabe nur schnell,
ausgeloest wird sie von 802.11k/v -> sticky client bis zum Abriss. st-main
(rrm/wnm, neighbor-group bf-main) wiederhergestellt und ins GC-Template
aufgenommen, damit eine Neuprovisionierung es nicht wieder still verliert.

Compliance 20/20 -> 63/68 (dieselben 5 bekannten Altlasten):
- neue Features wifi-steering, bridge-port, bridge-vlan
- der L2-Layer war bisher komplett unueberwacht (core-Zweig hatte gar keine
  Bridge-Sektion, AP-Zweig nur VLAN ohne Ports)
- Bridge-Sektionen bewusst als Literal-Block statt aus DCIM abgeleitet: pvid aus
  untagged_vlan zu generieren haette die akzeptierten Schiefstaende (core ether3,
  core ether2, branch ether9-23) zu Dauerdrift gemacht

Alle Geraete-Aenderungen liefen ueber Nautobot-GC-ConfigPlans mit /system backup
davor, keine Direkt-Writes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 02:51:38 +02:00
3666e1e7fe TP22: RouterOS-Fleet unter Nautobot Golden Config, Deploy scharf
Nimmt die 4 Live-Geräte (crs326-core/-branch, ap1, ap2) real unter Golden
Config: Backup -> Compliance -> intended -> kontrollierter Push. Damit greift
der Governance-Entscheid "Config exklusiv über Nautobot" operativ.

Secret-Leak geschlossen (Anlass, ungeplant gefunden)
  Es gab keine ConfigReplace-Regeln, deshalb hatte der Backup-Job den
  ap1-/export ungefiltert nach Gitea geschrieben: der live genutzte
  WG-Hub-private-key und 6 WLAN-PSKs lagen dort im Klartext.
  - nautobot/ingest-gc-scrubbing.py: 5 ConfigReplace-Regeln, Maske
    "<<REDACTED>>". RouterOS quotet nur bei Bedarf (4 von 6 PSKs standen
    unquotiert), daher Alternation mit der quotierten Variante zuerst --
    \S+ ist greedy und würde bei einem PSK mit Leerzeichen den Rest
    exponieren. Regex-Selbsttest läuft bei jedem Aufruf.
  - Gitea-Repo neu angelegt (History-Rewrite verworfen: Gitea hält
    unerreichbare Blobs bis zum server-seitigen gc). Verifiziert: 0
    unmaskierte Secrets über alle 4 Geräte. User-Entscheid: nicht rotieren.
  - push-gc-template.py: Pre-Push-Secret-Guard, --dry-run, -m, sha optional.

Template
  - AP-Zweig (role == "Wireless AP"), datengetrieben aus ConfigContext
    ap-common + local_config_context_data; ap1/ap2 differieren nur in 4
    Werten. RadioProfile verworfen (hängt an einem Controller, den es seit
    der CAPsMAN-Abschaffung nicht gibt).
  - crs326-core-Zweig von Slash- auf /export-Form (Space-Form, Attribute
    alphabetisch), stale disabled=yes aus der Cutover-Ära entfernt.
  - Switch-Zweig für crs326-branch.
  - Mgmt-Nummernplan korrigiert: ap2 und branch waren in den DNS-Statics
    vertauscht, ap1 zeigte auf ein nicht existierendes .99.3.
    Verbindlich: core .99.1 | branch .99.2 | ap1 .99.11 | ap2 .99.12.
  Ergebnis: ap1 intended == Geräte-Ist (0 Drift), core 68/69 Zeilen
  byte-identisch. 14 ComplianceRules, 51/56 compliant -- die 5 Restdrifts
  sind echte Altlasten (Rettungspfade, Aufräumen gehört zu TP19).

Deploy (nautobot_config.py, Image gc9)
  enable_plan/enable_deploy an. napalm-ros ist READ-ONLY: der Default-
  Dispatcher wählt NAPALM (Platform trägt napalm: ros), Backup geht,
  merge_config scheitert grundsätzlich mit leerer Fehlermeldung. Fix =
  custom_dispatcher auf NetmikoMikrotikRouteros, in den Golden-Config-
  Settings (nicht den Nornir-Settings). Pilot-Deploy: DNS-Statics auf dem
  Core korrigiert, per Purge-vor-Add, weil plan_type=missing nur add
  erzeugt und sonst Duplikate entstanden wären.
  Governance-Regeln in docs/teilprojekte.md festgeschrieben: Pläne nur
  feature-scoped (ein Voll-Push schriebe die Maske als PSK auf die APs),
  AP-Template nie zeilenweise auf ein laufendes Gerät (vlan-filtering=no
  reisst den Mgmt-Pfad ab).

CLAUDE.md: Power-Save-Fehldiagnose korrigiert
  Der P750W war nicht im Power-Save, sondern schlicht ausgeschaltet; das
  Ping-Symptom kam vom lokal mitlaufenden WARP-Client (cloudflared =
  QUIC-Proxy, kein ICMP). Die Merkregel "DHCP-geht-aber-Ping-nicht =
  ARP/Power-Save" ist damit widerlegt und entfernt; strukturell schliesst
  TP16.1 diese ICMP-Lücke.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 18:16:21 +02:00
3304fa0ed9 TP9: Begründung geschärft — HA beseitigt Core-SPOF nicht, baut nur Sollbruchstellen ein
Core ist unumgänglicher L3-Durchleitungspunkt; zweites Gerät/VRRP entfernt den SPOF
nicht, sondern addiert Config-Sync/Split-Brain/VRRP-Fehler = netto Zuverlässigkeits-
Verlust. User-Entscheid 'ganz klar nein'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-09 00:46:06 +02:00
7bba0c97cb teilprojekte: TP14 ✅ durch, Adoption→TP22 ausgelagert, TP13 vorbereitet, TP9 obsolet
- TP14 (VLAN1→VLAN20-Migration): ✅ DURCH, live re-verifiziert 2026-08-08
  (NAS/pve/LXC/pg/nautobot alle 0% Loss); TP14.5-Gate erfüllt → TP5 entblockt
- TP22 (neu): Device-Adoption + Golden-Config Compliance-Push aus TP21 ausgelagert
- TP13 (Botschafts-WLANs): von Idee zu vorbereitetem TP (Technik/Steps/Recht)
- TP9 (Router-HA): ❌ obsolet — crs326-core bleibt bewusster SPOF
- Kritischer-Pfad-Banner: neuer Rest-Pfad TP22 → TP5 → TP6

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-08 19:41:07 +02:00
e920daf7c8 sw1/ALLNET außer Betrieb (durch crs326-core ersetzt)
Hardware-Tabelle + TP1: ALLNET Core-Switch als außer Betrieb markiert (2026-08-08,
User-Bestätigung) — durch crs326-core (L3-Router + Core-Switch) physisch abgelöst.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-08 19:35:18 +02:00
0e210ac67c CLAUDE.md: Gotcha-Cleanup nach TP3-Rebuild
Überholte Referenzen bereinigt (crs326-core ist L3-Router, ap1/ap2 reine APs,
CAPsMAN + Omada weg):
- Intro/VLAN-Modell: WLAN via Standalone-APs statt CAPsMAN; Mgmt-IP-Schema .99.x
- Gotchas: ap2 an branch ether24 (nicht Omada Port2); beide APs Standalone
  vlan-filtering (nicht CAP); L3-Router=crs326-core (nicht ap1); Edge/WAN+WG-Hub
  auf core (nicht ap1); device-mode nur ap1/ap2; Erstzugriff-Werks-hAP-Weg;
  P750W auf -iot ohne Pin
- Tooling: MikroMCP für alle 4, manage_user für PW, !dynamic; Omada/sw2 abgebaut
- Arris speist core.vlan100

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-08 19:28:53 +02:00
9d39b22b61 TP3-Rebuild: ap1+ap2 als reine Standalone-APs (CAPsMAN weg)
Beide hAP ax² neu als Standalone-Access-Points provisioniert, kein CAPsMAN mehr:
- ap1 10.40.99.11 (core ether15), ap2 10.40.99.12 (branch ether24)
- Uplink geraeteseitig auf ether1 (PoE-Port, poe-out=off); ether2 aus Trunk entfernt
- 6 SSIDs (main WPA3+FT; infra/iot/media/untrusted/guest WPA2+3), iot nur 2,4 GHz,
  media FT=no; jede SSID mit eigenem datapath bridge+vlan-id -> TP3.1-Leck strukturell weg
- Kanaele non-DFS: ap1 ch36/ch1, ap2 ch149/ch11
- Einheitliches Admin-PW auf allen 4 MikroTik (core/branch/ap1/ap2)

Nautobot As-built (nautobot/ingest-ap-rebuild.py): ap1/ap2 Rolle Wireless AP + Active,
Mgmt .99.11/.99.12, ether1-Trunk, stale L3-Objekte (vlan10-90/100, wg-hub) entfernt;
crs326-core primary_ip4 auf .99.1 korrigiert. Verifiziert per GraphQL.

Doku: CLAUDE.md Hardware-Tabelle + teilprojekte.md TP3 aktualisiert.
Configs/PSKs liegen gitignored unter routeros/.secrets/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-08 19:18:50 +02:00
f482aafc84 TP21.1: Core-Cutover-Recovery — crs326-core als L3-Router live
crs326-core ist jetzt der produktive L3-Router (ersetzt ap1, das
plattgemacht + getrennt wurde). Nach dem Cutover fehlten DHCP, WAN,
WG-Hub und DNS-Upstream -> aus dem letzten ap1-Backup
(ap1-pre-core-cutover-20260806-073616) wiederhergestellt.

- DHCP: 7 Server (dhcp-v10..v99) + 8 Networks + 54 Leases
  (routeros/tp21-core-dhcp-from-ap1.rsc; VLAN1-Legacy + omada-inform weg)
- WAN: dhcp-client vlan100 -> Liwest 90.146.33.177, NAT-Masquerade
  (nur WAN-Variante; disabled bridge/ether1-Regeln bewusst nicht),
  Blackhole-Selbst-Default-Route entfernt
- WG-Hub (TP10): Interface + fm/dw-Peers + Routen; Privkey aus
  gitignored ap1-wg-hub.privkey -> Hub-Pubkey unveraendert, beide
  Spokes handshaken (routeros/tp21-core-wan-wg-restore.rsc, Privkey redacted)
- DNS: allow-remote-requests=yes + plain 1.1.1.1 (core hat certs=0 ->
  DoH-Cloudflare-Gateway ist TODO); entsperrte auch FM (Hub-DNS)
- Identity ap1 -> crs326-core; routers.yaml auf Zielschema
  core .99.1 / branch .99.2 / ap1 .99.11 / ap2 .99.12
- disabled/invalid-Fallen bereinigt: WG-Forward-Regeln mit stale *1D
  Interface-ID -> wg-hub; tote gateway=""-WG-Routen entfernt

Doku: teilprojekte.md TP21.1 + CLAUDE.md HW-Tabelle nachgezogen.
Offene TODOs: DoH-Restore, Nautobot-Write-back, branch-88er-Check,
core ether4, ap1/ap2-Reprovisionierung (WLAN-Rebuild).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-08 17:36:45 +02:00
9072b18113 TP15: WG-Hub Key-Restore + AP-Reset Handoff (ap1 resettet, ap2 pending)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 15:15:43 +02:00
30301d40e2 TP21: routers.yaml auf finale MGMT-IPs aktualisiert; Sub-TP21.1 CRS326-Branch-Recovery dokumentiert; Nautobot-Image procps-Fix
- mcp/mikromcp/config/routers.yaml: ap1→10.40.99.11, ap2→10.40.99.12,
  crs326-core→10.40.99.1, crs326-branch→10.40.99.2 (tags aktualisiert).
- docs/teilprojekte.md: TP21.1 angelegt — Branch nach Reboot/Lockout recovery.
- docs/nas-vlan20/nautobot-image/Dockerfile: procps installiert (healthcheck).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 11:40:20 +02:00
7ffb22de97 TP21: Plan aktualisiert — IP-Schema core .99.1, branch .99.2, ap1 .99.11, ap2 .99.12
- APs werden als reine APs neu aufgesetzt (kein Zurückbau)

- WG-Hub behält ap1-Private-Key, damit Remote-Spokes keine Reconfig brauchen

- WiFi-PSKs lokal auf APs, nicht im Nautobot-Template

- Nautobot/GC-Setup für alle 4 MikroTik-Geräte als Ziel, Switches heute nicht neu provisionieren

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 09:46:38 +02:00
f0d1ff9377 TP15: Core-Cutover follow-up (pve #13 VLAN20, IOT #14 VLAN30, APs pending)
- core ether13 tagged VLAN20 -> pve 10.40.20.100 reachable

- core ether14 untagged VLAN30 -> IOT access port

- WG hub already live on crs326-core; FM connected, DW/Geli needs peer pubkey update

- AP provisioning blocked: ap1 REST 401 (password mismatch), ap2 unreachable

- Nautobot down (HTTP 500); password consolidation required before next session

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 09:19:07 +02:00
d281a0f36f TP15: CRS326-Core als L3-Router aktiviert
- crs326-core nimmt Routing/DHCP/DNS/NAT/WAN/WireGuard von ap1 ueber.
- L2-Portplan korrigiert (ap1 #15, Arris WAN #16, branch #8, Sonos #2/3/5/6,
  IoT #14, VLAN10-Access #11, VLAN1-Hybrid #3/7/9/10/12/17-24).
- Backup-RSC gefixt (ether3-24 disabled) und via fixed-RSC eingespielt.
- Gestagede L3-Config enabled in einem Rutsch.
- Falsche statische Default-Route 0.0.0.0/0 -> 10.40.41.1 entfernt,
  WAN-DHCP via 90.146.33.177/24 aktiv.
- SFP-Ports bleiben disabled (Stromersparnis).
- ap1 ist L3-stillgelegt und wird in naechster Session reiner AP.

Backup-Dateien (*.backup) und leases-export.json bleiben lokal.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 22:39:29 +02:00
d8c8c3b828 TP15: WG-Endpoint (bf4) geklaert + Session-Handover
- bf4.emsenhuber.net = CF-A-Record (proxied=false, TTL120, 90.146.35.38),
  KEIN Updater auf ap1 -> nichts zu migrieren. Bei WAN-IP-Wechsel via
  CF_API_TOKEN nachziehen (bf4-Record + Access-Policy bf4-home-ip). Core
  ist nicht device-mode=home -> DDNS-Auto-Updater dort baubar (TP10-Follow-up).
- docs/tp15-core-swap-session-handover.md: Einstieg fuer die Cutover-Session
  (locked decisions, Pre-Window-Checkliste, Kurz-Runbook, Gotchas).
- staged .rsc + teilprojekte.md entsprechend fortgeschrieben.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 18:02:10 +02:00
e727262539 TP15: Core-Swap vorbereitet (staged L3-Config + WG-Hub-Fund)
- routeros/tp15-core-l3-staged.rsc: ap1s Live-L3-Config 1:1 als staged
  Config (alles Betriebsumlenkende disabled=yes, Cutover-Enable in einem
  Rutsch). Reservierungen + WG-Privkey bewusst erst im Fenster maschinell
  von ap1 geholt statt abgetippt.
- Fund/Luecke geschlossen: WG-Hub (TP10 FM/DW-VPN) haengt an ap1s
  Public-Edge, im Handoff uebersehen -> migriert im selben Fenster mit.
- Fenster-Start-Entscheide: Governance = frische Direkt-Ausnahme #3
  (REST/MikroMCP, danach intended->Nautobot); Rettungspfad iPhone-Hotspot.
- Prep-Gotchas dokumentiert: MikroMCP kann core noch nicht schreiben
  (ENV nicht geladen), Mgmt-.99.11 tot (nur .41.211), WG-Keypair-Transfer,
  Public-IP-Wechsel am WAN, vlan99 .1-vs-.11-Reconcile, VLAN1-Teardown.
- teilprojekte.md TP15 fortgeschrieben.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 17:49:08 +02:00
b595c75eef TP15: CRS326-Bring-up (core+branch) + Branch-Tausch gegen sw2 durch
- Beide CRS326 grundkonfiguriert via REST (Governance-Ausnahme #2): core-zuerst
  als L2-Pfad, Zugriff auf Werks-.88.1 über temporäre ap1-.88.2+Masquerade
  (nach Bring-up entfernt). Winbox-MAC scheiterte (sync-timeout).
- branch produktiv, volle SOLL-Portbelegung (ether1 Uplink→sw1#8, 2/8 NAS-20T,
  3 Drucker/4 Dock VLAN10, 5/6 Sonos VLAN40, 7 macmini VLAN20, 24 ap2), mgmt
  .99.13; core grundkonfiguriert nicht produktiv (mgmt .99.11, an sw1#12).
- Branch-Tausch: sw2 physisch raus, Lifelines auf branch; Abnahme grün (NAS/
  macmini VLAN20, Dock VLAN10, Sonos VLAN40). Gotcha: ether3/5-Kabel vertauscht
  (Sonos-VLAN10-Leck/Dual-Homing) → gefixt.
- Nautobot modelliert + GraphQL-verifiziert (nautobot/ingest-crs326-ports.py):
  branch Active + Ports, core Planned + tentativ, sw1 verifizierte 16-Port-
  Belegung (löst UNVERIFIZIERT), sw2 Decommissioning.
- CRS326 in MikroMCP routers.yaml; Creds in ~/.secrets. Doku (teilprojekte/
  CLAUDE/ip-plan) nachgezogen; Core-Swap-Handoff-Prompt neu.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 16:20:26 +02:00
dfec117e6b TP15: Portfakten + Governance-Ausnahme CRS326-Bring-up + Handoff-Prompt
Portplan-Widerspruch aufgeloest (User): Core #15 = ap1 (Ziel kuenftig #4), #11 = cudy1.
Damit gilt die TP4-Variante (gi16 Arris -> gi15 Trunk -> ap1); 03-trunk-ap-ports.cli
(gi1 = ap1) ist STALE, vom Edge-Cutover 2026-07-01 ueberholt. gi16/gi8 bleiben
unverifiziert und sind in Nautobot als solche markiert.

Kernrisiko dokumentiert: crs326-core ersetzt sw1 UND wird L3-Router, an sw1 haengt ap1
(#15) mit Gateway/DHCP/DNS/WAN-Trunk -> Core-Tausch und L3-Umzug sind dasselbe Ereignis
und bedeuten ein Vollausfall-Fenster. Entscheid: Branch zuerst, Core eigene Session.
Rettungspfade liegen guenstig getrennt (Notebook-WLAN via cudy1 am Core #11,
Kabel-Plan-B am sw2/Branch P4).

Governance-Ausnahme #2 erteilt (User): CRS326-Grundconfig direkt via MikroMCP/Winbox
(Henne-Ei - GC kann nicht auf ein Geraet ohne IP pushen, Templates fehlen). Auflage:
Ist-Stand danach als intended config nach Nautobot. Gilt nicht fuer ap1/ap2.

Nautobot: cudy1/cudy2 als Cudy WR3600E V1.0 (Firmware 2.3.15-20250905-191956),
cudy1 -> Technik UG, cudy2 -> Technik OG/Decommissioning; Platzhalter-DeviceType
entfernt; sw1 gi8/gi11/gi15/gi16; crs326-core ether4 als Zielport fuer ap1.
Alle 8 Devices haben jetzt einen Bereich.

Neu: docs/tp15-crs326-session-handoff-prompt.md - kopierfertiger Auftrag fuer die
naechste Session (beide CRS326 bring-up, Portplan, NUR Branch-Tausch).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 21:58:12 +02:00
a0162aed5f TP15: Standort-Mapping final (1:1 sw1->core / sw2+ap2->branch), Portplan-Blocker dokumentiert
- Technik UG (Diele, kein Keller) = sw1 -> crs326-core; Technik OG = sw2 + ap2 ->
  crs326-branch; ap1 bleibt Wohnzimmer Sideboard. In Nautobot gepflegt.
- Etappe 1 (Erstzugriff CRS326) als unkritisch eingestuft (Werkszustand, Geraet
  griffbereit) -> IP-Konflikt 192.168.88.1 wird physisch aufgeloest.
- Blocker fuer den Portplan festgehalten: sw1-Ist-Belegung nirgends verlaesslich
  erfasst (state-backups sind 214-Byte-Fehlschlaege durch toten claudecode-Login,
  running-PRE.txt ist Pre-TP1). Widerspruch gi1=ap1 vs. gi15=ap1 offen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 21:35:43 +02:00
b0a0b16556 TP21: Nautobot-Basisdaten (Ist-Stand) + TP15-Kurskorrektur CRS326 = L3-Router
Nautobot-Ingest (Ist, nicht Ziel):
- Locations: LocationType "Bereich"; Technik UG (Diele, kein Keller) = crs326-core,
  Technik OG = crs326-branch, Wohnzimmer Sideboard = ap1
- Devices: ap2 -> Rolle "Wireless AP" + Offline; beide CRS326 Platform RouterOS
  nachgetragen (fehlte -> haette jeden GC-Job auf ihnen verhindert);
  sw1/sw2/cudy1 als Uebergangs-Devices ohne Platform
- IPAM: VLAN-Group BF, 9 VLANs (VLAN1 deprecated), 8 Prefixes je VLAN-gebunden
- ap1: 26 Interfaces inkl. MACs, ether2 als Trunk, 9 GW-IPs
- WLAN: logischer Controller bf-wlan (kein CAPsMAN), 6 SSIDs mit VLAN-Bindung,
  2 RadioProfiles

Entscheide 2026-07-22:
- crs326-core wird L3-Router; Routing/DNS/DHCP wandern von ap1, APs werden reine APs.
  Ueberschreibt die fruehere "Router bleibt ap1/ap2"-Zeile desselben Tages.
- CAPsMAN wird abgeschafft, beide APs von Nautobot identisch generiert.
- AP-Uplink wandert auf ether1 (PoE-Port). RouterOS nummeriert ab 1, nie ether0.

Befunde:
- Root Cause des ap1-VLAN1-Lecks: cfg-main-2g hat gar keinen datapath-Block ->
  2,4-GHz-main taggt nicht, Bandwechsel = Subnetzsprung. Nicht das frame-types-Thema.
- Beide CRS326 laufen bereits (RouterOS 7.19.5, Werkszustand), beide auf 192.168.88.1
  im selben L2 = IP-Konflikt.
- hAP ax2 PoE ist passiv 18-28V, nicht 802.3af/at; ether1 steht auf poe-out=auto-on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 21:28:28 +02:00
1578de50c3 TP15/TP16.1: kein RB5009, WG-Mesh auf CRS326; TP21: Golden-Config-Image im Repo
- RB5009 final gestrichen (User-Entscheid 2026-07-22) — Router bleibt ap1/ap2,
  Referenzen in teilprojekte.md + hw-refresh-requirements.md bereinigt.
- TP16.1 Ziel-Device von ap1 auf CRS326 Core-Switch retargeted (Doku-only,
  Scharfschalten bleibt gated bis TP21 den CRS326 abdeckt), Runbook umbenannt
  auf tp16.1-warp-mesh-native-crs326.md, cf-tunnel-mapping.md §14 + Handoff-
  Prompt mitgezogen.
- TP21: docs/nas-vlan20/nautobot-image/ neu — der Dockerfile/nautobot_config.py/
  allnet_sg8316m_driver.py, aus denen das laufende Custom-Image tatsächlich
  gebaut ist (der bisherige Verweis auf scratch/nautobot-gc-build existierte
  nirgends). Ergänzt napalm-ros + nornir-napalm + librouteros + gepinntes
  setuptools<81 (pkg_resources-Regression), Nornir-Credentials auf
  CredentialsNautobotSecrets umgestellt, Compliance/Intended-Config/SoT-Agg
  aktiviert. Backup/Intended/Compliance-Pipeline live gegen ap1 verifiziert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 19:46:24 +02:00
f306d55815 docs ⚪ Nächster Schritt = TP21 (Nautobot Golden Config); Omada-PVID-Fix obsolet
- Omada-PVID-Fix gestrichen (User-Entscheid 2026-07-22): Omada spielt seit der
  TP15-Korrektur keine Rolle mehr im Netz → nicht wieder aufgreifen
- TP5 Deny-by-default folgt nach TP21/CRS326-Adoption (Holes + WAN-Seal stehen schon)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 18:01:15 +02:00
9daedf710c docs 🔑 TP16.1: Token-Permission-Gotcha — Mesh braucht "Cloudflare One Connector: WARP" (nicht Tunnel Write)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 17:22:03 +02:00
2e13594bd5 docs 🔑 CF-Zugang unmissverständlich: MCP read-only vs CF_API_TOKEN-Write (fix fresh-session permission-trap)
Frische Sonnet-Delegations-Session lief in die '10000 Authentication error'-Falle:
sie versuchte CF-Writes über den read-only MCP. Root Cause: .claude.json referenziert
nur die MCP-URL, NIE den Token in mcp/cloudflare/.env → kalter Agent kennt den Write-Pfad nicht.

- Handoff-Prompt: prominenter 'CF-KOMMUNIKATION'-Block (2 getrennte Pfade, exakte curl-
  Kommandos, '10000 = kein Rechteproblem, Pfad wechseln'-Hinweis im Ablauf).
- cf-tunnel-mapping.md §11: gleiche Klarstellung als SSoT-Callout inkl. Verifikation
  (no-op vnet-PATCH: MCP→10000, curl→success). 'Claude hat zig Tunnel erstellt' = immer
  via curl+Token, NIE via MCP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 14:38:19 +02:00
8665902de7 docs 🎫 TP16.1: Governance-Ausnahme ap1-CF-Tunnel erteilt + Handoff-Prompt-File
- Governance-Callout (teilprojekte.md): Christoph erteilt Ausnahme von 'Config nur
  via Nautobot' für alle (Vor)Arbeiten am zentralen CF-Tunnel-Zugang AUF AP1 (TP16/16.1,
  native WG-Mesh-Zeilen). Scope-Grenze: nur ap1 — CRS326 (TP15) fällt vorerst NICHT
  darunter, bleibt Nautobot-GC-pflichtig. Follow-up: ap1-Zeilen später in GC nachtragen.
- Neu: docs/tp16.1-session-handoff-prompt.md — kopierfertiger Auftrag für die
  Delegations-Session (Sonnet), Governance-Gate jetzt als 'erteilt' statt 'erst fragen'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 07:56:45 +02:00