diff --git a/CHANGELOG.md b/CHANGELOG.md index b81d7e3..003dda6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/). ### Sicherheit +## [0.19.1] – 2026-09-19 + +### Hinzugefügt +- Anleitung für den netbird Reverse Proxy (Beta): Dienst anlegen, Zertifikat, private Dienste – samt Warnung, dass eine Anmeldehürde vor dem Dienst auch die Agents aussperrt (#030) + ## [0.19.0] – 2026-09-19 ### Hinzugefügt diff --git a/DEVLOG.md b/DEVLOG.md index 257f9da..7d750d2 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -2,7 +2,7 @@ ## Zeitübersicht -**Gesamt:** 15 h 03 min +**Gesamt:** 15 h 23 min | Issue | Zeit | |---|---| @@ -35,6 +35,7 @@ | #027 Rollen und Benutzerverwaltung | 1 h 20 min | | #028 Passkeys | 0 h 45 min | | #029 Einrichtungsdokumentation | 0 h 40 min | +| #030 netbird Reverse Proxy | 0 h 20 min | | Meilenstein | Zeit | |---|---| @@ -57,7 +58,7 @@ ## 2026-09-17 · Sitzung 1 · 19:36–laufend **Issue:** #001–#007 (Meilensteine v0.1.0 bis v0.4.0) -**Version:** 0.19.0 +**Version:** 0.19.1 ### Erledigt - Auftrag gelesen, Rückfragen gestellt @@ -162,6 +163,8 @@ - Einrichtungsdokumentation (#029): Beim Aufschreiben des OIDC-Wegs fielen zwei Fehler auf, die nur hinter einem Reverse Proxy auftreten – Rückkehradresse und Code-Einlösung nahmen die interne Adresse. Beides behoben - Erkenntnis: Eine Anleitung Schritt für Schritt aufzuschreiben findet Fehler, die kein Test findet, weil sie nur in einer bestimmten Betriebsform auftreten +- netbird Reverse Proxy (#030) in die Anleitung aufgenommen – Florians Hinweis, dass die Beta gut läuft. Beim Durchgehen der Möglichkeiten fiel der Fallstrick auf: Eine Anmeldehürde vor dem Dienst trifft auch `/api/agent` und legt alle Agents still + ### Nächster Schritt - #016 Benutzerhandbuch mit Screenshots, danach #017 Favicons und #019 CI-Pipeline - Für 1.0.0 fehlt noch: PMG (kein Host verfügbar) und der Fall „aktive Subscription auf PBS“ (#023) diff --git a/README.md b/README.md index e6af813..fc8a739 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ sie sich mit eigenen Tokens ausweisen. | Anleitung | Inhalt | |---|---| | [Inbetriebnahme](docs/betrieb/inbetriebnahme.md) | von null zum meldenden Host, in der richtigen Reihenfolge | -| [Reverse Proxy](docs/betrieb/reverse-proxy.md) | HTTPS mit nginx Proxy Manager, privates Netz mit netbird | +| [Reverse Proxy](docs/betrieb/reverse-proxy.md) | HTTPS mit nginx Proxy Manager, netbird Reverse Proxy (Beta) oder netbird pur | | [authentik](docs/betrieb/authentik.md) | Anmeldung über OIDC, samt Fehlerbildern | | [Sicherung](docs/betrieb/sicherung.md) | was gesichert wird – und wie man es zurückspielt | diff --git a/docs/betrieb/README.md b/docs/betrieb/README.md index 0c17ef9..c9b9c50 100644 --- a/docs/betrieb/README.md +++ b/docs/betrieb/README.md @@ -5,7 +5,7 @@ Anleitungen für alles, was rund um ProxLedger eingerichtet wird. | Dokument | Inhalt | |---|---| | [inbetriebnahme.md](inbetriebnahme.md) | Von null zum laufenden Dashboard – Docker oder LXC, erster Agent, erste Zuordnung | -| [reverse-proxy.md](reverse-proxy.md) | HTTPS mit nginx Proxy Manager, privates Netz mit netbird | +| [reverse-proxy.md](reverse-proxy.md) | HTTPS mit nginx Proxy Manager, netbird Reverse Proxy (Beta) oder netbird pur | | [authentik.md](authentik.md) | Anmeldung über OIDC | | [sicherung.md](sicherung.md) | Was gesichert werden muss und wie man es zurückspielt | diff --git a/docs/betrieb/reverse-proxy.md b/docs/betrieb/reverse-proxy.md index b179279..7044055 100644 --- a/docs/betrieb/reverse-proxy.md +++ b/docs/betrieb/reverse-proxy.md @@ -66,7 +66,77 @@ Danach einmal anmelden und darauf achten, dass die Adresszeile auf `proxledger.f --- -## Weg B: netbird (kein offener Port) +## Weg B: netbird Reverse Proxy (Beta) + +Seit v0.65 bringt netbird einen **eigenen Reverse Proxy** mit; v0.72 hat private Dienste und „Bring +Your Own Proxy“ ergänzt. Damit entfällt der nginx Proxy Manager vollständig: netbird übernimmt die +TLS-Terminierung und reicht den Verkehr durch das Mesh an den Ziel-Peer weiter – **ohne offenen Port +und ohne Firewall-Regel auf dem ProxLedger-Host**. + +Für ProxLedger ist das der bequemste Weg, weil er die beiden Dinge löst, an denen es sonst hakt: ein +gültiges Zertifikat (damit Passkeys funktionieren) und eine feste öffentliche Adresse. + +> **Beta.** Die Funktion ist als Beta gekennzeichnet. Sie unterstützt derzeit **kein Rosenpass**, und +> wer netbird selbst hostet, braucht **Traefik** als äußeren Proxy – nur der beherrscht das nötige +> TLS-Passthrough. + +### 1. Dienst anlegen + +Im netbird-Dashboard unter *Services → Reverse Proxy → Create*: + +| Reiter | Einstellung | +|---|---| +| **Details** | Mode `HTTP`; Subdomain `proxledger`, dazu eine Basis-Domäne; als Target den Peer mit ProxLedger, Protokoll `HTTP`, Port `3000` | +| **Authentication** | für ProxLedger **aus lassen** – Begründung unten | +| **Access Control** | nach Bedarf: IP-Bereiche, Länder, CrowdSec-Bewertung | +| **Settings** | *Host header forwarding* **an**, ebenso das Umschreiben von Weiterleitungen | + +Das Zertifikat besorgt netbird selbst über ACME (Let's Encrypt); alternativ lassen sich eigene +Zertifikate hinterlegen. + +**Host header forwarding ist nicht optional.** ProxLedger bildet Weiterleitungen, die OIDC-Rückkehr +und die `rpID` der Passkeys aus der öffentlichen Adresse. Kommt beim Dienst nur die interne Adresse +an, landet man nach der Anmeldung auf einer Adresse, die es im Browser nicht gibt. + +### 2. Adresse eintragen + +```bash +APP_URL="https://proxledger." +``` + +und dieselbe Adresse unter *Einstellungen → System* als **Adresse des Dashboards**. Danach neu starten. + +### 3. Warum die netbird-Anmeldung hier ausbleiben sollte + +netbird kann den Dienst zusätzlich absichern – per SSO über den eigenen Identitätsanbieter, per +Passwort, PIN oder Kopfzeile. Verlockend, aber für ProxLedger meist falsch: + +**Die Absicherung gilt für den ganzen Dienst, also auch für `/api/agent`.** Die Agents auf den +Proxmox-Hosts können sich dort nicht anmelden – sie weisen sich mit ihrem eigenen Token aus. Steht +eine SSO-Hürde davor, melden alle Hosts stumm ins Leere, bis der Zwischenspeicher voll ist. + +Zwei Wege, wenn die zusätzliche Hürde gewünscht ist: + +1. **Zwei Dienste anlegen:** einen für die Oberfläche mit SSO, einen zweiten (eigene Subdomain) ohne + Anmeldung für die Agents. Im Installations-Einzeiler dann die Agent-Adresse verwenden + (`--url https://agents.`). +2. **Privater Dienst:** netbird kann einen Dienst so schalten, dass er **nur** aus dem eigenen Netz und + nur für ausgewählte Gruppen erreichbar ist. Das ist die sauberste Lösung, wenn sowohl Arbeitsplätze + als auch alle Proxmox-Hosts ohnehin im netbird-Netz sind: kein offener Zugang, trotzdem gültiges + Zertifikat und damit Passkeys. + +### 4. Prüfen + +```bash +curl -fsS -o /dev/null -w "%{http_code}\n" https://proxledger./api/gesundheit +curl -fsS https://proxledger./install.sh | grep -m1 DASHBOARD_URL +``` + +Die zweite Zeile muss die **öffentliche** Adresse zeigen – das ist die, die später in jedem Agent steht. + +--- + +## Weg C: netbird ohne Reverse Proxy (kein offener Port) netbird spannt ein privates Netz über WireGuard. ProxLedger ist dann **nur** für Geräte im Netz erreichbar – kein Port im Internet, kein Zertifikat von außen nötig. @@ -107,7 +177,8 @@ untereinander sprechen. ### 4. HTTPS trotzdem einrichten netbird verschlüsselt den Transport – der Browser weiß davon aber nichts, und **Passkeys bleiben ohne -HTTPS gesperrt**. Zwei Möglichkeiten: +HTTPS gesperrt**. Am einfachsten ist hier der Reverse Proxy aus Weg B (auch als privater Dienst +nutzbar). Sonst bleiben zwei Möglichkeiten: - **Empfohlen:** Zusätzlich einen kleinen Reverse Proxy im netbird-Netz betreiben (nginx oder Caddy) mit einem Zertifikat für einen internen Namen, ausgestellt über DNS-01 – dafür muss nichts nach @@ -121,14 +192,24 @@ betreiben. In dem Fall `APP_URL` auf genau diese Adresse setzen – sonst setzt --- -## Beides zusammen +## Welcher Weg wofür -Der häufigste Aufbau in der Praxis: +| Lage | Empfehlung | +|---|---| +| Eigener Server, Domäne vorhanden, Kunden sollen zugreifen | **Weg A** – nginx Proxy Manager | +| Alles läuft ohnehin über netbird, Zertifikat gewünscht | **Weg B** – netbird Reverse Proxy, bei Bedarf als privater Dienst | +| Kein offener Zugang, keine Passkeys nötig | **Weg C** – netbird pur, `APP_URL` auf die netbird-Adresse | + +Weg B ist der kürzeste, wenn netbird ohnehin im Einsatz ist: ein Dienst, ein Zertifikat, kein +offener Port. Nur die Beta-Kennzeichnung sollte man im Hinterkopf behalten und nicht gleichzeitig auf +etwas anderes umstellen, damit bei einem Problem klar ist, woran es liegt. + +Der häufigste gemischte Aufbau: | Zugang | Weg | |---|---| -| Oberfläche für Mitarbeiter und Kunden | nginx Proxy Manager mit Let's-Encrypt-Zertifikat | -| Agents aus Kundennetzen | netbird, oder dieselbe öffentliche Adresse | +| Oberfläche für Mitarbeiter und Kunden | nginx Proxy Manager oder netbird Reverse Proxy | +| Agents aus Kundennetzen | netbird-Netz, oder dieselbe öffentliche Adresse | Wichtig ist nur, dass die Agents dieselbe Adresse erreichen, die im Installations-Einzeiler steht. Ändert sich die Adresse später, genügt der Einzeiler erneut auf jedem Host – die Zuordnung bleibt @@ -136,6 +217,9 @@ erhalten, weil sie an der Maschinenkennung hängt, nicht an der Adresse. ## Merkposten +0. **Keine Anmeldehürde vor `/api/agent`.** Egal welcher Proxy: Wer die Oberfläche zusätzlich absichert, + schließt damit auch die Agents aus – die weisen sich mit eigenem Token aus und können sich nirgends + anmelden. 1. **Adresse zuerst festlegen, dann Passkeys anlegen.** Ein Passkey gilt nur für die Domäne, unter der er registriert wurde. 2. **`APP_URL` und die Dashboard-Adresse müssen auf die öffentliche Adresse zeigen** – daraus entstehen diff --git a/docs/issues/030-netbird-reverse-proxy.md b/docs/issues/030-netbird-reverse-proxy.md new file mode 100644 index 0000000..1d8b76a --- /dev/null +++ b/docs/issues/030-netbird-reverse-proxy.md @@ -0,0 +1,29 @@ +# #030 netbird Reverse Proxy in die Anleitung +**Status:** erledigt +**Meilenstein:** v0.19.1 +**Labels:** doku +**Geschätzt:** 1 h **Tatsächlich:** 0 h 20 min + +## Ziel +netbird bringt seit v0.65 einen eigenen Reverse Proxy mit (Beta), v0.72 ergänzte private Dienste. +Damit entfällt ein zusätzlicher nginx – das gehört in die Anleitung, weil es der kürzeste Weg zu +HTTPS ist, wenn netbird ohnehin im Einsatz ist. + +## Aufgaben +- [x] Weg B: netbird Reverse Proxy – Dienst anlegen, Zertifikat, Einstellungen +- [x] Alter netbird-Abschnitt wird Weg C (ohne Proxy) +- [x] Entscheidungstabelle, welcher Weg wofür taugt +- [x] Beta-Einschränkungen benennen (kein Rosenpass; selbst gehostet nur mit Traefik) + +## Der wichtigste Hinweis +Die Absicherung eines Dienstes (SSO, Passwort, PIN) gilt für den **ganzen** Dienst – also auch für +`/api/agent`. Die Agents weisen sich mit eigenem Token aus und können sich nirgends anmelden; eine +SSO-Hürde davor lässt alle Hosts stumm ins Leere melden, bis der Zwischenspeicher voll ist. + +Zwei brauchbare Auswege stehen in der Anleitung: zwei Dienste (Oberfläche mit SSO, Agents ohne) oder +ein privater Dienst, der nur aus dem netbird-Netz erreichbar ist. + +## Quellen +- +- +- diff --git a/docs/issues/README.md b/docs/issues/README.md index 255cbd6..558e3a9 100644 --- a/docs/issues/README.md +++ b/docs/issues/README.md @@ -33,4 +33,5 @@ Details und Architektur: [../architektur.md](../architektur.md). Zeiten werden a | [#027](027-rollen-benutzerverwaltung.md) | Rollen und Benutzerverwaltung | erledigt | v0.18.0 | 6 h | 1 h 20 min | | [#028](028-passkeys.md) | Anmeldung mit Passkeys | erledigt | v0.18.0 | 4 h | 0 h 45 min | | [#029](029-betriebsdokumentation.md) | Einrichtungsdokumentation | erledigt | v0.19.0 | 3 h | 0 h 40 min | -| | **Summe** | | | **146 h** | **15 h 03 min** | +| [#030](030-netbird-reverse-proxy.md) | netbird Reverse Proxy in die Anleitung | erledigt | v0.19.1 | 1 h | 0 h 20 min | +| | **Summe** | | | **147 h** | **15 h 23 min** | diff --git a/package.json b/package.json index 4c446bd..00024b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "proxledger", - "version": "0.19.0", + "version": "0.19.1", "private": true, "scripts": { "dev": "next dev",