{ "meta": { "title": "Proxmox-Dashboard-Authentifizierung — 2FA, API-Tokens, Benutzerprofil, Reverse-Proxy | ProxMenux Monitor", "description": "Zugriff und Schutz für ProxMenux Monitor: Ersteinrichtung, Passwort mit Anzeigename und Avatar, Profilseite, TOTP-2FA, langlebige API-Tokens, HTTPS, Beispiele für Nginx/Caddy/Traefik, Audit-Protokoll und optionale Fail2Ban-Jail.", "ogTitle": "Proxmox-Dashboard-Authentifizierung — 2FA, API-Tokens, Reverse-Proxy", "ogDescription": "ProxMenux Monitor mit Passwort, TOTP-2FA, langlebigen API-Tokens, HTTPS, Reverse-Proxy-Beispielen und optionaler Fail2Ban-Jail schützen.", "twitterTitle": "Proxmox Dashboard-Authentifizierung | ProxMenux Monitor", "twitterDescription": "Passwort + TOTP 2FA, API Token, HTTPS, Nginx/Caddy/Traefik Snippets und Audit Log." }, "header": { "title": "Zugriff und Authentifizierung", "description": "Dashboard-Zugriff, Ersteinrichtung und Schutzschichten: Passwort und TOTP, JWT-Sitzungen, langlebige API-Tokens, HTTPS, Reverse-Proxys, Secure Gateway und optionale Fail2Ban-Jail.", "section": "ProxMenux-Monitor" }, "intro": { "title": "Authentifizierung ist optional", "body": "Beim ersten Start zeigt das Dashboard den Dialog „Dashboard schützen?“ mit den Schaltflächen Ja, Passwort einrichten und Nein, ohne Schutz fortfahren. Bei der zweiten Option bleiben die API-Endpunkte über TCP 8008 offen. Das kann für ein isoliertes Labor-LAN ausreichen, ist in anderen Umgebungen jedoch gefährlich. Die Zwei-Faktor-Authentifizierung (2FA) ist nicht Teil dieser ersten Auswahl; sie wird nach dem Einrichten eines Passworts unter Sicherheit konfiguriert." }, "reaching": { "heading": "Dashboard öffnen", "intro": "ProxMenux Monitor lauscht auf 0.0.0.0:8008. Drei übliche Zugriffswege:", "outro": "Direktzugriff entspricht der Standard-systemd-Unit. Reverse-Proxy und Secure Gateway werden unten beschrieben. Das Vertrauen in Client-IPs aus X-Forwarded-For erfordert PROXMENUX_TRUST_PROXY=1 und einen von Ihnen kontrollierten Proxy. X-Forwarded-Proto oder X-Forwarded-Host allein aktivieren das Proxy-Vertrauen nicht. Auf den Ports 80/443 verwendet das Frontend relative /api/*-URLs; auf jedem anderen Port ruft es Port 8008 unter demselben Hostnamen auf." }, "firstLaunch": { "heading": "Ablauf beim ersten Start", "intro": "Beim ersten Öffnen ruft das Frontend GET /api/auth/status auf. Wurde die Authentifizierung noch nie eingerichtet (configured: false), erscheint „Dashboard schützen?“ mit zwei Optionen:", "imageAlt": "Ersteinrichtungsdialog „Dashboard schützen?“ mit „Ja, Passwort einrichten“ und „Nein, ohne Schutz fortfahren“", "imageCaption": "Authentifizierung beim ersten Start: Passwortschutz einrichten oder überspringen. Erscheint nach einer Neuinstallation oder nach „Authentifizierung deaktivieren“ in den Einstellungen erneut.", "headerButton": "Schaltfläche", "headerWhat": "Was passiert", "headerApi": "API-Aufruf", "rows": [ { "button": "Ja, Passwort einrichten", "what": "Öffnet ein Formular mit verpflichtendem Benutzernamen und Passwort sowie optionalem Anzeigenamen und Avatarbild. Aktiviert die Authentifizierung in auth.json mit enabled: true und gibt ein JWT zur Anmeldung zurück. Optionale Profilfelder werden durch weitere Aufrufe gespeichert, wie unten beschrieben.", "api": "POST /api/auth/setup" }, { "button": "Nein, fahren Sie ohne Schutz fort", "what": "Markiert declined: true in auth.json. Jeder API-Endpunkt ist öffentlich zugänglich, bis Sie Ihre Meinung über Einstellungen ändern.", "api": "POST /api/auth/skip" } ], "twofaCalloutTitle": "2FA wird später konfiguriert, nicht hier", "twofaCalloutBody": "Der erste Dialog entscheidet nur über den Passwortschutz. Zwei-Faktor-Authentifizierung (TOTP) richten Sie danach unter Sicherheit ein, sobald Sie mit Passwort angemeldet sind. Die vollständige Anleitung folgt weiter unten.", "createTitle": "Erstellen des ersten Benutzers", "createIntro": "Mit Ja, Passwort einrichten öffnen Sie ein Formular für Konto und optionales Profil. So erscheint der Avatar direkt nach dem Speichern im Kopfbereich. Die Felder:", "headerField": "Feld", "headerRequired": "Erforderlich", "headerNotes": "Notizen", "fieldRows": [ { "field": "Benutzername", "required": "Ja", "notes": "Kennung zur Anmeldung. Später nicht über die Oberfläche änderbar; dafür muss auth.json direkt bearbeitet werden." }, { "field": "Passwort", "required": "Ja", "notes": "Mindestens 10 Zeichen aus mindestens 3 von 4 Kategorien: Kleinbuchstaben, Großbuchstaben, Ziffern und Symbole. Offensichtliche Passwörter wie password, 12345678 oder proxmenux werden abgelehnt. Dieselben Regeln gelten serverseitig und lassen sich nicht per curl umgehen." }, { "field": "Anzeigename", "required": "Nein", "notes": "Name im Menü des Kopfbereichs und auf der Profilseite. Ohne Angabe wird der Benutzername verwendet. Später über Avatar → Profil ansehen änderbar." }, { "field": "Avatarbild", "required": "Nein", "notes": "PNG, JPEG, WebP oder GIF bis 2 MB. Erscheint als Kreis im Kopfbereich und im Profil. Ohne Bild wird der erste Buchstabe des Anzeigenamens oder Benutzernamens auf farbigem Hintergrund gezeigt. Im Profil können Sie das Bild später hochladen, ersetzen oder entfernen." } ], "createImageAlt": "Formular mit verpflichtendem Benutzernamen und Passwort sowie optionalem Anzeigenamen und Avatar-Upload", "createImageCaption": "Formular zur Ersteinrichtung. Anzeigename und Avatar sind optional. Ohne Angaben wird das Konto angelegt und im Kopfbereich ein Kreis mit einem Buchstaben angezeigt.", "saveCalloutTitle": "Einmal speichern, bis zu drei API-Aufrufe", "saveCalloutBody": "Zuerst sendet das Formular POST /api/auth/setup mit Benutzername und Passwort. Mit dem neuen JWT folgen gegebenenfalls PUT /api/auth/profile für den Anzeigenamen und POST /api/auth/profile/avatar für das Bild. Fehler beim Profil verhindern die Kontoerstellung nicht; das Profil lässt sich später ergänzen.", "avatarTitle": "Avatar-Menü und Profilseite", "avatarBody1": "Nach der Einrichtung erscheint oben rechts neben dem Designschalter ein Avatar. Sein Menü führt zum Profil und zur Sicherheit und bietet Abmelden. Eine Abmeldung ist auch unter Sicherheit möglich.", "avatarBody2": "Die Profilseite zeigt eine Avatarvorschau, den schreibgeschützten Benutzernamen und den bearbeitbaren Anzeigenamen. Avatar-Uploads, Ersetzungen und Löschungen erfolgen atomar; der Avatar im Kopfbereich aktualisiert sich nach Erfolg ohne Neuladen. Ersteinrichtung und Profilseite verwenden die nachfolgend beschriebenen Endpunkte.", "profileImageAlt": "Profilseite mit Avatarvorschau, Schaltflächen zum Hochladen, Ersetzen und Entfernen, schreibgeschütztem Benutzernamen und bearbeitbarem Anzeigenamen", "profileImageCaption": "Die dedizierte Profilseite. Benutzername ist schreibgeschützt; Anzeigename und Avatar können von hier aus bearbeitet werden, ohne die Registerkarte Sicherheit zu berühren.", "headerEndpoint": "Endpunkt", "headerEpWhat": "Was es tut", "endpointRows": [ { "endpoint": "GET /api/auth/profile", "what": "Gibt den aktuellen Benutzernamen, den Anzeigenamen und ob ein Avatar gesetzt ist (has_avatar, avatar_mtime) zurück." }, { "endpoint": "PUT /api/auth/profile", "what": "Aktualisiert den Anzeigenamen. Anfrageinhalt: '{' \"display_name\": \"...\" '}'." }, { "endpoint": "GET /api/auth/profile/avatar", "what": "Gibt das Avatarbild als PNG / JPEG / WebP / GIF mit passendem Inhaltstyp zurück. Benötigt den Bearer-Header; das Frontend lädt einen Blob und erzeugt daraus eine lokale Objekt-URL." }, { "endpoint": "POST /api/auth/profile/avatar", "what": "Ladet einen neuen Avatar hoch (max 2 MB). Der Inhaltstyp muss der Datei entsprechen. Der alte Avatar wird atomar ersetzt." }, { "endpoint": "DELETE /api/auth/profile/avatar", "what": "Entfernt den Avatar. Im Kopfbereich erscheint wieder eine Initiale in einem farbigen Kreis." } ], "reversibleTitle": "Der Verzicht auf Schutz lässt sich später ändern", "reversibleBody": "Nach Nein, ohne Schutz fortfahren erscheint der Dialog nicht erneut. Aktivieren Sie die Authentifizierung unter Sicherheit oder bearbeiten Sie /root/.config/proxmenux-monitor/auth.json, entfernen Sie das Flag declined und starten Sie den Dienst neu." }, "password": { "heading": "Passwort-Authentifizierung", "intro": "Nach der Einrichtung benötigen geschützte API-Aufrufe ein JWT in Authorization: Bearer <token>:", "items": [ "Sitzungstoken zur Anmeldung: 24 Stunden gültig. Ausgestellt über POST /api/auth/login.", "API-Token für Integrationen: 365 Tage gültig. Ausgestellt über POST /api/auth/generate-api-token. Weitere Informationen im nächsten Abschnitt." ], "loginImageAlt": "Anmeldebildschirm nach der Konfiguration der Authentifizierung angezeigt - Benutzername und Passwortfelder", "loginImageCaption": "Sobald die Authentifizierung konfiguriert ist, beginnt hier jeder Besuch des Dashboards. Wenn 2FA aktiviert ist, fragt der Bildschirm in einem zweiten Schritt nach dem akzeptierten Passwort nach dem 6-stelligen Code.", "loginFlowTitle": "Loginfluss", "twofaIntro": "Mit 2FA antwortet derselbe Aufruf zunächst mit requires_totp: true. Senden Sie ihn erneut mit dem sechsstelligen Code:", "publicTitle": "Öffentliche Endpunkte (ohne Token)", "publicIntro": "Anmeldung, Authentifizierungsstatus, Ersteinrichtung und der leichte Endpunkt /api/system-info sind öffentlich:", "publicItems": [ "/api/auth/login und /api/auth/status sind öffentlich. /api/auth/setup erstellt das erste Konto und lehnt das Überschreiben vorhandener Zugangsdaten ab.", "/api/system-info ist ein öffentlicher Endpunkt für grundlegende Systemdaten einschließlich health.status. Er verlangt kein Token. Auch /api/auth/status ist öffentlich und eignet sich für eine Erreichbarkeitsprüfung." ], "cryptoTitle": "Kryptographie und Speicherung", "cryptoIntro": "ProxMenux Monitor ist Open Source – nichts davon ist geheim. Die Dokumentation des Stacks hier ist eine bewusste Entscheidung: Betreiber, die Anmeldeinformationen auf ihrem Host speichern, verdienen es zu wissen, wie diese Anmeldeinformationen geschützt sind, bevor sie sich entscheiden, ihnen zu vertrauen. Die folgenden Algorithmen sind die gleichen, die der Code in scripts/auth_manager.py verwendet; dieser Abschnitt ist ein Vertrag, kein Marketingversprechen.", "headerAsset": "Datenelement", "headerAlgo": "Algorithmus", "headerWhere": "Speicherort", "cryptoRows": [ { "asset": "Passwort", "algorithm": "PBKDF2-HMAC-SHA256 mit einem Zufallssalz pro Passwort und einer hohen Iterationszahl (OWASP 2023+ Baseline). Speichert als pbkdf2_sha256$<iters>$<salt>$<hash>.", "where": "auth.json → password_hash" }, { "asset": "Sitzung / API JWT", "algorithm": "HS256 mit einem pro Installation beim ersten Start erzeugten Geheimnis (secrets.token_urlsafe, ≥48 Byte). Tokens enthalten die Angaben iss=proxmenux-monitor und aud=api; die Signatur wird bei jeder Anfrage mit dem aktuellen Geheimnis geprüft.", "where": "Geheimnis: auth.json → jwt_secret. JWT selbst: nur auf dem Client." }, { "asset": "API Token Metadaten", "algorithm": "Der SHA-256-Hash des JWT wird mit dem Fingerabdruck signed_with des verwendeten jwt_secret gespeichert. Damit lassen sich Token-Metadaten anzeigen und Tokens nach einem Wechsel des Signaturgeheimnisses erkennen.", "where": "auth.json → api_tokens[]" }, { "asset": "2FA-TOTP-Geheimnis", "algorithm": "Standard-TOTP (RFC 6238) mit Base32-kodiertem Geheimnis. Die acht Backup-Codes sind einmalig und werden als SHA-256-Hashes gespeichert.", "where": "auth.json → totp_secret + backup_codes[]" }, { "asset": "Widerrufe", "algorithm": "Bei Widerruf eines Tokens oder einer Sitzung wird dessen SHA-256-Hash in eine Sperrliste aufgenommen, die bei jeder Prüfung berücksichtigt wird. Eine etwa 30 Sekunden gültige Speicherkopie vermeidet häufige Datenträgerzugriffe.", "where": "auth.json → revoked_tokens[]" } ], "authJsonTitle": "auth.json - was es enthält und wie es geschützt ist", "authJsonBody": "Die Authentifizierungsdaten liegen in /root/.config/proxmenux-monitor/auth.json, mit Modus 0600 und Eigentümer root. Die Datei enthält Hashes (PBKDF2) und geheimes Schlüsselmaterial (jwt_secret, totp_secret), niemals das Klartextpasswort. Sichern oder replizieren Sie den Host nur auf ein verschlüsseltes Ziel und nehmen Sie diese Datei niemals in die Versionsverwaltung auf.", "rotateTitle": "Ein Wechsel von jwt_secret macht bestehende JWTs ungültig", "rotateBody": "Wird auth.json neu erstellt oder mit einem anderen Geheimnis wiederhergestellt, ändert sich jwt_secret. Bisherige Sitzungs- und API-Tokens scheitern dann mit „Invalid or expired token“. Die Oberfläche kennzeichnet betroffene Tokens mit Ungültig — neu erstellen. Widerrufen und ersetzen Sie sie auch in Home Assistant, Skripten und anderen Clients.", "recoverTitle": "Wiederherstellen eines verlorenen Passworts", "recoverIntro": "Es gibt keinen Online-Fluss für \"Passwort vergessen\" - von Grund auf, da das Dashboard auf dem eigenen Host des Betreibers läuft und der Wiederherstellungspfad Shell-Zugriff auf diesen Host ist. ProxMenux liefert einen geführten Reset im Konfigurationsmenü, sodass Sie auth.json nicht von Hand bearbeiten müssen:", "survivesTitle": "Was den Reset überlebt", "survivesBody": "Die interaktive Anmeldung wird gelöscht, jwt_secret und registrierte api_tokens bleiben erhalten. Home Assistant und andere Integrationen können ihre Tokens weiterverwenden. Für einen vollständigen Neustart samt neuem Signaturgeheimnis auth.json manuell löschen und den Dienst neu starten. Dann sind alle alten Tokens ungültig.", "physicalTitle": "Voraussetzung für den physischen Zugang", "physicalBody": "Erfordert eine Root-Shell auf dem Host. Wer menu als root ausführen kann, besitzt bereits vollständige Kontrolle; die Passwortzurücksetzung erweitert seine Rechte nicht. Ein Monitor-Passwort schützt den Host daher nicht vor Personen mit unberechtigtem Root-Zugang." }, "twofa": { "heading": "Zwei-Faktor-Authentifizierung (TOTP)", "intro": "2FA fügt Ihrem Passwort einen zweiten Faktor hinzu: einen 6-stelligen Code, der alle 30 Sekunden rotiert und auf einem von Ihnen kontrollierten Telefon- oder Passwortmanager generiert wird. Selbst wenn jemand das Passwort erhält, kann er sich immer noch nicht ohne den Code von Ihrem Gerät anmelden. ProxMenux Monitor implementiert das Standard-Protokoll TOTP (RFC 6238), so dass jede Authentifizierungs-App funktioniert.", "pickTitle": "Wählen Sie eine Authenticator App", "pickIntro": "Eine vorhandene TOTP-App können Sie weiterverwenden. Die Tabelle nennt übliche Optionen: einige kostenlos, andere mit Abonnement. Plattformen und Sicherungsverfahren unterscheiden sich ebenfalls.", "headerApp": "App", "headerPlatforms": "Plattformen", "headerAppNotes": "Notizen", "apps": [ { "name": "Google Authenticator", "href": "https://safety.google/authentication/", "platforms": "iOS, Android", "notes": "Der Standard für viele Benutzer. Optionales Google-Konto Cloud-Backup." }, { "name": "Microsoft Authenticator", "href": "https://www.microsoft.com/en-us/security/mobile-authenticator-app", "platforms": "iOS, Android", "notes": "Microsoft-Account Backup. Behandelt auch MS-Push-Benachrichtigungen, wenn Sie sie bei der Arbeit verwenden." }, { "name": "Authy", "href": "https://authy.com/", "platforms": "iOS, Android", "notes": "Verschlüsselte Synchronisierung zwischen Geräten. Die Desktop-App wird seit dem 19. März 2024 nicht mehr unterstützt." }, { "name": "Apple Passwords", "href": "https://support.apple.com/guide/passwords/welcome/mac", "platforms": "iOS, iPadOS, macOS, visionOS, Windows (über iCloud)", "notes": "In Apple-Betriebssystemen enthalten; eigenständige Passwords-App seit iOS 18 / macOS Sequoia. Speichert TOTP neben dem Passwort und synchronisiert über den iCloud-Schlüsselbund." }, { "name": "Bitwarden", "href": "https://bitwarden.com/", "platforms": "iOS, Android, Desktop, Browser", "notes": "Open Source. TOTP kann im Passworttresor neben Passwörtern gespeichert werden. Das ist praktisch, bietet aber keine Trennung auf ein zweites Gerät." }, { "name": "1Password", "href": "https://1password.com/", "platforms": "iOS, Android, Desktop, Browser", "notes": "Wie Bitwarden: TOTP im Passworttresor. Kostenpflichtiges Abonnement." }, { "name": "Aegis Authenticator", "href": "https://getaegis.app/", "platforms": "Android", "notes": "Open Source. Verschlüsselte Backup-Datei auf dem Gerät, die Sie kontrollieren. Keine Cloud, kein Account erforderlich." }, { "name": "Raivo OTP", "href": "https://raivo-otp.com/", "platforms": "iOS, macOS", "notes": "Open Source. Optionale iCloud Sync. Das Apple-Ökosystem Pendant zu Aegis." }, { "name": "Ente Auth", "href": "https://ente.io/auth/", "platforms": "iOS, Android, Desktop, Web", "notes": "Open Source. Ende-zu-Ende verschlüsselte Cloud-Synchronisierung über Geräte hinweg." }, { "name": "2FAS", "href": "https://2fas.com/", "platforms": "iOS, Android, Browsererweiterung", "notes": "Open Source. Optionales verschlüsseltes Cloud-Backup; Browsererweiterung kann automatisch Codes ausfüllen." }, { "name": "FreeOTP+", "href": "https://github.com/helloworld1/FreeOTPPlus", "platforms": "Android", "notes": "Open-Source-Abspaltung von FreeOTP für Android mit Import und Export. Kein Konto erforderlich." } ], "backupTitle": "Warum Sicherungen wichtig sind", "backupBody": "Bei Verlust des Authenticator-Geräts einen gesicherten Backup-Code verwenden oder die App aus einer zuvor eingerichteten Sicherung wiederherstellen. Cloud-Synchronisierung und lokale Exporte unterscheiden sich je nach App; prüfen Sie, ob die gewählte Methode die TOTP-Geheimnisse tatsächlich wiederherstellt. Mit Root-Zugang zum Host ist die unten beschriebene Wiederherstellung ebenfalls möglich. Bewahren Sie eine separate, sichere Kopie auf.", "setupTitle": "Schritt-für-Schritt-Setup aus dem Dashboard", "setupImageAlt": "Einrichtungsbildschirm 2FA mit QR-Code und Backup-Codes", "setupImageCaption": "Der 2FA-Einrichtungsdialog zeigt QR-Code, Base32-Geheimnis zur manuellen Eingabe und nach der Überprüfung acht einmalige Backup-Codes. Die Codes vor dem Schließen des Dialogs kopieren; sie werden nicht erneut angezeigt.", "setupSteps": [ "Installieren Sie die Authenticator-App auf Ihrem Telefon (oder öffnen Sie Ihren Passwort-Manager). Eine der Apps aus der Tabelle oben. Sie müssen dies nur einmal tun - die gleiche app enthält codes für jeden dienst, den sie schützen.", "Am Dashboard anmelden mit Benutzername und Passwort.", "Registerkarte Sicherheit öffnen in der Seitenleiste des Dashboards, dann auf 2FA aktivieren und Einrichtung starten klicken. Der Dialog zeigt QR-Code und manuellen Schlüssel; die acht Backup-Codes erscheinen, nachdem der Code überprüft wurde.", "Fügen Sie den Eintrag zur Authenticator-App hinzu:", "Bestätigen Sie, indem Sie den aktuellen 6-stelligen Code aus der App in das Feld \"Verifizierungscode\" des Setup-Dialogs eingeben und senden. Codes aktualisieren alle 30 Sekunden, wenn es also abläuft, während Sie tippen, geben Sie einfach den nächsten ein.", "Backup-Codes sichern. Nach der Überprüfung alle acht sicher in einem Passwortmanager, einer verschlüsselten Notiz oder einem sicheren Ausdruck aufbewahren. Jeder funktioniert einmal, wenn der Authenticator nicht verfügbar ist.", "Fertig. 2FA ist aktiv. Bei der nächsten Anmeldung wird zuerst das Passwort und danach der aktuelle sechsstellige Code abgefragt." ], "setupStep4Sub": [ "Einfaches Verfahren: In der App Konto hinzufügen → QR-Code scannen wählen und die Kamera auf den QR-Code richten. Die App benennt den Eintrag automatisch, etwa ProxMenux Monitor (your-username), und zeigt alle 30 Sekunden einen neuen sechsstelligen Code.", "Manuelle Alternative, falls Scannen nicht möglich ist, etwa auf demselben Telefon: Konto hinzufügen → Einrichtungsschlüssel eingeben. Einen Namen wie Proxmox Monitor wählen, Base32-Geheimnis einfügen, Typ auf Zeitbasiert belassen und speichern." ], "testTitle": "Test vor dem Abmelden", "testBody": "Die bestehende Sitzung geöffnet lassen und sofort nach der Einrichtung in einem privaten Fenster eine neue Anmeldung testen. Bei abgelehntem Code zuerst Server- und Telefonuhr prüfen, bevor Sie sich aus der funktionierenden Sitzung abmelden. Bei bereits verlorenem Zugang einen Backup-Code verwenden oder auth.json in der Host-Shell bearbeiten.", "lostTitle": "Verlorener Authentifikator", "lostIntro": "Drei Wiederherstellungswege, von geringem bis stärkerem Eingriff:", "lostItems": [ "Backup-Code verwenden. Einen der acht gesicherten Codes im TOTP-Feld eingeben. Er funktioniert einmal; unbenutzte Codes bleiben gültig. Nach der Anmeldung Sicherheit öffnen, zuerst 2FA deaktivieren und danach 2FA aktivieren wählen, um acht neue Codes zu erhalten.", "Authenticator aus Cloud oder Sicherung wiederherstellen. Bei eingerichteter Cloud-Synchronisierung die App auf dem neuen Gerät installieren und anmelden, etwa Google, Microsoft, Authy, Apple Passwords über iCloud-Schlüsselbund, Ente oder 2FAS. Bei einer Exportdatei, etwa aus Aegis, Raivo oder FreeOTP+, die App installieren und die Datei importieren.", "Deaktivieren Sie 2FA von der Host-Shell. Wenn die vorherigen Optionen nicht verfügbar sind, bearbeiten Sie /root/.config/proxmenux-monitor/auth.json auf dem Proxmox-Host (Sie benötigen SSH oder Konsolenzugriff), setzen Sie totp_enabled auf false, speichern und starten Sie den Dienst neu:" ], "lostShellOutro": "Sie können sich nur mit Benutzername + Passwort anmelden und dann 2FA aus Einstellungen wieder aktivieren.", "disableTitle": "Deaktivieren Sie 2FA", "disableBody": "Sicherheit öffnen und 2FA deaktivieren wählen. POST /api/auth/totp/disable benötigt das aktuelle Passwort und einen gültigen TOTP- oder Backup-Code. Dabei werden TOTP-Geheimnis und Backup-Codes gelöscht. Den alten Eintrag auch in der Authenticator-App entfernen.", "rejectedTitle": "Der 6-stellige Code wird immer abgelehnt", "rejectedIntro": "TOTP ist zeitbasiert. Server- und Telefonuhr dürfen nur etwa 30 Sekunden voneinander abweichen. Zwei Prüfungen:", "rejectedItems": [ "Telefon: Einstellungen → Datum und Uhrzeit → automatische / Netzwerksynchronisierung aktivieren.", "Proxmox-Host: timedatectl status sollte „System clock synchronized: yes“ anzeigen. Andernfalls timedatectl set-ntp true ausführen und eine Minute warten." ], "rejectedOutro": "Sobald beide Uhren übereinstimmen, wird der Code innerhalb des nächsten 30-Sekundenfensters akzeptiert." }, "apiTokens": { "heading": "API-Token (langlebig)", "intro": "Browsersitzungen laufen nach 24 Stunden ab. Für Homepage-Widgets, Home Assistant, Grafana oder Uptime Kuma erstellen Sie ein separates API-Token mit 365 Tagen Laufzeit. Es verwendet dasselbe Signaturgeheimnis; die Angabe token_name erlaubt die Zuordnung und den einzelnen Widerruf.", "imageAlt": "API-Token-Panel zeigt die Token-Liste mit Name, Präfix, erstelltem Datum und Ablauf", "imageCaption": "Die API-Tokenliste unter Einstellungen — Name, Präfix (die letzten 4-Zeichen werden zur Identifizierung angezeigt), erstellt und Ablaufdatum, Widerrufsaktion.", "generateTitle": "Generieren Sie ein Token", "generateIntro": "Aus dem Dashboard:", "generateSteps": [ "Unter Sicherheit → API-Zugriffstokens öffnen.", "Beschreibenden Namen angeben, z. B. „Home Assistant“.", "Geben Sie Ihr Passwort erneut ein. Wenn 2FA eingeschaltet ist, auch der aktuelle 6-stellige Code.", "Token erstellen wählen. Es erscheint nur einmal; sofort kopieren." ], "generateCli": "Aus der Kommandozeile:", "useTitle": "Verwenden Sie ein Token", "revokeTitle": "Einen Token widerrufen", "revokeBody": "Jede Zeile bietet Widerrufen. Dadurch wird der Token-Hash unter revoked_tokens in auth.json gespeichert. Ab der nächsten Anfrage wird das Token abgelehnt.", "cheatTitle": "Kurzübersicht zur Token-Sicherheit", "cheatItems": [ "Tokens im Geheimnisspeicher der Integration ablegen: Homepage secrets.yaml, Home Assistant !secret oder Umgebungsvariablen. Niemals in Git aufnehmen.", "Ein nach der jeweiligen Integration benanntes Token verwenden. Beim Entfernen der Integration dieses Token einzeln widerrufen.", "Rotieren Sie alle 6–12 Monate. Der Ablauf ist eine harte Grenze, keine Empfehlung." ], "outro": "Hinweise zur sicheren Speicherung und Integrationsbeispiele: API-Referenz → Token-Verwaltung und Integrationen." }, "https": { "heading": "HTTPS", "intro": "Zwei Wege zu TLS:", "items": [ "Reverse-Proxy (empfohlen). Beenden Sie TLS auf Nginx / Caddy / Traefik und leiten Sie HTTP auf Port 8008 zum Flask-Prozess weiter. Snippets unten.", "Direktes HTTPS in der AppImage. Zertifikat über POST /api/ssl/configure einrichten (Oberfläche: Einstellungen → SSL). HTTPS verwendet gevent.pywsgi mit dem Standardhandler; flask-sock übernimmt WebSocket-Verbindungen für WSS. Zertifikatspfade stehen in der SSL-Konfiguration." ], "calloutTitle": "Direkte HTTPS-Beschränkungen", "calloutBody": "Der Monitor kann ein von Proxmox verwaltetes Zertifikat oder eigene Zertifikatsdateien verwenden. Er stellt selbst keine ACME-Zertifikate aus. Für automatische Ausstellung und Erneuerung Proxmox ACME oder einen Reverse-Proxy wie Caddy, Traefik oder Nginx verwenden; erneuerte Zertifikate müssen geladen werden." }, "gateway": { "heading": "Sicheres Gateway (Tailscale)", "intro": "Ein Reverse-Proxy ermöglicht Fernzugriff. Secure Gateway bietet Zugriff ohne Veröffentlichung von TCP 8008: Ein Alpine-LXC führt Tailscale als Subnetz-Router aus. Die LAN-IP des Hosts ist über genehmigte Subnetzrouten und Tailnet-Zugriffsregeln erreichbar.", "calloutTitle": "Warum dies bequem ist", "calloutBody": "Die LAN-URL http://<proxmox-lan-ip>:8008 über die genehmigte Route verwenden. Tailscale-Subnetz-Router nutzen standardmäßig SNAT. Der Monitor sieht daher üblicherweise die LAN-IP des Gateways statt der Clientadresse 100.x.y.z. Protokoll und Fail2Ban erkennen die tatsächlich am Host ankommende Quelladresse.", "deployBody": "Auf einer Seite LXC-Speicher wählen, einen unter login.tailscale.com/admin/settings/keys erzeugten Tailscale-Schlüssel einfügen, Subnetze wählen und bereitstellen. Der LXC wird in etwa 30 Sekunden eingerichtet und im Tailnet registriert.", "outro": "Bereitstellung, Subnetzrouten, Tailscale-ACLs und Exit-Node-Modus stehen unter Dashboard → Sicherheit → Secure Gateway. Dort befindet sich auch der Assistent. Diese Seite beschreibt den Zugriff." }, "proxy": { "heading": "Konfigurationsbeispiele für Reverse-Proxys", "intro": "Einen eigenen Hostnamen wie monitor.example.com auf Port 8008 des Proxmox-Hosts weiterleiten. Die Beispiele nutzen dieses Schema. Ein Unterpfad wie example.com/proxmenux-monitor/ braucht weitere Frontend- und Proxy-Anpassungen; Entfernen des Präfixes allein reicht nicht.", "nginxTitle": "Nginx", "caddyTitle": "Caddy", "traefikTitle": "Traefik (Labels — Docker / Kubernetes)", "subPathTitle": "Erweitert: Bereitstellung unter einem Unterpfad", "subPathBody": "Das aktuelle Frontend hat keine konfigurierte Unterpfad-Basis und erstellt API-Aufrufe mit rootrelativen /api/*-URLs. Ein Präfix wie example.com/proxmenux-monitor/ zu entfernen reicht weder für diese API-Aufrufe noch für alle Frontend-Dateien aus. Verwenden Sie einen eigenen Hostnamen. Ein Unterpfad erfordert abgestimmte Frontend-/Proxy-Anpassungen und eigene Tests." }, "audit": { "heading": "Prüfprotokoll", "intro": "Fehlgeschlagene Anmeldungen und Warnungen des Anmeldelimits werden zeilenweise in /var/log/proxmenux-auth.log geschrieben. Erfolgreiche Anmeldungen protokolliert dieser Logger nicht:", "outro": "Mit tail -F /var/log/proxmenux-auth.log verfolgen. Eine zusätzliche Konfiguration für logrotate ermöglicht die Rotation; der Monitor führt sie nicht selbst durch." }, "fail2ban": { "heading": "Optional: Fail2Ban-Jail", "calloutTitle": "Fail2Ban ist nicht mit dem Monitor gebündelt", "calloutBody": "Fail2Ban wird nicht von ProxMenux Monitor selbst installiert. Installieren Sie es über Sicherheit → Fail2Ban im Menü ProxMenux (oder mit dem Standard-Debian-Paket). Ohne sie schreibt der Monitor immer noch das obige Überwachungsprotokoll – Wiederholungstäter werden einfach nicht automatisch gesperrt.", "intro": "Wenn Fail2Ban installiert ist, liefert die ProxMenux-Integration einen [proxmenux] jail mit, der:", "items": [ "Liest /var/log/proxmenux-auth.log.", "Erkennt das Muster authentication failure; rhost=<ip> mit einem eigenen Filter.", "Sperrt die beanstandete IP standardmäßig auf Kernel-Firewall-Ebene.", "Der Flask-Hook before_request prüft Anfragen anhand der für 30 Sekunden zwischengespeicherten Sperrliste. Hinter einem Reverse-Proxy sind PROXMENUX_TRUST_PROXY=1 und ein kontrollierter Proxy mit vertrauenswürdigen Weiterleitungsheadern erforderlich." ], "outro": "Konfiguration, Sperrdauer und Entsperren: Sicherheit → Fail2Ban." }, "troubleshoot": { "heading": "Fehlerbehebung", "noScreenTitle": "Der erste Launch-Bildschirm erscheint nie", "noScreenBody": "Die Authentifizierung ist bereits eingerichtet (configured: true) oder wurde übersprungen. Für eine neue Einrichtung:", "noScreenOutro": "Löscht den Authentifizierungszustand einschließlich TOTP-Geheimnissen und API-Tokens. Zuerst auth.json sichern, falls Sie Tokens behalten möchten.", "tokenTitle": "HTTP 401 bei jeder Anfrage von einem funktionierenden API-Token", "tokenBody": "Token abgelaufen (365 Tage) oder in revoked_tokens eingetragen. Neues Token in den Einstellungen erstellen und die Integration aktualisieren. Prüfen mit:", "tokenOutro": "Abgelaufene oder widerrufene Token geben '{'\"error\":\"Invalid or expired token\"'}' zurück.", "no2faTitle": "Kann sich nicht anmelden, nachdem 2FA aktiviert wurde, kein Authentifikator zur Hand", "no2faBody": "Verwenden Sie einen Backup-Code im TOTP-Feld. Wenn diese nicht mehr vorhanden sind, bearbeiten Sie /root/.config/proxmenux-monitor/auth.json von einer Host-Shell, setzen totp_enabled auf false, starten Sie den Dienst neu.", "wsTitle": "Reverse Proxy funktioniert, aber der Terminal-Tab trennt sich jede Minute", "wsBody": "Möglicher Grund ist das WebSocket-Leerlaufzeitlimit des Proxys. Lesezeitlimit erhöhen (Nginx: proxy_read_timeout 86400s; Traefik: idleTimeout im Einstiegspunkt oder der Middleware). In Nginx proxy_set_header Upgrade $http_upgrade und Connection \"upgrade\" prüfen." }, "whereNext": { "heading": "Wohin als nächstes", "items": [ { "label": "API-Referenz → Token-Verwaltung", "href": "/docs/monitor/api", "tail": " — API-Tokens erstellen, auflisten und widerrufen; sichere Speicherung und Sicherheitsregeln." }, { "label": "Integrationen", "href": "/docs/monitor/integrations", "tail": " — Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma und allgemeine cURL-Beispiele." }, { "label": "Übersicht → Sicherheit → Sicheres Gateway", "href": "/docs/monitor/dashboard/security", "tail": " — Tailscale-Gateway-LXC schrittweise bereitstellen: Subnetzrouten, ACLs und Exit-Node-Modus." }, { "label": "Sicherheit: Fail2Ban", "href": "/docs/security/fail2ban", "tail": " — optionale Jail installieren und konfigurieren." }, { "label": "Einstellungen → ProxMenux Monitor", "href": "/docs/settings/proxmenux-monitor", "tail": " — systemd-Dienst über die ProxMenux-TUI starten und stoppen." } ] } }