Files
bf-infra/docs/tp31-schritt5-runbook.md
Christoph Emsenhuber b697ffc6fa TP16.3/TP31 Schritt 5: Vor-Ort-Runbook fuer bf-public-Connector (ap1/ap2/ap3)
Runbook docs/tp16.3-bf-public-ap-connector-runbook.md fuer die Vor-Ort-Session
geschrieben; docs/tp31-schritt5-runbook.md abgeloest (read-only-Header).

Live-Befunde 2026-08-30, die den Plan aendern:

- ap3 ist neu und NICHT baugleich: cAP ax (cAPGi-5HaxD2HaxD, 10.40.99.13),
  arm64/96 MB frei, aber ROS 7.24.1 gegen 7.24 auf ap1/ap2 => zwei
  verschiedene container.npk. device-mode=basic statt home (fetch bereits an).
- Blocker A: bf-public-Ingress zeigt auf :80, Caddy antwortet dort mit 308 auf
  https => Redirect-Schleife ueber CF fuer alle vier Namen. Faellt heute nicht
  auf, weil die Alttunnel an Caddy vorbei direkt aufs Backend gehen.
  Fix: https://10.40.20.40:443 + originServerName je Regel (ueber 443 4x 200).
- Blocker B: es gibt KEINE Freigabe vlan99 -> vlan20:443. Die forward-Kette
  wurde vollstaendig gelesen (36 Regeln); die einzige MGMT->INFRA-Regel ist ein
  src-port=8728-Rueckweg. Der Vorgaenger-Runbook behauptet das Gegenteil
  ("Regel 27 deckt vlan99->vlan20:80 ab") - Regel 27 ist IOT->INFRA.
- Blocker C: ROUTER_AP3_PASS fehlt in ~/.secrets/credentials.env (nur in
  ~/.claude.json). Nebenbefund: credentials.env laesst sich in zsh nicht
  sourcen (rohe WireGuard-Zeilen ab ~Z.69) - Variablen bleiben still leer.
- Kein PoE an beiden CRS326 => kein Remote-Power-Cycle, Bestaetigung physisch.
- Die sechs abzubauenden Container auf allen drei Hosts verifiziert;
  terpene-cloudflared und fm.emsenhuber.net bleiben.

CF-Rollback-Snapshots unter docs/cf-backup/*-20260830-vor-tp16.3-schnitt.json
neu angelegt (vier Ingress-Configs + CNAMEs inkl. Record-IDs) - es gab sie
vorher nicht.

Quick-Index, TP16.3-Abschnitt und Ist-Stand-Block mitgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 21:07:17 +02:00

7.8 KiB

TP31 Schritt 5 — Runbook: cloudflared auf ap1/ap2 + CNAME-Flip

Stand 2026-08-27 — vorbereitet, nicht ausgeführt.

⚠️ device-mode-Wechsel ist NICHT remote möglich — erfordert physischen

Mode-Button-Druck an jedem AP, danach Reboot. Dieser Runbook-Teil muss

vor Ort ausgeführt werden.

🔴 ABGELÖST 2026-08-30 — NICHT MEHR AUSFÜHREN. Nachfolger: tp16.3-bf-public-ap-connector-runbook.md. Dieses Dokument bleibt als Historie stehen. Drei Gründe, warum es nicht mehr trägt:

  1. Es kennt ap3 nicht (cAP ax, 10.40.99.13, seit 2026-08-30 in Betrieb) — und ap3 läuft ROS 7.24.1 gegen 7.24 auf ap1/ap2, braucht also ein anderes container.npk.
  2. §2b unterstellt einen Registry-Pull. Auf ap1/ap2 ist fetch: no (device-mode=home) — das Image muss als .tar hoch und per /container add file= importiert werden.
  3. 🔴 §0 behauptet, „Regel 27 MGMT→INFRA TCP deckt vlan99→vlan20:80 bereits ab ✅". Das ist falsch. Die forward-Kette des Core wurde am 2026-08-30 vollständig gelesen: Regel 27 ist IOT->INFRA http-rueckweg (in-interface=vlan30), und die einzige MGMT→INFRA-Regel (Nr. 26) ist ein src-port=8728-Rückweg der API. Eine Freigabe für den Connector existiert nicht — ohne sie landet er in TP5-WOULD-DROP + Drop.

Ebenfalls im Nachfolger, hier noch nicht enthalten: der Redirect-Loop über :80 (Caddy antwortet dort mit 308) und der Abbau der sechs Container.

0. IST-STAND (live gelesen 2026-08-27)

  • Tunnel bf-public 48d3b0b6 ✅: Ingress mit 4 öffentlichen Hostnames → 10.40.20.40:80
  • Token: ~/.secrets/credentials.env → BF_PUBLIC_TUNNEL_TOKEN
  • Config-Dateien: routeros/cloudflared/credentials.json, cloudflared-bf-public-config.yml, ap-bootstrap.rsc
  • Firewall: Regel 27 MGMT→INFRA TCP deckt vlan99→vlan20:80 bereits ab ✅
  • Alte Tunnel: bf-mm (n8n, n8n-mcp, gitea-mcp, pbs), bf-nas (gitea, grafana, pve-mcp, vw, ds-bf), bf-pve (pve, ccu, iobroker, z2m25, portainer, hass, ha-mcp)

1. DEVICE-MODE-WECHSEL (physisch, vor Ort)

1a. Container-Paket checken

/system package print where name="container"

Falls nicht installiert: Winbox → System → Packages → Check For Updates → container aktivieren.

1b. device-mode ändern

/system device-mode update container=yes

Das Gerät fordert auf, den Mode-Button zu drücken. Am hAP ax² ist das der Knopf an der Front. Nach Drücken: „configuration changed, reboot required".

1c. Reboot

/system reboot

1d. Prüfen

/system device-mode print
# output muss zeigen: container: yes

2. CONTAINER BOOTSTRAP (auf JEDEM AP einzeln)

2a. Backup

/system backup save name=vor-tp31-apX

2b. Dateien hochladen (via SFTP, Port 22)

# ap1 (10.40.99.11)
sftp admin@10.40.99.11 <<'EOF'
put routeros/cloudflared/credentials.json flash/
put routeros/cloudflared-bf-public-config.yml flash/
EOF

# ap2 (10.40.99.12)
sftp admin@10.40.99.12 <<'EOF'
put routeros/cloudflared/credentials.json flash/
put routeros/cloudflared-bf-public-config.yml flash/
EOF

2c. Bootstrap-Script importieren + ausführen

/import routeros/cloudflared/ap-bootstrap.rsc

Falls /import Probleme macht: Zeilen einzeln per SSH absetzen.

2d. Abnahme

/container print
# Status muss "started" sein
/log print where message~"cloudflared"
# Muss "Registered tunnel connection" zeigen

CF-Dashboard: Tunnel bf-public → Connections muss > 0 zeigen (1 Connector pro AP).

3. CNAME-FLIP (nach erfolgreichem Bootstrap, sequentiell)

Reihenfolge: n8n → gitea → hass → vw. Jeweils mit Abnahme zwischen den Flips.

3a. Vor jedem Flip: Test-CNAME temporär

Vor dem Umhängen eines Produktiv-Namens testen wir mit einem Extra-CNAME test-tp31.emsenhuber.net → bf-public.cfargotunnel.com, der durch die Wildcard-Access-App *.emsenhuber.net bereits geschützt ist.

# curl im BF-LAN (testet Tunnel→Caddy→Backend)
curl -s -o /dev/null -w '%{http_code}' --resolve test-tp31.emsenhuber.net:443:10.40.99.11 http://test-tp31.emsenhuber.net
# Erwartet: 302 (Access-Login-Redirect)
# Bei 5xx: Container-Log lesen, Caddy erreichbar? /log print auf dem AP

3b. Flip n8n.emsenhuber.net

# Zone-ID ist 1b5bc02fdf61b6b989afde543f3f4134
# Alten CNAME lesen:
CNAME_ID=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
  "https://api.cloudflare.com/client/v4/zones/1b5bc02fdf61b6b989afde543f3f4134/dns_records?name=n8n.emsenhuber.net" \
  | jq -r '.result[0].id')

# Auf bf-public.cfargotunnel.com umhängen:
curl -s -X PATCH -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.cloudflare.com/client/v4/zones/1b5bc02fdf61b6b989afde543f3f4134/dns_records/$CNAME_ID" \
  -d '{"content":"48d3b0b6-7233-4781-a76a-1de4a5e957ce.cfargotunnel.com","proxied":true}'

Abnahme: Browser → n8n.emsenhuber.net → Access-Login → 200 von n8n.

3c. Flip gitea.emsenhuber.net

Analog, aber VORHER prüfen ob Git-Push über Token von außen noch geht.

3d. Flip hass.emsenhuber.net

VORSICHT: HA Companion App kann Access-Login nicht. Vor dem Test:

  • Browser öffnen, Access-Login durchführen, Session-Cookie setzen
  • App öffnen und prüfen ob sie die Session übernimmt

3e. Flip vw.emsenhuber.net

VORSICHT: Bitwarden auf bypass, NICHT hinter Access. Prüfen dass die Access-Policy vw.emsenhuber.net weiterhin bypass ist.

4. AUFRÄUMEN (nach erfolgreichem Flip ALLER 4 Namen)

4a. Alte CNAMEs löschen

Löschen aller CNAMEs, die noch auf bf-mm/bf-nas/bf-pve zeigen. Ausnahme: 3k23uow7, 82unkpb5, j44d6tua (SSH-Tunnel-Namen, keine öffentlichen Hostnames — erst mit Schritt 6 anfassen).

for name in n8n-mcp gitea-mcp grafana pve-mcp ds-bf ccu iobroker z2m25 pve portainer pbs ha-mcp nautobot gateway-dw; do
  ID=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
    "https://api.cloudflare.com/client/v4/zones/1b5bc02fdf61b6b989afde543f3f4134/dns_records?name=${name}.emsenhuber.net" \
    | jq -r '.result[0].id // empty')
  if [ -n "$ID" ]; then
    curl -s -X DELETE -H "Authorization: Bearer $CF_API_TOKEN" \
      "https://api.cloudflare.com/client/v4/zones/1b5bc02fdf61b6b989afde543f3f4134/dns_records/$ID"
    echo "Deleted ${name}.emsenhuber.net"
  fi
done

4b. Alte Tunnel deaktiviert lassen (nicht löschen!)

bf-mm, bf-nas, bf-pve erst löschen nach 1 Woche Betrieb ohne Vorfälle.

5. ABNAHME-KRITERIEN (pro Flip)

  • Tunnel bf-public zeigt 2+ Connections (ap1 + ap2)
  • Browser: Name → Access-Login → 200/302 vom Caddy
  • Caddy-Log zeigt eingehenden Request (pct exec 130 -- journalctl -u caddy -n 5)
  • Kein 530/1033 über 24h (alte Tunnel noch aktiv → Round-Robin wäre sichtbar)

6. ROLLBACK (je Flip)

CNAME zurück auf den alten Tunnel setzen:

curl -s -X PATCH -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.cloudflare.com/client/v4/zones/1b5bc02fdf61b6b989afde543f3f4134/dns_records/$CNAME_ID" \
  -d '{"content":"<alter-tunnel-id>.cfargotunnel.com","proxied":true}'

7. FALLEN

  • Kein Container ohne device-mode-Wechsel — container-Paket ist mit device-mode=home gesperrt. Physischer Zugang zwingend.
  • hAP Flash-Constraint: ~95 MB frei. cloudflared-Image ~30 MB → passt. Aber keine weiteren Container auf demselben AP.
  • NAND-Verschleiß: cloudflared schreibt kaum (Config in Cloudflare, kein Query-Log wie AGH). Trotzdem kein zweiter Container.
  • MGMT→INFRA forward nur TCP: Cloudflared baut QUIC (UDP 7844) zu CF. Das ist Egress (LAN→WAN), nicht INFRA — die Regel 27 greift nicht für Cloudflareds eigenen Tunnel-Traffic. Der geht über die defconf-Regel 2 (est/rel) oder über LAN→WAN (Regel 14). Kein zusätzlicher Firewall-Change nötig.