Authentifizierung & Sicherheit
Die API verwendet eine Kombination aus sitzungsbasierter Authentifizierung und CSRF-Schutz für alle Schreiboperationen in der Datenbank, um unbefugten Zugriff und potenzielle Denial-of-Service-Angriffe zu verhindern. Externe APIs, die von Duplicati und Homepage verwendet werden, bleiben von CSRF ausgenommen. Sie können optional einen bereichsbezogenen API-Schlüssel und/oder eine IP-Zulassungsliste erfordern (beide standardmäßig aus). /api/upload verfügt zudem über eine konfigurierbare Obergrenze für die Textkörper-Größe und ein Ratenlimit.
Sitzungsbasierte Authentifizierung
Geschützte Endpunkte erfordern ein gültiges Sitzungs-Cookie und ein CSRF-Token. Das Sitzungssystem bietet eine sichere Authentifizierung für alle geschützten Operationen.
Sitzungsverwaltung
- Sitzung erstellen: POST an
/api/session, um eine neue Sitzung zu erstellen - CSRF-Token abrufen: GET
/api/csrf, um ein CSRF-Token für die Sitzung zu erhalten - In Anfragen einbinden: Sitzungs-Cookie und CSRF-Token mit geschützten Anfragen senden
- Sitzung validieren: GET
/api/session, um zu prüfen, ob die Sitzung noch gültig ist - Sitzung löschen: DELETE
/api/session, um sich abzumelden und die Sitzung zu löschen
CSRF-Schutz
Alle zustandsändernden Operationen erfordern ein gültiges CSRF-Token, das mit der aktuellen Sitzung übereinstimmt. Das CSRF-Token muss für geschützte Endpunkte im Header X-CSRF-Token enthalten sein.
Geschützte Endpunkte
Alle Endpunkte, die Datenbankdaten ändern, erfordern eine Sitzungsauthentifizierung und ein CSRF-Token:
- Serververwaltung:
/api/servers/:id(PATCH, DELETE),/api/servers/:id/server-url(PATCH),/api/servers/:id/password(PATCH, GET) - Konfigurationsverwaltung:
/api/configuration/email(GET, POST, DELETE),/api/configuration/unified(GET),/api/configuration/ntfy(GET),/api/configuration/notifications(GET, POST),/api/configuration/backup-settings(POST),/api/configuration/templates(POST),/api/configuration/overdue-tolerance(GET, POST),/api/configuration/daily-summary(GET, POST),/api/configuration/daily-summary/send(POST),/api/configuration/daily-summary/retry(POST),/api/configuration/daily-summary/preview(POST) - Benachrichtigungssystem:
/api/notifications/test(POST),/api/notifications/preview(POST),/api/notification-channel-alerts(GET, POST) - Administrator erforderlich; POST erfordert zudem ein CSRF-Token - Cron-Konfiguration:
/api/cron-config(GET, POST) - Cron-Proxy:
/api/cron/*(GET, POST) – leitet Anfragen an den Cron-Dienst weiter. POST erfordert einen Administrator. Der Cron-Prozess bindet standardmäßig an127.0.0.1; mutierende Cron-Dienst-Routen erfordernX-Cron-Service-Secret, wennCRON_SERVICE_SECRETfestgelegt ist. - Sitzungsverwaltung:
/api/session(POST, GET, DELETE),/api/csrf(GET) - Diagrammdaten:
/api/chart-data/*(GET) - Dashboard:
/api/dashboard(GET) - Server-Details:
/api/servers(GET),/api/servers/:id(GET),/api/detail/:serverId(GET) - Audit-Protokoll:
/api/audit-log(GET),/api/audit-log/download(GET),/api/audit-log/filters(GET),/api/audit-log/retention(PATCH),/api/audit-log/cleanup(POST) – Admin für Schreiboperationen erforderlich - Benutzerverwaltung:
/api/users(GET, POST, PATCH, DELETE) – Admin erforderlich - Datenbankverwaltung:
/api/database/backup(GET),/api/database/restore(POST) – Admin erforderlich - Anwendungsprotokolle:
/api/application-logs(GET),/api/application-logs/export(GET) – Admin erforderlich - Sicherungserfassung:
/api/backups/collect(POST) – erfordert Sitzung und CSRF-Token - Sicherungszeitplan-Synchronisierung:
/api/backups/sync-schedule(POST) – erfordert Sitzung und CSRF-Token - Überfälligkeitsprüfung:
/api/notifications/check-overdue(POST) – erfordert Sitzung und CSRF-Token - Überfällige Zeitstempel löschen:
/api/notifications/clear-overdue-timestamps(POST) – erfordert Sitzung und CSRF-Token
Externe Endpunkte
Diese Routen verwenden keine Sitzungs-Cookies oder CSRF. Die Authentifizierung ist optional und wird in den Einstellungen konfiguriert:
/api/upload– Sicherungsdaten-Uploads von Duplicati (Schlüssel mit Upload-Bereich, Größen- und Ratenbegrenzungen)/api/lastbackup/:serverId– Neuester Sicherungsstatus (Schlüssel mit Lese-Bereich)/api/lastbackups/:serverId– Status der neuesten Sicherungen (Schlüssel mit Lese-Bereich)/api/summary– Gesamtzusammenfassungsdaten (Schlüssel mit Lese-Bereich)/api/health– Health-Check-Endpunkt (niemals mit Schlüssel; ressourcenschonende SQLite-Prüfung; Ratenbegrenzung pro IP)/api/ping– Konnektivitätsprüfung (niemals mit Schlüssel; Ratenbegrenzung pro IP)
Wenn API-Schlüssel anfordern ausgeschaltet ist, akzeptieren die ersten vier Routen Anfragen mit oder ohne Schlüssel: Ein gültiger Schlüssel mit passendem Bereich wird aufgezeichnet; ein ungültiger Schlüssel wird ignoriert. Wenn der Schalter eingeschaltet ist, geben sie ohne gültigen Schlüssel 401 und bei nicht übereinstimmendem Schlüsselbereich 403 zurück. /api/health und /api/ping verwenden niemals Schlüssel. Siehe API-Schlüssel und IP-Zulassungsliste.
Anwendungsbeispiel (Sitzung + CSRF)
// 1. Create session
const sessionResponse = await fetch('/api/session', { method: 'POST' });
const { sessionId } = await sessionResponse.json();
// 2. Get CSRF token
const csrfResponse = await fetch('/api/csrf', {
headers: { 'Cookie': `session=${sessionId}` }
});
const { csrfToken } = await csrfResponse.json();
// 3. Make protected request
const response = await fetch('/api/servers/server-id', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken,
'Cookie': `session=${sessionId}`
},
body: JSON.stringify({
alias: 'Updated Server Name',
note: 'Updated notes'
})
});
Authentifizierungsendpunkte
Login - /api/auth/login
-
Endpunkt:
/api/auth/login -
Methode: POST
-
Beschreibung: Authentifiziert einen Benutzer und erstellt eine Sitzung. Unterstützt Kontosperrung nach fehlgeschlagenen Versuchen und Anforderungen zur Passwortänderung.
-
Authentifizierung: Erfordert eine gültige Sitzung und ein CSRF-Token (jedoch keinen angemeldeten Benutzer)
-
Request-Body:
{"username": "admin","password": "password123"} -
Antwort (Erfolgreich):
{"success": true,"user": {"id": "user-id","username": "admin","isAdmin": true,"mustChangePassword": false},"keyChanged": false} -
Fehlerantworten: Alle Fehlerantworten enthalten
error(englische Meldung) underrorCode(stabilen Code für clientseitige Übersetzung).400: Fehlender Benutzername oder Passwort —errorCode: "REQUIRED_CREDENTIALS"401: Ungültiger Benutzername oder Passwort —errorCode: "INVALID_CREDENTIALS"403: Konto aufgrund zu vieler fehlgeschlagener Anmeldeversuche gesperrt —errorCode: "ACCOUNT_LOCKED"(enthältlockedUntil,minutesRemaining)500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"503: Datenbank nicht bereit —errorCode: "DATABASE_NOT_READY"
-
Hinweise:
- Konto wird nach 5 fehlgeschlagenen Anmeldeversuchen für 15 Minuten gesperrt
- Fehlgeschlagene Anmeldeversuche werden verfolgt und protokolliert
- Sitzungs-Cookie wird automatisch in der Antwort gesetzt
- Wenn der Benutzer das Flag
mustChangePasswordgesetzt hat, sollte er zur Passwort-Änderungsseite weitergeleitet werden - Alle Anmeldeversuche (erfolgreich und fehlgeschlagen) werden im Audit-Protokoll protokolliert
Abmelden - /api/auth/logout
-
Endpunkt:
/api/auth/logout -
Methode: POST
-
Beschreibung: Meldet den aktuellen Benutzer ab und zerstört dessen Sitzung.
-
Authentifizierung: Erfordert eine gültige Sitzung und ein CSRF-Token
-
Antwort (Erfolgreich):
{"success": true,"message": "Logged out successfully","successCode": "LOGGED_OUT"} -
Fehlerantworten: Enthalten
errorunderrorCodefür clientseitige Übersetzung.400: Keine aktive Sitzung —errorCode: "NO_ACTIVE_SESSION"500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"
-
Hinweise:
- Sitzungs-Cookie wird in der Antwort gelöscht
- Abmeldung wird im Audit-Protokoll protokolliert
- Sitzung wird sofort ungültig gemacht
Aktuellen Benutzer abrufen - /api/auth/me
-
Endpunkt:
/api/auth/me -
Methode: GET
-
Beschreibung: Gibt die Informationen des aktuell authentifizierten Benutzers zurück oder gibt an, ob kein Benutzer angemeldet ist.
-
Authentifizierung: Erfordert eine gültige Sitzung (aber kein angemeldeter Benutzer erforderlich)
-
Antwort (authentifiziert):
{"authenticated": true,"user": {"id": "user-id","username": "admin","isAdmin": true,"mustChangePassword": false}} -
Antwort (nicht authentifiziert):
{"authenticated": false,"user": null} -
Fehlerantworten: Enthalten
errorunderrorCodefür clientseitige Übersetzung.500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"
-
Hinweise:
- Kann ohne angemeldeten Benutzer aufgerufen werden (gibt
authenticated: falsezurück) - Nützlich zum Prüfen des Authentifizierungsstatus beim Laden der Seite
- Kann ohne angemeldeten Benutzer aufgerufen werden (gibt
Passwort ändern - /api/auth/change-password
-
Endpunkt:
/api/auth/change-password -
Methode: POST
-
Beschreibung: Ändert das Passwort für den aktuell authentifizierten Benutzer. Wenn
mustChangePasswordfestgelegt ist, wird die Überprüfung des aktuellen Passworts übersprungen. -
Authentifizierung: Erfordert eine gültige Sitzung und ein CSRF-Token (angemeldeter Benutzer erforderlich)
-
Request-Body:
{"currentPassword": "old-password","newPassword": "new-secure-password"} -
currentPassword: Optional, wennmustChangePasswordtrue ist, andernfalls erforderlichnewPassword: Erforderlich, muss die Anforderungen der Passwortrichtlinie erfüllen
-
Antwort (Erfolgreich):
{"success": true,"message": "Password changed successfully","successCode": "PASSWORD_CHANGED"} -
Fehlerantworten: Enthalten
errorunderrorCodefür clientseitige Übersetzung. Richtlinienverstoß kannvalidationErrorsenthalten (Array von Zeichenketten).400: Neues Passwort fehlt —errorCode: "NEW_PASSWORD_REQUIRED"400: Verstoß gegen Passwort-Richtlinie —errorCode: "POLICY_NOT_MET"(kannvalidationErrorsenthalten)400: Neues Passwort entspricht dem aktuellen —errorCode: "NEW_PASSWORD_SAME_AS_CURRENT"401: Aktuelles Passwort ist falsch —errorCode: "CURRENT_PASSWORD_INCORRECT"404: Benutzer nicht gefunden —errorCode: "USER_NOT_FOUND"500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"
-
Hinweise:
- Neues Passwort muss die Anforderungen der Passwort-Richtlinie erfüllen (Länge, Komplexität usw.)
- Wenn das Flag
mustChangePasswordgesetzt ist, wird die Überprüfung des aktuellen Passworts übersprungen - Nach erfolgreicher Passwortänderung wird das Flag
mustChangePasswordgelöscht - Passwortänderungen werden im Audit-Protokoll protokolliert
- Neues Passwort muss sich vom aktuellen Passwort unterscheiden
Prüfen: Admin – Passwort muss geändert werden - /api/auth/admin-must-change-password
-
Endpunkt:
/api/auth/admin-must-change-password -
Methode: GET
-
Beschreibung: Prüft, ob der Administrator-Benutzer sein Passwort ändern muss. Dieser Endpunkt ist öffentlich (keine Authentifizierung erforderlich), da er nur ein boolesches Flag zurückgibt.
-
Antwort:
{"mustChangePassword": false} -
Fehlerantworten:
500: Interner Serverfehler (gibt bei FehlermustChangePassword: falsezurück, um Tipp nicht anzuzeigen, falls es ein Datenbankproblem gibt)
-
Hinweise:
- Öffentlicher Endpunkt, keine Authentifizierung erforderlich
- Gibt
falsezurück, wenn Administrator-Benutzer nicht existiert - Wird verwendet, um zu bestimmen, ob Passwort-Änderungshinweis angezeigt werden soll
- Bei Fehler gibt
falsezurück, um Tipp nicht anzuzeigen, falls es ein Datenbankproblem gibt
Passwortrichtlinie abrufen - /api/auth/password-policy
-
Endpunkt:
/api/auth/password-policy -
Methode: GET
-
Beschreibung: Gibt die aktuelle Konfiguration der Passwortrichtlinie zurück. Dieser Endpunkt ist öffentlich (keine Authentifizierung erforderlich), da er für die Frontend-Validierung benötigt wird.
-
Antwort:
{"minLength": 8,"requireUppercase": true,"requireLowercase": true,"requireNumbers": true,"requireSpecialChars": false} -
Fehlerantworten: Enthalten
errorunderrorCodefür clientseitige Übersetzung.500: Abrufen der Passwort-Richtlinie fehlgeschlagen —errorCode: "POLICY_RETRIEVE_FAILED"
-
Hinweise:
- Öffentlicher Endpunkt, keine Authentifizierung erforderlich
- Wird von Frontend-Komponenten verwendet, um Passwortanforderungen anzuzeigen und Passwörter vor der Übermittlung zu überprüfen
- Richtlinie wird über Umgebungsvariablen konfiguriert (
PWD_ENFORCE,PWD_MIN_LEN) - Standard-Passwort-Überprüfung (Verhinderung der Verwendung des Standard-Admin-Passworts) wird immer erzwungen, unabhängig von Richtlinieneinstellungen
Fehler- und Erfolgscodes der Auth-API (i18n)
Auth-Endpunkte geben zusätzlich zum visuell lesbaren Feld error oder message einen stabilen errorCode (und bei Erfolg successCode) zurück. Die Werte für error und message sind auf Englisch. Clients sollten die Codes verwenden, um lokalisierte Zeichenfolgen nachzuschlagen, damit die Benutzeroberfläche Nachrichten in der vom Benutzer ausgewählten Sprache anzeigt.
| Endpunkt | Erfolgscode | Fehlercodes |
|---|---|---|
/api/auth/login | — | REQUIRED_CREDENTIALS, INVALID_CREDENTIALS, ACCOUNT_LOCKED, DATABASE_NOT_READY, INTERNAL_ERROR |
/api/auth/logout | LOGGED_OUT | NO_ACTIVE_SESSION, INTERNAL_ERROR |
/api/auth/me | — | INTERNAL_ERROR |
/api/auth/change-password | PASSWORD_CHANGED | NEW_PASSWORD_REQUIRED, POLICY_NOT_MET, USER_NOT_FOUND, CURRENT_PASSWORD_INCORRECT, NEW_PASSWORD_SAME_AS_CURRENT, INTERNAL_ERROR |
/api/auth/password-policy | — | POLICY_RETRIEVE_FAILED |
Fehlerantworten
401 Unauthorized: Ungültige oder fehlende Sitzung, abgelaufene Sitzung oder Validierung des CSRF-Tokens fehlgeschlagen403 Forbidden: Validierung des CSRF-Tokens fehlgeschlagen oder Vorgang nicht zulässig
Den duplistatus-Server nicht für das öffentliche Internet freigeben. Verwenden Sie ihn in einem sicheren Netzwerk (z. B. lokales LAN, das durch eine Firewall geschützt ist).
Die Freigabe der duplistatus-Benutzeroberfläche für das öffentliche Internet ohne angemessene Sicherheitsmaßnahmen könnte zu unbefugtem Zugriff führen.