commit 131ad11b095dcc745701e69494f7f0a14b7c5dc9 Author: Carsten Rüthel Date: Wed Apr 1 23:41:02 2026 +0200 initialer Commit diff --git a/config/configuration.yml b/config/configuration.yml new file mode 100644 index 0000000..355c88e --- /dev/null +++ b/config/configuration.yml @@ -0,0 +1,37 @@ +server: + address: tcp://0.0.0.0:9091 + +authentication_backend: + file: + path: /config/users_database.yml + +access_control: + default_policy: deny + rules: + - domain: "*.fritz.box" + policy: one_factor + +session: + secret: "insecure_session_secret" + + cookies: + - domain: "fritz.box" + authelia_url: "https://auth.fritz.box" + default_redirection_url: "https://raspberrypi4.fritz.box" + +storage: + local: + path: /config/db.sqlite3 + + encryption_key: "insecure_encryption_key_123456" + +identity_validation: + reset_password: + jwt_secret: "insecure_jwt_secret_123456" + +notifier: + filesystem: + filename: /config/notification.txt + +ntp: + disable_startup_check: true \ No newline at end of file diff --git a/config/notification.txt b/config/notification.txt new file mode 100644 index 0000000..e69de29 diff --git a/config/users_database.yml b/config/users_database.yml new file mode 100644 index 0000000..d1d23d4 --- /dev/null +++ b/config/users_database.yml @@ -0,0 +1,6 @@ +users: + testuser: + displayname: "Testuser" + password: "$argon2id$v=19$m=65536,t=3,p=4$FWx99onWDmq2JdpYgrMpUA$+ksWqtIu2IOLw9vySFMPV1SdIO6CxDrGxzJYGHrXyfs" + groups: + - users \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0fa322e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3.8" + +services: + authelia: + image: authelia/authelia + container_name: authelia + volumes: + - ./config:/config + ports: + - 9091:9091 + restart: unless-stopped \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..a0d9c84 --- /dev/null +++ b/readme.md @@ -0,0 +1,521 @@ +# Aufgabenstellung + +ich betreibe verschiedene Dienste auf einen Raspberry Pi hinter einem Caddy, ein Teil der Dienste wird mit Portainer verwaltet. +Jetzt möchte ich noch ein nodeRED hinzufügen und quasi öffentlich zugänglich machen. Wie kann ich den Zugang auf ausgewählte Benutzer beschränken und auch die Dienste nur für diese zugänglich machen? + +Du hast im Prinzip zwei saubere Ebenen, auf denen du Zugriff beschränken kannst: + +1. **Reverse Proxy (Caddy) → zentrale Zugangskontrolle** +2. **Applikation selbst (Node-RED, Portainer etc.) → zusätzliche Absicherung** + +Die robuste Lösung kombiniert beide. + +--- + +# 🔐 1. Zugriff zentral über Caddy absichern (empfohlen) + +Da du bereits **Caddy** nutzt, ist das der beste Ort für Authentifizierung. + +## Option A: Basic Auth (einfach & effektiv) + +Beispiel für deine Caddyfile: + +```caddy +nodered.example.com { + reverse_proxy localhost:1880 + + basicauth { + user1 JDJhJDE0JHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHg + } +} +``` + +Hash erzeugen mit: + +```bash +caddy hash-password +``` + +👉 Vorteil: + +* Schnell eingerichtet +* Schützt ALLE dahinterliegenden Dienste sofort + +👉 Nachteil: + +* Nur Benutzer/Passwort, kein Feingranularität + +--- + +## Option B: Forward Auth (professionell / skalierbar) + +Hier lagerst du Authentifizierung an einen Dienst aus, z. B.: + +* Authelia +* Authentik + +Caddy-Konfiguration (Beispiel mit Forward Auth): + +```caddy +nodered.example.com { + route { + forward_auth authelia:9091 { + uri /api/verify?rd=https://login.example.com + copy_headers Remote-User Remote-Groups + } + reverse_proxy localhost:1880 + } +} +``` + +👉 Vorteil: + +* Benutzerverwaltung +* 2FA möglich +* Zugriff nach Gruppen steuerbar (z. B. nur „admin“ darf Node-RED) + +👉 Das ist die **beste Lösung**, wenn du mehrere Dienste öffentlich machst. + +--- + +# 🔐 2. Node-RED selbst absichern + +Zusätzlich solltest du **Node-RED** selbst schützen. + +In `settings.js`: + +```javascript +adminAuth: { + type: "credentials", + users: [{ + username: "admin", + password: "$2b$08$hash...", + permissions: "*" + }] +} +``` + +Passwort-Hash erzeugen mit: + +```bash +node-red admin hash-pw +``` + +👉 Wichtig: + +* Das schützt den Editor (`/`) +* Nicht automatisch alle HTTP-In-Nodes! + +--- + +# 🔐 3. Zugriff auf Flows / APIs absichern + +Wenn du HTTP-Endpunkte in Node-RED nutzt: + +## Variante A: Token / API-Key im Flow prüfen + +Typischer Flow: + +* HTTP In +* Function (Token prüfen) +* HTTP Response + +## Variante B: Zugriff komplett über Caddy regeln + +👉 Besser: alle Endpoints durch den Proxy schützen + +--- + +# 🔐 4. Netzwerk-Ebene (sehr empfehlenswert) + +Zusätzlich: + +### Nur intern laufen lassen + +* Node-RED auf `localhost:1880` +* Kein direkter Port nach außen + +### Docker (falls über Portainer) + +Mit **Portainer**: + +* Kein `ports:` Mapping nach außen +* Nur über Caddy erreichbar + +--- + +# 🔐 5. Best Practice Architektur + +So sollte dein Setup aussehen: + +``` +Internet + ↓ +Caddy (TLS + Auth) + ↓ +[Authelia / Authentik] (optional, empfohlen) + ↓ +Node-RED / Portainer / andere Dienste + (nur intern erreichbar) +``` + +--- + +# 🔒 Konkrete Empfehlung für dich + +Wenn du „ausgewählte Benutzer“ willst: + +👉 **Minimal:** + +* Caddy + BasicAuth + +👉 **Sauber & zukunftssicher:** + +* Caddy + Authelia +* Gruppen definieren: + + * user → Zugriff auf Node-RED + * admin → Zugriff auf Portainer + +👉 **Zusätzlich:** + +* Node-RED adminAuth aktivieren + +--- + +# ⚠️ Häufige Fehler + +* ❌ Node-RED direkt ins Internet exposen +* ❌ Nur Node-RED Auth nutzen (leicht zu umgehen bei APIs) +* ❌ Ports in Docker offen lassen +* ❌ Kein HTTPS (Caddy löst das aber für dich) + +--- + +Wenn du willst, kann ich dir eine **konkrete Caddyfile + Authelia docker-compose** für dein Setup bauen (inkl. Portainer + Node-RED sauber getrennt). + +# Erkläre und zeige Beispiele für Authelia bzw. Authentik + +Ja — das ist problemlos möglich. **Authelia** läuft sauber unter Docker auf Windows und eignet sich gut zum Testen, bevor du es auf deinen Raspberry Pi bringst. + +Ich zeige dir eine **minimal lauffähige Testumgebung**, die du lokal aufsetzen kannst. + +--- + +# 🧰 Voraussetzungen + +* **Docker Desktop** installiert +* WSL2 aktiviert (Standard bei neueren Setups) + +--- + +# 🚀 1. Projektstruktur + +Erstelle einen Ordner, z. B.: + +```text +authelia-test/ +├── docker-compose.yml +└── config/ + ├── configuration.yml + └── users_database.yml +``` + +--- + +# 📦 2. docker-compose.yml + +```yaml +version: "3.8" + +services: + authelia: + image: authelia/authelia + container_name: authelia + volumes: + - ./config:/config + ports: + - 9091:9091 + restart: unless-stopped +``` + +👉 Danach starten mit: + +```bash +docker compose up -d +``` + +--- + +# ⚙️ 3. Minimal-Konfiguration + +## `config/configuration.yml` + +```yaml +server: + address: tcp://0.0.0.0:9091 + +authentication_backend: + file: + path: /config/users_database.yml + +access_control: + default_policy: deny + rules: + - domain: "localhost" + policy: one_factor + +session: + secret: "insecure_test_secret" + cookies: + - domain: "localhost" + authelia_url: "http://localhost:9091" + +storage: + local: + path: /config/db.sqlite3 + +notifier: + filesystem: + filename: /config/notification.txt +``` + +--- + +## 👤 `users_database.yml` + +```yaml +users: + testuser: + password: "$2y$05$replace_with_hash" + groups: + - users +``` + +--- + +# 🔑 4. Passwort erzeugen + +Im Terminal: + +```bash +docker run --rm authelia/authelia authelia crypto hash generate argon2 --password "MeinSicheresPasswort" +``` + +liefert +```bash +Digest: $argon2id$v=19$m=65536,t=3,p=4$c87AqKINtBkJ6ajQiIiz5A$e27srHc5hnPlT0unJyFoYNg6pTf2CxuLK4WqQMC8cYI +``` + +👉 Hash in die Datei einfügen, d.h. alles beginnend mit $argon... + +--- + +# 🌐 5. Test im Browser + +Öffne: + +```text +http://localhost:9091 +``` + +👉 Du solltest das Authelia-Login sehen + +--- + +# 🔄 Optional: Dummy-Service zum Absichern + +Wenn du das echte Verhalten testen willst, ergänze z. B.: + +```yaml +whoami: + image: traefik/whoami + container_name: whoami + ports: + - 8080:80 +``` + +Dann später mit Reverse Proxy kombinieren. + +--- + +# ⚠️ Wichtige Unterschiede zu deinem Pi-Setup + +Auf Windows fehlt dir erstmal: + +* ❌ echtes HTTPS (Caddy später!) +* ❌ echte Domains +* ❌ ForwardAuth Integration + +👉 Das hier ist nur zum **Verstehen & Testen der Auth-Logik** + +--- + +# 🧪 Typische Tests, die du machen kannst + +* Login funktioniert? +* Benutzer/Gruppen greifen? +* Zugriff verweigert bei falschem User? +* Config-Änderungen live nachvollziehen + +--- + +# 🧭 Fazit + +✔ Ja, ideal zum Einstieg +✔ Läuft stabil unter Docker Desktop +✔ Perfekt zum Experimentieren mit Policies + +👉 Für dein finales Setup (Pi + Caddy) musst du dann nur noch: + +* Domains anpassen +* ForwardAuth aktivieren + +--- + +Wenn du willst, kann ich dir als nächsten Schritt eine **1:1 übertragbare Konfiguration von Windows → Raspberry Pi** bauen, damit du nichts doppelt machen musst. + +# Erkläre Schritt 4 + +Schritt 4 ist zentral, weil **Authelia** **keine Klartext-Passwörter akzeptiert**. Stattdessen erwartet es **stark gehashte Passwörter (Argon2)** in der Benutzerdatei. + +Ich erkläre dir das präzise: + +--- + +# 🔐 Was passiert in Schritt 4? + +Du erzeugst einen **sicheren Passwort-Hash**, der dann in `users_database.yml` gespeichert wird. + +👉 Authelia vergleicht später: + +* eingegebenes Passwort +* mit diesem Hash + +**→ ohne das Passwort jemals im Klartext zu speichern** + +--- + +# ⚙️ Der Befehl im Detail + +```bash +docker run --rm authelia/authelia authelia crypto hash generate argon2 + +``` + +### Zerlegt: + +* `docker run --rm` + → startet temporär einen Container und löscht ihn danach wieder + +* `authelia/authelia` + → offizielles Image + +* `authelia crypto hash generate argon2` + → internes CLI-Tool von Authelia zur Hash-Erzeugung + +--- + +# 🧪 Ablauf beim Ausführen + +Nach dem Start wirst du interaktiv gefragt: + +```text +Enter password: +Confirm password: +``` + +👉 Du gibst dein gewünschtes Passwort ein (z. B. `meinGeheimesPasswort`) + +--- + +# 📦 Ergebnis + +Du bekommst eine Ausgabe wie: + +```text +$argon2id$v=19$m=65536,t=3,p=4$... +``` + +Das ist dein **Hash**. + +--- + +# 🧾 Verwendung in `users_database.yml` + +Vorher: + +```yaml +testuser: + password: "$2y$05$replace_with_hash" +``` + +Nachher: + +```yaml +testuser: + password: "$argon2id$v=19$m=65536,t=3,p=4$..." +``` + +👉 Wichtig: + +* **komplette Zeichenkette übernehmen** +* in **Anführungszeichen lassen** + +--- + +# 🔍 Warum Argon2? + +Argon2 ist: + +* resistent gegen GPU-Angriffe +* speicherintensiv (Memory-hard) +* aktueller Stand der Technik + +👉 besser als: + +* MD5 ❌ +* SHA1 ❌ +* sogar bcrypt (in vielen Fällen) ⚠️ + +--- + +# ⚠️ Typische Fehler + +* ❌ Hash abgeschnitten +* ❌ Anführungszeichen vergessen +* ❌ Windows fügt Zeilenumbruch ein +* ❌ falscher Algorithmus + +--- + +# 🔁 Nach Änderung + +Wenn du den Hash eingetragen hast: + +```bash +docker compose restart authelia +``` + +--- + +# 🧭 Kurz gesagt + +Schritt 4 ist nichts anderes als: + +👉 „Erzeuge eine sichere, nicht rückrechenbare Repräsentation deines Passworts“ + +Damit: + +* deine Credentials sicher bleiben +* Authelia korrekt authentifizieren kann + +--- + +Wenn du möchtest, kann ich dir auch zeigen: +👉 wie du mehrere User + Gruppen sauber strukturierst (für Node-RED vs. Portainer Zugriff) + + +# Tatsächliche Werte: + + docker run --rm authelia/authelia authelia crypto hash generate argon2 --password "FooBarYou#2026" \ No newline at end of file