Dashboard-Auth: Hermes-eigene Auth nicht mehr Pflicht, Caddy reicht
Dashboard bindet seit dem Caddy-Umbau nur noch auf 127.0.0.1 -- Hermes' Auth-Gate engagiert sich laut eigener Fehlermeldung NUR bei einem 0.0.0.0-Bind, greift also gar nicht mehr. HERMES_DASHBOARD_PASSWORD_HASH ist damit optional statt Pflicht (kein docker-compose-Abbruch mehr bei leerem Wert), der dashboard: basic_auth-Block in config.yaml.example ist standardmaessig auskommentiert. Caddy (TLS + eigene Basic-Auth) bleibt die einzige im Normalbetrieb noetige Auth-Schicht. README/.env.example entsprechend entschlackt -- Hash-Erzeugen + Dollarzeichen-Escaping nur noch als Fallback dokumentiert, falls der Bind mal wieder auf 0.0.0.0 wandert.
This commit is contained in:
+20
-10
@@ -20,20 +20,28 @@ HERMES_GATEWAY_PORT=8447
|
||||
HERMES_UID=10000
|
||||
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):
|
||||
# NICHT MEHR NOETIG im Normalbetrieb (seit dem Caddy-Umbau, 19.07.2026 spaeter
|
||||
# Abend): das Dashboard bindet nur noch auf 127.0.0.1, Hermes' eigenes
|
||||
# Auth-Gate engagiert sich laut eigener Fehlermeldung NUR bei einem 0.0.0.0-
|
||||
# Bind. Caddy (siehe CADDY_BASIC_AUTH_HASH unten) macht die eigentliche
|
||||
# Absicherung nach aussen. Einfach leer lassen.
|
||||
#
|
||||
# Nur falls der Dashboard-Bind mal wieder auf 0.0.0.0 gestellt wird, ist ein
|
||||
# Wert hier noetig (sonst verweigert Hermes den Start hart mit "no auth
|
||||
# providers are registered") — dann zusaetzlich den dashboard:-Block in
|
||||
# hermes-agent-config/config.yaml.example (bzw. der echten config.yaml)
|
||||
# einkommentieren. HERMES_DASHBOARD_USER ist Klartext (frei waehlbar),
|
||||
# HERMES_DASHBOARD_PASSWORD_HASH ist NIEMALS das Klartext-Passwort, sondern
|
||||
# der Hash daraus. Erzeugen (einmalig, gegen den "hermes-agent"-Container,
|
||||
# NICHT "hermes-agent-dashboard" — der braucht den Hash schon zum Hochfahren,
|
||||
# Henne-Ei-Problem):
|
||||
# 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.
|
||||
#
|
||||
# ACHTUNG DOLLARZEICHEN-FALLE: der erzeugte Hash hat das Format
|
||||
# "pbkdf2:sha256:<n>$<salt>$<hash>" - also ZWEI rohe "$"-Zeichen drin.
|
||||
# Docker Compose interpretiert "$xyz" in .env-Werten selbst als
|
||||
# ACHTUNG DOLLARZEICHEN-FALLE falls Du's doch brauchst: der erzeugte Hash hat
|
||||
# das Format "pbkdf2:sha256:<n>$<salt>$<hash>" - also ZWEI rohe "$"-Zeichen
|
||||
# drin. Docker Compose interpretiert "$xyz" in .env-Werten selbst als
|
||||
# Variablen-Referenz und ersetzt nicht aufloesbare Teile stillschweigend
|
||||
# durch Leerstring (sichtbar als "WARN The "xyz" variable is not set"
|
||||
# beim "docker-compose up"). Ergebnis: ein verstuemmelter Hash, das
|
||||
@@ -44,6 +52,8 @@ HERMES_GID=10000
|
||||
# pbkdf2:sha256:260000$f2kwriK6aYVRG5$BRps7npu2Tzg...
|
||||
# wird
|
||||
# pbkdf2:sha256:260000$$f2kwriK6aYVRG5$$BRps7npu2Tzg...
|
||||
# Am schnellsten mit dem sed-Trick:
|
||||
# sed -i '/^HERMES_DASHBOARD_PASSWORD_HASH=/ s/\$/$$/g' .env
|
||||
HERMES_DASHBOARD_USER=admin
|
||||
HERMES_DASHBOARD_PASSWORD_HASH=
|
||||
|
||||
|
||||
@@ -83,75 +83,24 @@ 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. **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'))"
|
||||
```
|
||||
**ACHTUNG DOLLARZEICHEN-FALLE:** der Hash hat das Format
|
||||
`pbkdf2:sha256:<n>$<salt>$<hash>` — zwei rohe `$`-Zeichen drin. Docker
|
||||
Compose interpretiert `$xyz` in `.env`-Werten selbst als Variablen-
|
||||
Referenz und ersetzt nicht aufloesbare Teile stillschweigend durch
|
||||
Leerstring (sichtbar als `WARN The "xyz" variable is not set` beim
|
||||
`docker-compose up`). Ohne Escaping kommt im Container ein
|
||||
verstuemmelter Hash an und das Dashboard bleibt bei "no auth providers
|
||||
are registered" haengen, obwohl alles "richtig" eingetragen aussieht.
|
||||
**Jedes `$` im Hash durch `$$` ersetzen**, bevor Du ihn in `.env`
|
||||
eintraegst (z.B. `260000$abc$def` → `260000$$abc$$def`). Anfuehrungszeichen
|
||||
um den Wert helfen dabei NICHT — Compose expandiert `$` in `.env`-Werten
|
||||
unabhaengig davon ob sie gequotet sind.
|
||||
4. **Dashboard-Auth: NICHT mehr noetig, ueberspringen.** (Historie: war
|
||||
zwischenzeitlich Pflicht, solange `hermes-agent-dashboard` mit `--host
|
||||
0.0.0.0` lief — Hermes verweigert diesen Bind hart ohne registrierten
|
||||
Auth-Provider: `Refusing to bind dashboard to 0.0.0.0 — the auth gate
|
||||
engages on non-loopback binds, but no auth providers are registered`.
|
||||
Seit Schritt 5 unten (Caddy) bindet das Dashboard aber nur noch auf
|
||||
`127.0.0.1` — Hermes' Auth-Gate engagiert sich laut eigener Fehlermeldung
|
||||
NUR bei einem 0.0.0.0-Bind, hier greift's also gar nicht. Caddy macht die
|
||||
eigentliche Absicherung nach aussen. `HERMES_DASHBOARD_USER`/
|
||||
`_PASSWORD_HASH` in `.env` koennen leer bleiben, kein Hash-Erzeugen mehr
|
||||
noetig.)
|
||||
|
||||
Am einfachsten den Hash direkt per `sed` in der Zeile escapen, statt ihn
|
||||
von Hand nochmal abzutippen (verdoppelt NUR die `$` in genau dieser einen
|
||||
Zeile):
|
||||
```bash
|
||||
sed -i '/^HERMES_DASHBOARD_PASSWORD_HASH=/ s/\$/$$/g' .env
|
||||
```
|
||||
Zur Kontrolle, ob noch unverdoppelte `$` uebrig sind (sollte leer sein):
|
||||
```bash
|
||||
grep -o '\$[^$]' .env
|
||||
```
|
||||
|
||||
Output (den escapeten 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).
|
||||
|
||||
**WICHTIG, wenn Du Schritt 3 schon VOR dem 19.07.2026 gemacht hast:**
|
||||
Schritt 3 kopiert `config.yaml.example` nur EINMALIG nach
|
||||
`hermes-data/agent-home/config.yaml` — kein automatischer Re-Sync danach.
|
||||
Der `dashboard:`-Block wurde erst nachtraeglich in die `.example`-Datei
|
||||
ergaenzt, landet also NICHT von selbst in einer bereits existierenden
|
||||
`config.yaml`. Ohne ihn bleibt Hermes bei "no auth providers are
|
||||
registered" haengen, egal wie sauber `.env` escaped ist (weil Hermes den
|
||||
Block ja gar nicht sieht). Pruefen:
|
||||
```bash
|
||||
grep -A3 '^dashboard:' hermes-data/agent-home/config.yaml
|
||||
```
|
||||
Kommt nichts zurueck → Block manuell anhaengen:
|
||||
```bash
|
||||
cat >> hermes-data/agent-home/config.yaml <<'EOF'
|
||||
|
||||
dashboard:
|
||||
basic_auth:
|
||||
username: "${HERMES_DASHBOARD_USER}"
|
||||
password_hash: "${HERMES_DASHBOARD_PASSWORD_HASH}"
|
||||
EOF
|
||||
```
|
||||
Danach neu hochziehen: `docker compose up -d --build hermes-agent-dashboard`
|
||||
Nur falls Du den Dashboard-Bind mal wieder direkt auf `0.0.0.0` stellst
|
||||
(z.B. um ohne Caddy zu testen), brauchst Du das wieder — dann in
|
||||
`hermes-agent-config/config.yaml.example` (bzw. Deiner echten
|
||||
`config.yaml`) den auskommentierten `dashboard:`-Block reaktivieren und
|
||||
`HERMES_DASHBOARD_PASSWORD_HASH` in `.env` setzen (Anleitung dazu direkt
|
||||
im Kommentar über dem Block, inkl. Dollarzeichen-Escaping-Falle).
|
||||
|
||||
5. **TLS-Reverse-Proxy (Caddy) einrichten — macht Port 443 von aussen
|
||||
erreichbar, Dashboard bleibt intern auf `127.0.0.1`:**
|
||||
@@ -200,10 +149,10 @@ aussen — kein anderer Rechner kommt mehr direkt ran.
|
||||
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), `hermes-agent-dashboard` und
|
||||
`caddy`. Falls `HERMES_DASHBOARD_PASSWORD_HASH` oder `CADDY_BASIC_AUTH_HASH`
|
||||
noch leer sind: der jeweilige Service bricht beim Start ab, die anderen
|
||||
laufen trotzdem — Werte nachtragen, dann
|
||||
`docker compose up -d hermes-agent-dashboard caddy`.
|
||||
`caddy`. Falls `CADDY_BASIC_AUTH_HASH` noch leer ist: `caddy` bricht beim
|
||||
Start ab, die anderen laufen trotzdem — Wert nachtragen (Schritt 5b), dann
|
||||
`docker compose up -d caddy`. `HERMES_DASHBOARD_PASSWORD_HASH` darf leer
|
||||
bleiben (siehe Schritt 4).
|
||||
|
||||
7. **Einmalig Claude-CLI-Login** (oeffnet Browser-OAuth mit deiner Claude-Max-Subscription):
|
||||
```bash
|
||||
|
||||
+13
-10
@@ -187,22 +187,25 @@ services:
|
||||
environment:
|
||||
- HERMES_UID=${HERMES_UID:-10000}
|
||||
- HERMES_GID=${HERMES_GID:-10000}
|
||||
# Pflicht seit 19.07.2026: Hermes verweigert den 0.0.0.0-Bind mit hartem
|
||||
# Exit, wenn kein Auth-Provider registriert ist ("Refusing to bind
|
||||
# dashboard to 0.0.0.0 — ... no auth providers are registered"). Diese
|
||||
# beiden Werte fuettern den dashboard.basic_auth-Block in
|
||||
# hermes-agent-config/config.yaml.example (dort auch die Anleitung zum
|
||||
# Hash-Erzeugen).
|
||||
# NICHT MEHR PFLICHT seit dem Caddy-Umbau (19.07.2026, spaeter Abend):
|
||||
# Hermes' eigenes Auth-Gate "engagiert sich" laut seiner eigenen
|
||||
# Fehlermeldung NUR bei einem 0.0.0.0-Bind ("the auth gate engages on
|
||||
# non-loopback binds"). Der Service unten bindet per `command:` auf
|
||||
# 127.0.0.1 — das Gate greift also gar nicht, Caddy (siehe unten) macht
|
||||
# die eigentliche Absicherung nach aussen (TLS + eigene Basic-Auth).
|
||||
# HERMES_DASHBOARD_PASSWORD_HASH ist daher optional: leer lassen ist ok,
|
||||
# kein Hash-Erzeugen mehr noetig fuer den Normalbetrieb. Nur falls der
|
||||
# Dashboard-Bind mal wieder auf 0.0.0.0 wandert, braucht's wieder einen
|
||||
# Wert (siehe .env.example fuer die Erzeugung).
|
||||
- HERMES_DASHBOARD_USER=${HERMES_DASHBOARD_USER:-admin}
|
||||
- HERMES_DASHBOARD_PASSWORD_HASH=${HERMES_DASHBOARD_PASSWORD_HASH:?HERMES_DASHBOARD_PASSWORD_HASH muss in .env gesetzt sein - siehe .env.example. Ohne Auth-Provider verweigert Hermes den 0.0.0.0-Bind komplett.}
|
||||
- HERMES_DASHBOARD_PASSWORD_HASH=${HERMES_DASHBOARD_PASSWORD_HASH:-}
|
||||
# Kurskorrektur 19.07.2026, spaeter Abend: Stefan wollte erst 0.0.0.0
|
||||
# (SSH-Tunnel machte mit SSL Probleme), jetzt aber die richtige Loesung:
|
||||
# Dashboard bleibt auf 127.0.0.1 (Hermes' eigenes Auth-Gate verlangt dann
|
||||
# gar keinen registrierten Provider mehr, siehe Fehlermeldung "the auth
|
||||
# gate engages on non-loopback binds") und der Caddy-Reverse-Proxy unten
|
||||
# macht TLS + Basic-Auth auf Port 443 nach aussen. HERMES_DASHBOARD_USER/
|
||||
# _PASSWORD_HASH bleiben trotzdem gesetzt (schadet nicht, falls der Bind
|
||||
# doch mal wieder auf 0.0.0.0 wandert).
|
||||
# macht TLS + Basic-Auth auf Port 443 nach aussen. Das ist die einzige
|
||||
# Auth-Schicht die im Normalbetrieb wirklich noetig ist.
|
||||
command: ["dashboard", "--host", "127.0.0.1", "--no-open"]
|
||||
|
||||
# ─── Caddy (TLS-Reverse-Proxy + Basic-Auth vor dem Dashboard) ──────────
|
||||
|
||||
@@ -32,26 +32,27 @@ model:
|
||||
# (den Hermes intern nutzt) setzt den Header automatisch aus diesem Feld.
|
||||
api_key: "${HERMES_GATEWAY_TOKEN}"
|
||||
|
||||
# ─── Dashboard-Auth ─────────────────────────────────────────────────────
|
||||
# Seit 19.07.2026 Pflicht: Hermes verweigert den Bind des Dashboards auf
|
||||
# 0.0.0.0 komplett, 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 Block bindet's nur
|
||||
# noch auf 127.0.0.1 (Tunnel), egal was im docker-compose `command:` steht.
|
||||
# ─── Dashboard-Auth (standardmaessig AUSKOMMENTIERT) ────────────────────
|
||||
# Hermes' eigenes Auth-Gate verweigert den Bind des Dashboards auf 0.0.0.0
|
||||
# komplett, 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") — greift aber laut derselben Meldung
|
||||
# NUR bei einem 0.0.0.0-Bind. Unser docker-compose.yml bindet das Dashboard
|
||||
# bewusst auf 127.0.0.1 und stellt es per Caddy-Reverse-Proxy (TLS + eigene
|
||||
# Basic-Auth) nach aussen bereit — das Gate hier engagiert sich dabei gar
|
||||
# nicht erst, dieser Block ist im Normalbetrieb also NICHT noetig.
|
||||
#
|
||||
# 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:
|
||||
# Nur falls Du den Dashboard-Bind mal direkt auf 0.0.0.0 stellst (z.B. ohne
|
||||
# Caddy testen): Block unten einkommentieren + HERMES_DASHBOARD_PASSWORD_HASH
|
||||
# in .env setzen. 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 den Hash schon zum
|
||||
# Hochfahren, Henne-Ei-Problem):
|
||||
# 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.
|
||||
#
|
||||
# ${HERMES_DASHBOARD_USER} / ${HERMES_DASHBOARD_PASSWORD_HASH} werden wie
|
||||
# oben von Hermes selbst aus den Container-Env-Vars expandiert.
|
||||
dashboard:
|
||||
basic_auth:
|
||||
username: "${HERMES_DASHBOARD_USER}"
|
||||
password_hash: "${HERMES_DASHBOARD_PASSWORD_HASH}"
|
||||
# dashboard:
|
||||
# basic_auth:
|
||||
# username: "${HERMES_DASHBOARD_USER}"
|
||||
# password_hash: "${HERMES_DASHBOARD_PASSWORD_HASH}"
|
||||
|
||||
Reference in New Issue
Block a user