my_voice_assistant_v2/deploy/README.md
Dieter Schlüter 76df695111 feat(web): Remote-Web-UI mit Mikrofon + Forward-Auth (YunoHost-SSO)
- Minimale Web-UI (app/web/, vanilla, same-origin -> kein CORS): Text-Prompt +
  Mikrofon-Button (Aufnahme im Browser -> /ws/voice -> Antwort wird vorgelesen),
  Token-Streaming, PCM-Wiedergabe, Identitaet/Logout/Admin im Menue
- Forward-/Trusted-Header-Auth (app/auth.py): Identitaet aus SSO-Header, nur von
  TRUSTED_PROXY_IPS akzeptiert; sonst Token/Anonymous-Fallback. Auto-Provisioning
  via store.get_or_create_user_by_external_id (+ external_id-Spalte/Migration)
- /api/me um is_admin + sso_logout_url erweitert; GET /api/admin/users (Liste) und
  GET /api/admin/request-headers (SSO-Header-Discovery), Admin-gated
- StaticFiles-Mount; Config: TRUSTED_AUTH_HEADER/_PROXY_IPS, ADMIN_USERS, SSO_LOGOUT_URL
- WS-Auth liest Identitaet aus dem Handshake-Header
- Deploy: nginx-Vorlage (WS-Upgrade!) + deploy/README.md (HTTPS/SSO/Firewall/Discovery)
- Tests: Forward-Auth (Provisioning, Admin-Flag, Proxy-IP-Trust, 401/403, Static)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 04:37:16 +02:00

53 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Remote-Betrieb über YunoHost (assistent.linix.de)
Web-UI + Mikrofon vom Handy/Browser, abgesichert per HTTPS und YunoHost-SSO.
Topologie: `https://assistent.linix.de` → nginx@YunoHost (TLS, SSO) → über LAN →
`http://<GPU-Box>:8003` (Gateway). Der interne LAN-Hop ist unverschlüsselt
(vertrautes LAN, wie bei Ollama).
> **Warum HTTPS Pflicht ist:** Browser geben das Mikrofon (`getUserMedia`) nur in
> einem „secure context" frei also HTTPS oder `http://localhost`. Über einfaches
> `http://` vom Handy gibt es **kein** Mikrofon.
## 1. Gateway auf der GPU-Box
`deploy/voice-assistant.env.example``/etc/voice-assistant/voice-assistant.env` anpassen:
- `HOST` = **LAN-IP** der GPU-Box (nicht `0.0.0.0`), `PORT=8003`
- `AUTH_ENABLED=true`
- `TRUSTED_AUTH_HEADER` (nach Discovery, s. u.), `TRUSTED_PROXY_IPS` = LAN-IP von linix.de
- `ADMIN_USERS=atoor,dieterschlueter,dschlueter`, `SSO_LOGOUT_URL=…`
> Kein `--forwarded-allow-ips` setzen: Das Identitäts-Vertrauen prüft die
> **direkte Quell-IP** (= der Proxy). Würde uvicorn den Client aus
> `X-Forwarded-For` überschreiben, schlüge der Proxy-IP-Check fehl.
## 2. Drei Sicherheits-Pflichten
1. **Bind:** Gateway nur an die LAN-IP (Schritt 1).
2. **Firewall:** Port 8003 der GPU-Box **nur** von der linix.de-IP erlauben, z. B.:
```
sudo ufw allow from <linix.de_LAN_IP> to any port 8003 proto tcp
sudo ufw deny 8003
```
3. **Header überschreiben:** nginx setzt den Identitäts-Header selbst; Client-Eingaben
werden verworfen (siehe nginx-Conf). App-seitig zusätzlich der Proxy-IP-Check.
## 3. nginx auf YunoHost
`deploy/assistent.linix.de.nginx.conf` als Vorlage → auf dem YunoHost-Server unter
`/etc/nginx/conf.d/assistent.linix.de.d/assistant.conf` ablegen, `GPU_BOX_LAN_IP`
eintragen, die `map $http_upgrade …` einmalig im http{}-Kontext anlegen, dann
`nginx -t && systemctl reload nginx`. Subdomain `assistent.linix.de` in YunoHost
anlegen (Let's Encrypt) und per SSO schützen (nur erlaubte Tester/Gruppe).
## 4. Discovery: richtigen Identitäts-Header bestimmen
Als Admin **hinter dem SSO** aufrufen:
```
https://assistent.linix.de/api/admin/request-headers
```
Dort den Header finden, der den eingeloggten SSO-Usernamen trägt (z. B. `X-Remote-User`,
`Remote-User`, `Auth-User` …). Diesen Namen in `TRUSTED_AUTH_HEADER` **und** in der
nginx-`proxy_set_header …`-Zeile eintragen, Gateway + nginx neu laden.
## 5. Test
- `https://assistent.linix.de/` lädt die UI, links „Angemeldet als <SSO-User>".
- Text-Chat funktioniert; **Mikrofon-Button** nimmt auf und spielt die Antwort ab.
- Admins (`ADMIN_USERS`) sehen den Admin-Bereich (Nutzerliste).