Internetzugriff: fehlenden Einrichtungs-Runbook nachgereicht, Pfad-Freigabeliste korrigiert
REVERSE_PROXY.md verwies auf INTERNET_ZUGRIFF_EINRICHTEN.md, das nie geschrieben wurde - jetzt vorhanden (Cloudflare-Konto, Nameserver-Umstellung, Cloudflared/NPM-Add-ons, Pfad-Freigabeliste eintragen, Prüfung). Dabei einen echten Fehler in der Freigabeliste gefunden: sie ging noch von einem companion-app-Web-Build unter /local/dm360/ aus (Planungsstand 2026-08-11) - das wurde nie gebaut, die App ist nativ/sideload-only. Ersetzt durch den tatsächlichen Fernbedarf: das OTA-Bündel unter /audi_dashboard_static/app/* (@capgo/capacitor-updater). Damit genügt auch ein einziger Hostname statt der ursprünglich erwogenen App-/API-Trennung. COMPANION_APP_ARCHITECTURE.md §5 und AGENTS.md entsprechend nachgezogen. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# Internetzugriff für DataMetric360 einrichten
|
||||
|
||||
Schritt-für-Schritt-Anleitung, damit die native Companion-App (iOS-Sideload, siehe
|
||||
`../COMPANION_APP_ARCHITECTURE.md` §1) von unterwegs (Mobilfunk, fremdes WLAN) funktioniert - nicht nur
|
||||
im Heimnetz/über Tailscale. Home Assistant selbst bleibt dabei durchgehend **lokal, ohne offenen Port**;
|
||||
nur ein eng begrenzter, pfad-gefilterter Ausschnitt der API wird über einen Cloudflare-Tunnel erreichbar
|
||||
gemacht. Architektur/Begründung: `../COMPANION_APP_ARCHITECTURE.md` §4. Die technische Pfad-Freigabeliste
|
||||
selbst, die in Schritt 6 unten eingetragen wird: [`REVERSE_PROXY.md`](REVERSE_PROXY.md).
|
||||
|
||||
**Wer was macht:** Kontoerstellung, Domain-/Nameserver-Verwaltung bei Cloudflare bzw. all-inkl und das
|
||||
Klicken durch die HA-Add-on-Oberfläche sind ausschließlich Sache des Fahrzeughalters selbst - dafür gibt
|
||||
es hier keine Automatisierung, nur die genauen Schritte. Alles, was als Datei/Konfiguration vorbereitet
|
||||
werden konnte, ist bereits fertig (`REVERSE_PROXY.md`s Regeln).
|
||||
|
||||
**Voraussetzungen, die bereits erfüllt sind** (nichts davon ist hier noch zu tun):
|
||||
- `datametric360.app` ist bei all-inkl registriert (siehe `../COMPANION_APP_ARCHITECTURE.md` §5 Punkt 4)
|
||||
- eigens dafür, ohne Webseite/Postfach darauf.
|
||||
- Die companion-app spricht bereits ausschließlich REST/WebSocket gegen eine konfigurierbare
|
||||
"Server-Adresse" (kein `hass`-Objekt, kein fest verdrahteter Hostname) - dieser Schritt ändert nur,
|
||||
*welche* Adresse dort später eingetragen wird, nicht die App selbst.
|
||||
|
||||
---
|
||||
|
||||
## 1. Cloudflare-Konto anlegen, Domain hinzufügen
|
||||
|
||||
1. Auf [cloudflare.com](https://cloudflare.com) ein (kostenloses) Konto anlegen.
|
||||
2. Im Dashboard *Add a Site* → `datametric360.app` eingeben.
|
||||
3. Plan **Free** wählen - reicht vollständig aus (Tunnel und DNS sind im Free-Plan enthalten, nur das
|
||||
"partial/CNAME setup" ohne Nameserver-Wechsel wäre Business-only, siehe Schritt 2).
|
||||
4. Cloudflare scannt bestehende DNS-Einträge der Domain und schlägt zwei Nameserver vor (z. B.
|
||||
`xxx.ns.cloudflare.com`, `yyy.ns.cloudflare.com`) - **notieren**, die werden in Schritt 2 gebraucht.
|
||||
|
||||
## 2. Nameserver bei all-inkl auf Cloudflare umstellen
|
||||
|
||||
**Das ist der eigentliche Knackpunkt** - erst danach kann der Tunnel überhaupt einen Hostnamen
|
||||
veröffentlichen.
|
||||
|
||||
1. Bei all-inkl (KAS-Verwaltung) einloggen → *Domains* → `datametric360.app` → Nameserver-Einstellungen.
|
||||
2. Von all-inkls eigenen Nameservern auf die beiden von Cloudflare vorgeschlagenen (Schritt 1.4)
|
||||
umstellen - das ist ein **"Full setup"**: die komplette DNS-Verwaltung der Domain wandert zu
|
||||
Cloudflare, nicht nur ein einzelner Eintrag. Das ist hier folgenlos, weil auf dieser Domain nichts
|
||||
anderes liegt (keine Webseite, kein Postfach) - siehe die Einschränkung in
|
||||
`../COMPANION_APP_ARCHITECTURE.md` §5 Punkt 4, warum die Domain extra dafür angelegt wurde.
|
||||
3. Umstellung kann laut Cloudflare bis zu 24 Stunden dauern (meist deutlich schneller). Status im
|
||||
Cloudflare-Dashboard prüfen - die Domain wechselt dort von "Pending Nameserver Update" auf "Active".
|
||||
4. Erst wenn "Active" angezeigt wird, mit Schritt 3 weitermachen (ein Tunnel-Hostname lässt sich vorher
|
||||
zwar anlegen, aber die DNS-Auflösung funktioniert erst danach).
|
||||
|
||||
## 3. Cloudflared-Add-on installieren und Tunnel einrichten
|
||||
|
||||
1. In Home Assistant: *Einstellungen → Add-ons → Add-on Store* → nach "Cloudflared" suchen, installieren.
|
||||
(Offizielles Home Assistant Community Add-on - nicht die eigenständige `cloudflared`-CLI von Hand
|
||||
einrichten.)
|
||||
2. Im Cloudflare-Dashboard: *Zero Trust → Networks → Tunnels* → *Create a tunnel* → Typ "Cloudflared" →
|
||||
Namen vergeben (z. B. `datametric360`).
|
||||
3. Cloudflare zeigt einen Tunnel-Token an - diesen im HA-Add-on unter *Konfiguration* eintragen (Feld
|
||||
`tunnel_token` bzw. je nach Add-on-Version über die angezeigte `cloudflared service install`-Zeile;
|
||||
das Add-on übernimmt das Token-Handling, kein manueller `cloudflared`-Aufruf per SSH nötig).
|
||||
4. Add-on starten. Im Cloudflare-Dashboard sollte der Tunnel danach als "Healthy"/verbunden angezeigt
|
||||
werden - das bestätigt die **ausgehende** Verbindung vom HAOS-Host zu Cloudflares Edge (kein
|
||||
Router-Port nötig, kein Port-Forward einzurichten).
|
||||
5. **Öffentlichen Hostnamen noch nicht auf Home Assistant selbst zeigen lassen** - das kommt erst in
|
||||
Schritt 5, nachdem der Reverse Proxy (Schritt 4) steht. Der Tunnel zeigt am Ende auf den Reverse
|
||||
Proxy, nie direkt auf Port 8123.
|
||||
|
||||
## 4. Nginx Proxy Manager installieren und Pfad-Freigabeliste eintragen
|
||||
|
||||
1. *Einstellungen → Add-ons → Add-on Store* → "Nginx Proxy Manager" installieren, starten.
|
||||
2. Die Weboberfläche des Add-ons öffnen (Standard-Login beim ersten Start: `[email protected]` /
|
||||
`changeme` - **sofort ändern**, siehe Add-on-Dokumentation).
|
||||
3. *Hosts → Proxy Hosts → Add Proxy Host*:
|
||||
- **Domain Names:** `datametric360.app`
|
||||
- **Forward Hostname/IP:** `homeassistant` (interner Name im Supervisor-Docker-Netz;
|
||||
alternativ `localhost`/`homeassistant.local.hass.io`, je nach Add-on-Version - im Zweifel im
|
||||
Add-on-Log nachsehen, mit welchem Namen sich `homeassistant:8123` von dort aus auflösen lässt)
|
||||
- **Forward Port:** `8123`
|
||||
- **SSL:** eigenes Cloudflare-Zertifikat reicht (der Tunnel terminiert TLS bereits an Cloudflares
|
||||
Edge) - hier kann "Force SSL" aktiv bleiben, ein eigenes Let's-Encrypt-Zertifikat ist nicht
|
||||
zwingend nötig, schadet aber auch nicht.
|
||||
4. Im Tab **Advanced** den kompletten `nginx`-Codeblock aus [`REVERSE_PROXY.md`](REVERSE_PROXY.md)
|
||||
(Abschnitt "Nginx Proxy Manager") **unverändert** einfügen - das ist die eigentliche
|
||||
Pfad-Freigabeliste: nur `/api/`, `/api/states/sensor.audi_dashboard_*`,
|
||||
`/api/services/audi_dashboard/*`, `/api/services/homeassistant/restart`, `/api/websocket`,
|
||||
`/audi_dashboard_static/app/*` und `/local/bilder/*.{webp,png,jpg,svg}` kommen durch - alles andere
|
||||
(`/lovelace`, `/config`, `/auth/*`, die HA-Oberfläche selbst) liefert `404`.
|
||||
5. Speichern.
|
||||
|
||||
## 5. Cloudflare-Tunnel auf den Reverse Proxy zeigen lassen
|
||||
|
||||
1. Zurück im Cloudflare-Dashboard: *Zero Trust → Networks → Tunnels* → den Tunnel aus Schritt 3 öffnen →
|
||||
*Public Hostname* → *Add a public hostname*.
|
||||
2. **Subdomain:** leer lassen (Apex-Domain `datametric360.app` selbst - kein Subdomain-Präfix, siehe
|
||||
"Ein einziger Hostname genügt" in `REVERSE_PROXY.md`).
|
||||
3. **Domain:** `datametric360.app`
|
||||
4. **Service Type:** `HTTPS` (nicht `HTTP` - Nginx Proxy Manager terminiert selbst wieder TLS).
|
||||
5. **URL:** die interne Adresse des Nginx-Proxy-Manager-Add-ons, üblicherweise der Add-on-Hostname im
|
||||
Supervisor-Netz plus dessen konfigurierten Port (im Add-on selbst unter *Info* nachsehen, welcher
|
||||
interne Port/Hostname das ist - **nicht** Port 8123, das wäre HA direkt).
|
||||
6. Speichern.
|
||||
|
||||
## 6. Prüfen
|
||||
|
||||
Von einem Netz **ohne** VPN/Tailscale (z. B. Mobilfunk, WLAN-Tethering vom Handy) die Prüfbefehle aus
|
||||
[`REVERSE_PROXY.md`](REVERSE_PROXY.md) (Abschnitt "Nach der Einrichtung prüfen") ausführen. Kurzfassung:
|
||||
`GET /api/` und `GET /api/states/sensor.audi_dashboard_profil` (mit gültigem Zugriffstoken) müssen
|
||||
funktionieren; `GET /auth/authorize` und `GET /api/config` müssen `404`/`403` liefern; ohne Token muss
|
||||
`/api/states/...` mit `401` statt `200` antworten. **Und:** Port 8123 darf von außen gar nicht antworten
|
||||
(z. B. über einen externen Port-Checker prüfen, oder `curl` gegen `http://<öffentliche-WAN-IP>:8123`,
|
||||
das muss ins Leere laufen).
|
||||
|
||||
## 7. Server-Adresse in der App eintragen
|
||||
|
||||
Auf jedem Gerät, auf dem die companion-app sideload-installiert ist: beim (erneuten) Einrichten
|
||||
`https://datametric360.app` als Server-Adresse eintragen, den bestehenden Zugriffstoken wiederverwenden
|
||||
oder einen neuen erzeugen. Ab hier funktionieren sowohl die normalen Datenabrufe als auch
|
||||
Fern-OTA-Updates (`AGENTS.md`, Abschnitt zu `@capgo/capacitor-updater`) über denselben Weg - lokal im
|
||||
Heimnetz weiterhin genauso wie zuvor, da HA selbst unverändert nur lokal erreichbar bleibt und die App
|
||||
ohnehin dieselbe Server-Adresse für beide Fälle verwendet.
|
||||
|
||||
## Was danach noch offen bleibt
|
||||
|
||||
- Ein Fehlschlag in Schritt 6 zuerst hier prüfen, in dieser Reihenfolge: Ist die Domain in Cloudflare
|
||||
"Active" (Schritt 2)? Zeigt der Tunnel "Healthy" (Schritt 3.4)? Antwortet der Nginx-Proxy-Manager-Host
|
||||
lokal überhaupt (`curl` von der HA-Konsole gegen die in Schritt 5.5 eingetragene interne Adresse)?
|
||||
Erst danach die Pfad-Regeln selbst (Schritt 4) noch einmal gegen `REVERSE_PROXY.md` vergleichen.
|
||||
- Ein Gerät verlieren/kompromittiert vermuten: den betroffenen Zugriffstoken im HA-Profil zurückziehen
|
||||
(*Profil → Sicherheit → Zugriffstoken (Long-Lived Access Tokens)*) - das sperrt sofort aus, unabhängig
|
||||
vom Tunnel/Reverse-Proxy.
|
||||
- Diese Anleitung deckt nur den Netzwerkweg ab. Für alles rund um Xcode-Signierung/Sideload der App
|
||||
selbst: `../COMPANION_APP_ARCHITECTURE.md` §1 ("Distribution: sideload only").
|
||||
@@ -15,9 +15,23 @@ Proxy, der ausschließlich die unten aufgeführten Pfade durchlässt.
|
||||
> Seit der Umstellung auf eine native Integration (2026-08-23, siehe `AGENTS.md` Abschnitt H) heißen
|
||||
> Entitäten `sensor.audi_dashboard_*` und Dienste `audi_dashboard.<name>` - keine doppelten Präfixe
|
||||
> mehr. Die Regeln unten sind auf den aktuellen Stand korrigiert und um zwei seither neu hinzugekommene
|
||||
> Bedarfe ergänzt (`homeassistant.restart` fürs Selbst-Update, `/local/dm360/*` für die App selbst -
|
||||
> beide fehlten in der alten Fassung ersatzlos, ohne sie hätte weder der Update-Neustart-Knopf noch die
|
||||
> ausgelieferte App über den Tunnel funktioniert).
|
||||
> Bedarfe ergänzt (`homeassistant.restart` fürs Selbst-Update, sowie das OTA-Bündel unter
|
||||
> `/audi_dashboard_static/app/*` - beide fehlten in der alten Fassung ersatzlos, ohne sie hätte weder
|
||||
> der Update-Neustart-Knopf noch ein OTA-Update über den Tunnel funktioniert).
|
||||
>
|
||||
> **Zweite Korrektur, selber Tag:** die erste Überarbeitung übernahm noch ungeprüft die alte Annahme
|
||||
> aus der frühen Planungsphase (2026-08-11), die App würde als eigener Web-Build unter
|
||||
> `/config/www/dm360/` bzw. `/local/dm360/` ausgeliefert. Das wurde nie gebaut - die Distributionsart
|
||||
> ist seit der Architekturentscheidung "sideload only" (siehe `COMPANION_APP_ARCHITECTURE.md` §1) eine
|
||||
> **native Capacitor-App**, direkt per Xcode aufs Gerät geladen, nicht über HA im Browser aufgerufen.
|
||||
> Ein `/local/dm360/*`-Pfad existiert auf dieser Instanz nicht und wird nie gebraucht. Was die native
|
||||
> App stattdessen tatsächlich extern erreichen muss, ist ihr eigener Oberflächen-Nachlieferweg (OTA,
|
||||
> `@capgo/capacitor-updater`, siehe `AGENTS.md` Abschnitt "Deployed-parity"-Unterabschnitt): das Bündel
|
||||
> liegt unter `/audi_dashboard_static/app/bundle.zip`, ausgeliefert von der Integration selbst
|
||||
> (`custom_components/audi_dashboard/frontend/app/`, `const.py`'s `BUENDEL_URL`) - dieselbe
|
||||
> `basisUrl`, die die App auch für ihre normalen API-Aufrufe verwendet (`ota.ts`'s
|
||||
> `buendelAnwenden()`), also derselbe Tunnel-Hostname, kein zweiter. Die Regel unten ist entsprechend
|
||||
> ersetzt, nicht nur umbenannt.
|
||||
|
||||
## Was die App wirklich braucht
|
||||
|
||||
@@ -31,7 +45,7 @@ nicht geschätzt - dort gibt es genau drei REST-Aufrufmuster plus WebSocket:
|
||||
| `POST` | `/api/services/audi_dashboard/*` | alle schreibenden Vorgänge (Fahrt/Tankvorgang anlegen/ändern, CSV-/Historien-Import, Update prüfen/installieren, ...) |
|
||||
| `POST` | `/api/services/homeassistant/restart` | genau ein Dienst außerhalb der eigenen Domain - der "Jetzt neu starten"-Knopf nach einem Integrations-Update (siehe `AGENTS.md` Abschnitt L) |
|
||||
| `GET` (Upgrade) | `/api/websocket` | Live-Aktualisierung |
|
||||
| `GET` | `/local/dm360/*` | die ausgelieferte App selbst (`companion-app`, `vite.config.ts`: `base: "./"`, Ziel `/config/www/dm360/`) - ohne diesen Pfad lädt die Seite gar nicht erst |
|
||||
| `GET` | `/audi_dashboard_static/app/*` | das OTA-Oberflächen-Bündel (`bundle.zip`) für die native App - ohne diesen Pfad findet ein Update aus der Ferne nicht statt (die App selbst läuft nativ auf dem Gerät, wird nicht über diesen Pfad "geladen") |
|
||||
| `GET` | `/local/bilder/*.{webp,png,jpg,svg}` | Fahrzeugfotos, die die App anzeigt |
|
||||
|
||||
Alles andere wird geblockt, insbesondere `/auth/*`, `/lovelace*`, `/config*`, `/api/config`,
|
||||
@@ -101,8 +115,9 @@ location = /api/websocket {
|
||||
include conf.d/include/proxy.conf;
|
||||
}
|
||||
|
||||
# Die App selbst (companion-app, ausgeliefert unter /config/www/dm360/).
|
||||
location ^~ /local/dm360/ {
|
||||
# Das OTA-Oberflächen-Bündel für die native App (siehe Hinweis oben - das ist
|
||||
# NICHT die App selbst, die läuft nativ; nur ihr nachladbares HTML/CSS/JS).
|
||||
location ^~ /audi_dashboard_static/app/ {
|
||||
limit_except GET { deny all; }
|
||||
proxy_pass http://homeassistant:8123;
|
||||
include conf.d/include/proxy.conf;
|
||||
@@ -121,11 +136,13 @@ location / {
|
||||
}
|
||||
```
|
||||
|
||||
Wird die App selbst unter derselben Adresse ausgeliefert (`/local/dm360/` auf demselben Hostnamen wie
|
||||
die Schnittstelle), braucht dieser Proxy-Host nur die Blöcke oben - kein separater Host nötig. Ein
|
||||
getrennter Hostname für die Schnittstelle (`api.datametric360.app` statt `datametric360.app`) ist
|
||||
trotzdem sauberer, siehe `COMPANION_APP_ARCHITECTURE.md` §5 Punkt 4: dann bleibt der `/local/dm360/`-Block
|
||||
auf dem App-Host, die übrigen Blöcke auf dem API-Host.
|
||||
**Ein einziger Hostname genügt.** Die frühere Überlegung, App und Schnittstelle auf zwei getrennte
|
||||
Hostnamen zu legen (`datametric360.app` für die App, `api.datametric360.app` für die Schnittstelle),
|
||||
stammte aus der Annahme, die App würde selbst als Web-Build unter einer eigenen Adresse ausgeliefert
|
||||
(siehe Korrektur-Hinweis oben) - das entfällt mit der nativen Distribution ersatzlos. Es gibt nur noch
|
||||
*eine* Adresse, die überhaupt gebraucht wird: die, die die App beim Einrichten als "Server-Adresse"
|
||||
bekommt, und über die sie sowohl die API-Aufrufe als auch das OTA-Bündel erreicht. Ein zweiter Hostname
|
||||
wäre zusätzlicher Aufwand ohne Gegenwert.
|
||||
|
||||
## Nach der Einrichtung prüfen
|
||||
|
||||
@@ -133,13 +150,15 @@ Von einem Netz ohne VPN, etwa über Mobilfunk (Hostnamen unten sind Platzhalter
|
||||
Einrichtung tatsächlich gewählt wurde):
|
||||
|
||||
```bash
|
||||
API=https://api.datametric360.app
|
||||
API=https://datametric360.app
|
||||
T=<Zugriffstoken>
|
||||
|
||||
# muss gehen
|
||||
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $T" "$API/api/"
|
||||
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $T" \
|
||||
"$API/api/states/sensor.audi_dashboard_profil"
|
||||
# kein Token nötig - statische Auslieferung, kein API-Aufruf
|
||||
curl -s -o /dev/null -w '%{http_code}\n' "$API/audi_dashboard_static/app/bundle.zip"
|
||||
|
||||
# muss 404 oder 403 liefern
|
||||
curl -s -o /dev/null -w '%{http_code}\n' "$API/auth/authorize"
|
||||
@@ -160,6 +179,5 @@ geordneten Ablauf - kurz zusammengefasst bleibt vor der ersten echten Nutzung di
|
||||
|
||||
- Cloudflare-Konto anlegen, `datametric360.app`-Zone hinzufügen
|
||||
- Nameserver von `datametric360.app` bei all-inkl auf Cloudflare umstellen („Full setup")
|
||||
- Cloudflared- und Nginx-Proxy-Manager-Add-ons installieren, Tunnel + öffentliche Hostnamen einrichten
|
||||
- Endgültige Hostnamen festlegen (App-Domain vs. API-Subdomain) und hier eintragen
|
||||
- companion-app-Web-Build nach `/config/www/dm360/` ausliefern
|
||||
- Cloudflared- und Nginx-Proxy-Manager-Add-ons installieren, Tunnel + öffentlichen Hostnamen einrichten
|
||||
- `https://datametric360.app` als Server-Adresse in der App eintragen (jedes Gerät, beim Einrichten)
|
||||
|
||||
Reference in New Issue
Block a user