README: fehlenden Dashboard-Auth-Setup-Schritt ergaenzen + Henne-Ei-Bug fixen
README dokumentierte den seit 19.07.2026 pflichtigen Dashboard-Auth-Block (HERMES_DASHBOARD_USER/PASSWORD_HASH, dashboard.basic_auth in config.yaml) noch gar nicht - neuer Setup-Schritt 4, Schritt 7/8 umnummeriert, Architektur- Diagramm und Sicherheitshinweis auf den 0.0.0.0-Dashboard-Stand gebracht. Nebenbei echten Bug gefunden: .env.example und config.yaml.example sagten, den Passwort-Hash per 'docker exec hermes-agent-dashboard' zu erzeugen - aber genau dieser Container startet ohne bereits gesetztes HERMES_DASHBOARD_PASSWORD_HASH gar nicht (docker-compose :?-Pflichtvar). Hash muss gegen 'hermes-agent' erzeugt werden, der teilt sich das Image ohne die Pflicht-Var.
This commit is contained in:
+5
-3
@@ -23,10 +23,12 @@ HERMES_GID=10000
|
||||
# Pflicht seit 19.07.2026, SOBALD hermes-agent-dashboard auf 0.0.0.0 bindet:
|
||||
# Hermes verweigert sonst den Start hart ("no auth providers are registered").
|
||||
# HERMES_DASHBOARD_USER ist Klartext (frei waehlbar), HERMES_DASHBOARD_PASSWORD_HASH
|
||||
# ist NIEMALS das Klartext-Passwort, sondern der Hash daraus. Erzeugen (einmalig,
|
||||
# im laufenden Dashboard-Container):
|
||||
# docker exec -it hermes-agent-dashboard python -c \
|
||||
# ist NIEMALS das Klartext-Passwort, sondern der Hash daraus. Erzeugen (einmalig):
|
||||
# docker exec -it hermes-agent python -c \
|
||||
# "from plugins.dashboard_auth.basic import hash_password; print(hash_password('DEIN-PASSWORT'))"
|
||||
# WICHTIG: gegen den "hermes-agent"-Container, NICHT "hermes-agent-dashboard" —
|
||||
# der braucht HERMES_DASHBOARD_PASSWORD_HASH schon zum Hochfahren (Henne-Ei-
|
||||
# Problem, siehe docker-compose.yml), "hermes-agent" laeuft auch ohne.
|
||||
# Den Output (nicht das Passwort selbst!) hier eintragen.
|
||||
HERMES_DASHBOARD_USER=admin
|
||||
HERMES_DASHBOARD_PASSWORD_HASH=
|
||||
|
||||
@@ -28,7 +28,9 @@ hermes-agent (Nous Research, network_mode: host)
|
||||
v
|
||||
Anthropic (ueber deine Claude-Max-Subscription)
|
||||
|
||||
hermes-agent-dashboard (127.0.0.1:9119, Hermes' eigenes Web-UI/Setup)
|
||||
hermes-agent-dashboard (0.0.0.0:9119, Hermes' eigenes Web-UI/Setup, per
|
||||
Basic-Auth gesichert seit 19.07.2026 — Stefans
|
||||
Entscheidung, siehe Sicherheitshinweis)
|
||||
```
|
||||
|
||||
Warum das Gateway trotzdem noch da ist, obwohl alles auf einer Maschine
|
||||
@@ -81,22 +83,48 @@ aussen — kein anderer Rechner kommt mehr direkt ran.
|
||||
beim Config-Laden aus den Container-Env-Vars expandiert, die kommen aus
|
||||
Deiner `.env`. Kein manuelles Ausfuellen noetig.
|
||||
|
||||
4. **Stack starten:**
|
||||
4. **Dashboard-Auth einrichten** (Pflicht seit 19.07.2026 — `hermes-agent-dashboard`
|
||||
laeuft mit `--host 0.0.0.0` und Hermes verweigert diesen Bind hart, wenn
|
||||
kein Auth-Provider registriert ist: `Refusing to bind dashboard to
|
||||
0.0.0.0 — the auth gate engages on non-loopback binds, but no auth
|
||||
providers are registered`. Ohne diesen Schritt kommt der Dashboard-
|
||||
Container beim naechsten Schritt gar nicht hoch):
|
||||
```bash
|
||||
# HERMES_DASHBOARD_USER in .env ist Klartext, HERMES_DASHBOARD_PASSWORD_HASH
|
||||
# ist NIEMALS das Klartext-Passwort, sondern der Hash daraus. Erzeugen kannst
|
||||
# Du den erst NACHDEM Schritt 5 unten (docker compose up -d) mindestens
|
||||
# hermes-agent hochgefahren hat -- gegen "hermes-agent", NICHT
|
||||
# "hermes-agent-dashboard" (der braucht den Hash schon zum Start, Henne-Ei):
|
||||
docker exec -it hermes-agent python -c \
|
||||
"from plugins.dashboard_auth.basic import hash_password; print(hash_password('DEIN-PASSWORT'))"
|
||||
```
|
||||
Output (den Hash, nicht das Passwort) in `.env` bei `HERMES_DASHBOARD_PASSWORD_HASH`
|
||||
eintragen, `HERMES_DASHBOARD_USER` nach Belieben setzen (Default `admin`).
|
||||
Der `dashboard.basic_auth`-Block dazu liegt schon fertig in
|
||||
`hermes-agent-config/config.yaml.example` (Platzhalter, die Hermes selbst
|
||||
aus den Container-Env-Vars expandiert — kein manuelles Ausfuellen noetig,
|
||||
siehe Schritt 3).
|
||||
|
||||
5. **Stack starten:**
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
Baut beim ersten Mal das Hermes-Image aus `hermes-agent-src` (dauert ein
|
||||
paar Minuten), startet dann `hermes-proxy`, `hermes-gateway`,
|
||||
`hermes-agent` (Gateway/Messaging-Prozess) und `hermes-agent-dashboard`.
|
||||
Falls `HERMES_DASHBOARD_PASSWORD_HASH` noch leer ist (Schritt 4 noch nicht
|
||||
gemacht): `hermes-agent-dashboard` bricht beim Start ab, die anderen drei
|
||||
Services laufen trotzdem — Hash nachtragen, dann
|
||||
`docker compose up -d hermes-agent-dashboard`.
|
||||
|
||||
5. **Einmalig Claude-CLI-Login** (oeffnet Browser-OAuth mit deiner Claude-Max-Subscription):
|
||||
6. **Einmalig Claude-CLI-Login** (oeffnet Browser-OAuth mit deiner Claude-Max-Subscription):
|
||||
```bash
|
||||
docker exec -it hermes-proxy claude
|
||||
```
|
||||
Danach liegen die Credentials persistent in `hermes-data/claude-config/`
|
||||
— ueberlebt Container-Restarts.
|
||||
|
||||
6. **Testen, dass der Proxy laeuft:**
|
||||
7. **Testen, dass der Proxy laeuft:**
|
||||
```bash
|
||||
curl -s http://127.0.0.1:${HERMES_GATEWAY_PORT:-8447}/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
@@ -105,15 +133,15 @@ aussen — kein anderer Rechner kommt mehr direkt ran.
|
||||
```
|
||||
Ohne oder mit falschem Bearer-Token gibt's `401 unauthorized`.
|
||||
|
||||
7. **Mit Hermes chatten:**
|
||||
8. **Mit Hermes chatten:**
|
||||
```bash
|
||||
docker exec -it hermes-agent hermes chat
|
||||
```
|
||||
oder das Dashboard per SSH-Tunnel oeffnen:
|
||||
```bash
|
||||
ssh -L 9119:localhost:9119 <diese-maschine>
|
||||
```
|
||||
dann im Browser `http://localhost:9119`.
|
||||
oder das Dashboard direkt im Browser oeffnen: `http://<diese-maschine>:9119`
|
||||
— bindet auf `0.0.0.0`, kein SSH-Tunnel mehr noetig, dafuer fragt es jetzt
|
||||
den Basic-Auth-Login aus Schritt 4 ab. Traffic ist weiterhin unverschluesseltes
|
||||
HTTP (siehe Sicherheitshinweis unten) — fuer mehr als "kurz testen" gehoert
|
||||
ein TLS-Reverse-Proxy davor.
|
||||
|
||||
## Mobiler Client (Android)?
|
||||
|
||||
@@ -132,13 +160,24 @@ Zwei GRUNDVERSCHIEDENE Richtungen, nicht verwechseln:
|
||||
|
||||
## Sicherheitshinweis
|
||||
|
||||
`hermes-gateway` bindet jetzt nur noch auf `127.0.0.1` — von aussen kommt
|
||||
niemand mehr ran, solange Du nicht selbst was aendertst (z.B. fuer den
|
||||
mobilen API-Server oben, oder falls Hermes doch mal auf eine zweite Maschine
|
||||
zieht). Wenn Du `HERMES_GATEWAY_PORT` oder `API_SERVER_HOST` doch mal nach
|
||||
aussen exposest: der Traffic ist unverschluesseltes HTTP, kein TLS. Nicht
|
||||
direkt ins offene Internet haengen — SSH-Tunnel, WireGuard/Tailscale oder
|
||||
einen TLS-Reverse-Proxy davorschalten.
|
||||
`hermes-gateway` bindet nur auf `127.0.0.1` — von aussen kommt niemand mehr
|
||||
ran, solange Du nicht selbst was aendertst (z.B. fuer den mobilen API-Server
|
||||
oben, oder falls Hermes doch mal auf eine zweite Maschine zieht).
|
||||
|
||||
`hermes-agent-dashboard` bindet seit 19.07.2026 bewusst auf `0.0.0.0` (Stefans
|
||||
Entscheidung — ein SSH-Tunnel machte mit dem SSL-Setup Probleme) und ist per
|
||||
Basic-Auth gesichert (siehe Setup-Schritt 4, Hermes verweigert den 0.0.0.0-Bind
|
||||
sonst ohnehin hart). Das ist Testzustand, kein Dauerbetrieb-Haerten: das
|
||||
Passwort geht als HTTP Basic-Auth unverschluesselt raus (kein TLS auf Port
|
||||
9119), Keys/Config/Sessions liegen dahinter offen. Fuer Dauerbetrieb gehoert
|
||||
ein TLS-Reverse-Proxy (Caddy/nginx) davor, der Basic-Auth + Zertifikat
|
||||
uebernimmt — Dashboard-Port dann wieder `127.0.0.1`, nur der Proxy von aussen
|
||||
erreichbar.
|
||||
|
||||
Generell gilt: wenn Du `HERMES_GATEWAY_PORT`, `API_SERVER_HOST` oder den
|
||||
Dashboard-Port doch mal direkt nach aussen exposest, ist der Traffic
|
||||
unverschluesseltes HTTP, kein TLS. Nicht direkt ins offene Internet haengen —
|
||||
SSH-Tunnel, WireGuard/Tailscale oder einen TLS-Reverse-Proxy davorschalten.
|
||||
|
||||
## Verzeichnisse (nicht committet, siehe .gitignore)
|
||||
|
||||
|
||||
@@ -39,9 +39,13 @@ model:
|
||||
# but no auth providers are registered"). Ohne diesen Block bindet's nur
|
||||
# noch auf 127.0.0.1 (Tunnel), egal was im docker-compose `command:` steht.
|
||||
#
|
||||
# Hash EINMALIG erzeugen (im laufenden Dashboard-Container, NICHT das
|
||||
# Klartext-Passwort committen oder in .env schreiben — nur den Hash):
|
||||
# docker exec -it hermes-agent-dashboard python -c \
|
||||
# Hash EINMALIG erzeugen (NICHT das Klartext-Passwort committen oder in .env
|
||||
# schreiben — nur den Hash). Gegen den "hermes-agent"-Container, NICHT
|
||||
# "hermes-agent-dashboard" — der braucht HERMES_DASHBOARD_PASSWORD_HASH schon
|
||||
# zum Hochfahren (Henne-Ei-Problem: ohne Hash kein Start, ohne laufenden
|
||||
# Container kein Hash). "hermes-agent" teilt sich dasselbe Image und laeuft
|
||||
# auch ohne den Wert:
|
||||
# docker exec -it hermes-agent python -c \
|
||||
# "from plugins.dashboard_auth.basic import hash_password; print(hash_password('DEIN-PASSWORT'))"
|
||||
# Ergebnis nach .env als HERMES_DASHBOARD_PASSWORD_HASH eintragen.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user