# 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. ## 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) ```bash # 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. ```bash # 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 ```bash # 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). ```bash 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: ```bash 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":".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.**