344 lines
20 KiB
Markdown
344 lines
20 KiB
Markdown
# Changelog
|
||
|
||
Alle nennenswerten Änderungen an Clusev. Format nach
|
||
[Keep a Changelog](https://keepachangelog.com), Versionierung nach
|
||
[SemVer](https://semver.org).
|
||
|
||
**Release-Prozess:** Feature-Commits sammeln sich auf dem Branch. Ist ein Stand
|
||
reif, wird er nach `main` gemerged, als `vX.Y.Z` getaggt und hier unter einer
|
||
eigenen Versionsüberschrift dokumentiert. Nutzer beziehen ausschließlich
|
||
getaggte Releases (Kanal `stable`, optional `beta`) — niemals Entwicklungs-Builds.
|
||
|
||
## [Unreleased]
|
||
|
||
_Keine offenen Änderungen — der nächste Stand wird hier gesammelt und als `vX.Y.Z` getaggt._
|
||
|
||
## [0.6.1] - 2026-06-14
|
||
|
||
### Behoben
|
||
- **Sidebar-Server-Switcher driftete von der Detailseite ab.** Es gab zwei „aktueller
|
||
Server"-Begriffe: den Switcher (Session) und die `/servers/{uuid}`-Detailseite. Jetzt setzt der
|
||
Aufruf einer Detailseite den Server aktiv (Sidebar spiegelt immer die Seite), und ein Wechsel im
|
||
Switcher auf einer Detailseite navigiert zum gewählten Server statt die alte Seite neu zu laden.
|
||
Geschrieben wird nur bei bewusster Navigation (race-frei). *Bekannte Rest-Kante:* nach
|
||
Back/Forward (wire:navigate-Cache, kein erneutes `mount()`) zeigt die gecachte Seite den richtigen
|
||
Server, aber die Session kann kurz auf den vorigen zeigen — löst sich bei der nächsten bewussten
|
||
Navigation; inhärent am Single-Session-Modell (auch Multi-Tab).
|
||
|
||
## [0.6.0] - 2026-06-14
|
||
|
||
### Hinzugefügt
|
||
- **WebAuthn / Security-Keys (YubiKey) als optionaler 2. Login-Faktor.** Per
|
||
`web-auth/webauthn-lib`. TOTP + Backup-Codes bleiben der erforderliche 2FA und die einzige
|
||
Wiederherstellung; ein Security-Key ist eine zusätzliche Login-Option.
|
||
- **Gated auf Domain + HTTPS:** Die rpId ist die aktive Domain — auf Bare-IP/HTTP ist die
|
||
Funktion ausgeblendet (mit Hinweis), da eine IP keine gültige rpId ist.
|
||
- **Einstellungen → Sicherheit:** Security-Keys hinzufügen (benannt), auflisten, entfernen
|
||
(mit Bestätigung). Beim Login-2FA-Schritt „Mit Security-Key anmelden" neben TOTP/Backup-Code.
|
||
- 2FA deaktivieren (UI **und** `clusev:reset-admin --disable-2fa`) entfernt jetzt auch
|
||
Security-Keys + Backup-Codes, damit ein Reset den zweiten Faktor vollständig zurücksetzt.
|
||
|
||
### Sicherheit
|
||
- rpId strikt = aktive Domain (nie eine IP). Challenges serverseitig + einmalig.
|
||
- Signatur-Zähler-Prüfung mit Rollback-/Klon-Erkennung; Zähler 0 nur toleriert, wenn der
|
||
gespeicherte Zähler ebenfalls 0 ist (Plattform-Authenticator/Passkeys).
|
||
- Registrierung erfordert eine aktive 2FA-Anmeldung; Label wird vor der Browser-Ceremony
|
||
validiert (keine verwaisten Credentials). Alle Aktionen im Audit-Log.
|
||
|
||
> Hinweis: Der echte End-to-End-Test (YubiKey registrieren + anmelden) ist nur unter einer Domain
|
||
> mit HTTPS möglich; die Ceremony-Logik ist auf Options-/Speicher-/Gating-Ebene getestet.
|
||
|
||
## [0.5.0] - 2026-06-14
|
||
|
||
### Hinzugefügt
|
||
- **Kontowiederherstellung.**
|
||
- **2FA-Backup-Codes:** 8 Einmal-Codes werden bei der 2FA-Einrichtung erzeugt, einmalig
|
||
angezeigt und als `.txt` herunterladbar; in den Einstellungen (Sicherheit) neu erzeugbar.
|
||
Beim Login-2FA-Schritt als Alternative zum Authenticator-Code verwendbar.
|
||
- **„Passwort vergessen":** Reset über einen 2FA-Code oder Backup-Code (ohne E-Mail nötig).
|
||
Zusätzlich ein E-Mail-Reset-Link, sobald ein echter Mailer konfiguriert ist
|
||
(`mail.default` ≠ `log`/`array`).
|
||
- **CLI-Notfall:** `php artisan clusev:reset-admin` setzt das Admin-Passwort (und optional 2FA
|
||
+ Backup-Codes) per Server-Shell zurück — der Last-Resort bei kompletter Aussperrung.
|
||
|
||
### Sicherheit
|
||
- Passwort-Resets (Formular, E-Mail-Link, CLI) rotieren das `remember_token` — eine gestohlene
|
||
„Angemeldet bleiben"-Cookie überlebt einen Reset nicht.
|
||
- Backup-Codes werden atomar (Row-Lock) verbraucht (kein Replay).
|
||
- Der Notify-Toaster liegt jetzt auch auf den Auth-Seiten; alle Reset-/Backup-Aktionen werden im
|
||
Audit-Log erfasst.
|
||
|
||
## [0.4.6] - 2026-06-14
|
||
|
||
### Behoben
|
||
- **Validierungsmeldungen waren nur Englisch.** Es gab keine `lang/{de,en}/validation.php`, also
|
||
fiel Laravel bei jedem Eingabefeld-Fehler auf seine eingebauten englischen Meldungen zurück —
|
||
unabhängig von der gewählten Sprache. Vollständige `validation.php` in Deutsch (Quelle) und
|
||
Englisch ergänzt, plus lokalisierte Attribut-Namen (z. B. „SSH-Port", „E-Mail-Adresse"). Leeres
|
||
Login-Formular zeigt jetzt z. B. „E-Mail-Adresse muss ausgefüllt werden.".
|
||
|
||
## [0.4.5] - 2026-06-14
|
||
|
||
### Hinzugefügt
|
||
- **Favicons + PWA-Manifest.** Vollständiger Icon-Satz aus dem App-Brand-Mark (oranges
|
||
Server-Glyph auf Dunkel): `favicon.svg` (skalierbar), `favicon.ico` (16/32/48),
|
||
`apple-touch-icon.png`, `icon-192/512.png` und `site.webmanifest`. In beiden Layouts via
|
||
gemeinsames `partials/head-icons` eingebunden (incl. `theme-color`); nginx liefert das
|
||
Manifest als `application/manifest+json`.
|
||
- **Eigene Fehlerseiten.** Gebrandete, zweisprachige Seiten für 403/404/419/429/500/503 auf
|
||
einem eigenständigen Fehler-Layout (Design-Tokens, Brand-Mark) — ersetzen Laravels
|
||
Standard-Fehlerseiten. Es werden nie rohe Status-Texte oder Stacktraces gezeigt; in Prod ist
|
||
`APP_DEBUG` fest auf `false` gepinnt.
|
||
|
||
### Behoben
|
||
- **Roher Fehlertext beim Datei-Download.** Der Download-Fehler zeigte die unverpackte
|
||
Exception-Meldung; jetzt eine lokalisierte Meldung (`files.download_failed`), konsistent mit
|
||
Upload/Löschen.
|
||
- **Fehlerseiten-Sprache.** Früh geworfene Fehler (CSRF 419, gematchte Aborts) berücksichtigen
|
||
jetzt die Nutzersprache (locale-Auflösung im Exception-Hook, absturzsicher gekapselt).
|
||
|
||
## [0.4.4] - 2026-06-14
|
||
|
||
### Behoben
|
||
- **Zoom beim Fokus auf Eingabefelder (Handy/Tablet).** iOS Safari zoomt die Seite hinein, wenn
|
||
ein fokussiertes Eingabefeld eine Schriftgröße < 16px hat — durch das dichte Design (`text-xs`/
|
||
`text-sm` auf Inputs) trat das bei jedem Feld auf. Eine zentrale Regel (`@media (pointer:
|
||
coarse)`) erzwingt jetzt 16px für `input`/`textarea`/`select` auf Touch-Geräten (Handy + Tablet
|
||
jeder Größe, inkl. iPad Pro 1024/1366px), während das Desktop-Layout (Maus) unverändert klein
|
||
bleibt. Per Touch-Emulation über alle Eingabefelder verifiziert.
|
||
|
||
## [0.4.3] - 2026-06-14
|
||
|
||
### Behoben
|
||
- **Mobile Overflow durch lange URLs und IPv6-Bans.** Responsive-Audit (R7) über alle Views bei
|
||
375/768px: mit den aktuellen Daten lief nichts über, aber lange Werte konnten Zeilen über den
|
||
Viewport schieben. Behoben: die Panel-Domain (`break-all` am Link, `min-w-0` an der
|
||
Zugriffsadresse) im System-Bereich und gebannte IPv6-Adressen in der fail2ban-Liste
|
||
(`min-w-0 break-all`). Per injizierter 253-Zeichen-Domain und langer IPv6 bei 375px verifiziert.
|
||
|
||
## [0.4.2] - 2026-06-14
|
||
|
||
### Hinzugefügt
|
||
- **Server-Status „Initialisierung".** Neu angelegte Server starten in einem cyanfarbenen
|
||
`pending`-Zustand (nicht mehr sofort rot/Offline), bis der erste Kontakt sie auf online/offline
|
||
setzt.
|
||
- **SSH-Verbindungstest beim Anlegen.** Beim Server-Anlegen wird die SSH-Anmeldung in der
|
||
Anlage-Transaktion geprüft (Login + Befehls-Marker beweisen, dass Befehle ausführbar sind);
|
||
schlägt sie fehl, wird nichts gespeichert und der SSH-Grund im Formular angezeigt.
|
||
- **Hinweis „nur per SSH-Key".** Die SSH-Passwort-Login-Zeile der Härtungs-Checkliste weist
|
||
darauf hin, dass der Zugang nach dem Deaktivieren nur noch per SSH-Key möglich ist.
|
||
|
||
### Geändert
|
||
- **Einheitliche Buttons.** Alle Buttons haben durchgehend Rahmen + Hintergrund; Löschen-Aktionen
|
||
nutzen die neue `danger-soft`-Variante (dezent rot getönt, dauerhaft — nicht erst beim Hover).
|
||
Die rahmenlosen `ghost`/`ghost-danger`-Varianten sind entfallen.
|
||
- **Firewall- und fail2ban-Boxen** erscheinen nur noch, wenn das jeweilige Tool installiert ist
|
||
(oder die Statusabfrage fehlschlug), und liegen im responsiven 2-Spalten-Grid (eine Box → volle
|
||
Breite). Die redundante „nicht installiert"-Box entfällt — installiert wird über die
|
||
Härtungs-Checkliste.
|
||
- **Automatische Updates** gelten als Betreiber-Präferenz, nicht als Sicherheitsanforderung: der
|
||
Zustand wird neutral als aktiv/inaktiv angezeigt und „aus" nie mehr als unsicher (OFFEN) markiert.
|
||
|
||
### Behoben
|
||
- **fail2ban/UFW fälschlich „nicht installiert".** Die Härtungs-Checkliste erkennt ein Tool jetzt
|
||
auch dann als installiert, wenn nur die Binary auf dem PATH liegt oder der Dienst läuft (vorher
|
||
nur `dpkg -l … ^ii`) — konsistent mit den Status-Panels. Behebt den Widerspruch „Checkliste:
|
||
nicht installiert" vs. „Panel: aktiv, N gesperrt".
|
||
|
||
## [0.4.1] - 2026-06-14
|
||
|
||
### Behoben
|
||
- **Verstümmelter Header auf jeder eingeloggten Seite.** Ein Kommentar im `@php`-Block der
|
||
topbar enthielt die literalen Tokens `@php`/`@endphp`; Blades Raw-Block-Matcher nahm das
|
||
`@endphp` im Kommentar als Block-Ende und gab den Rest (inkl. `$title ??= …`) als Klartext im
|
||
`<header>` aus — der Seitentitel blieb zudem leer. Kommentar bereinigt; neue Regel **R17**
|
||
(keine Direktiv-Tokens in Blade-Kommentaren; gerenderte Ausgabe prüfen, nicht nur HTTP 200).
|
||
|
||
### Sicherheit
|
||
- **Realtime-Kanäle sind jetzt privat.** Der Live-Metrik-Broadcast (`MetricsTicked`) läuft über
|
||
einen `PrivateChannel`, autorisiert über `/broadcasting/auth` (im `web`-Group → PanelScheme +
|
||
Session). Damit kann niemand mehr allein mit dem (öffentlich gebündelten) App-Key Infrastruktur-
|
||
Metriken abonnieren — auch nicht über einen alten Caddy-Host nach einem Domain-Wechsel. Neue
|
||
Konvention (CLAUDE.md §3 / `routes/channels.php`): **jeder** Broadcast-Kanal ist privat.
|
||
|
||
## [0.4.0] - 2026-06-14
|
||
|
||
Die Panel-Domain ist wieder aus dem Dashboard änderbar — diesmal sicher: gespeichert wird in der Datenbank, angewendet beim Neustart, das Zertifikat holt Caddy automatisch.
|
||
|
||
### Hinzugefügt
|
||
- **Domain aus dem Dashboard ändern.** Auf der System-Seite lässt sich die Panel-Domain
|
||
eintragen oder leeren. Gespeichert wird als Einstellung (`panel_domain`, übersteuert die
|
||
Installations-Domain `APP_DOMAIN`); nach einem Stack-Neustart leiten sich URL, der
|
||
WebSocket-Endpunkt (Reverb), das TLS-Zertifikat und die Cookie-Sicherheit automatisch davon
|
||
ab. Kein Terminal-Editieren mehr — nur „speichern und neu starten".
|
||
- **Automatisches TLS per On-Demand (Caddy).** Caddy stellt das Zertifikat beim ersten
|
||
HTTPS-Zugriff aus und fragt vorher die App (`/_caddy/ask`), ob für genau diese Domain
|
||
ausgestellt werden darf — so kann keine fremde, auf die IP gezeigte Domain Zertifikate
|
||
erzwingen. Voraussetzung bleibt: die Domain zeigt per DNS auf den Server.
|
||
|
||
### Geändert
|
||
- Der Reverb-Client (Browser) bezieht seinen Endpunkt jetzt zur Laufzeit aus der aktuellen
|
||
Anfrage und läuft über dieselbe Adresse wie das Panel (Proxy/Reverse-Tunnel `/app/*`,
|
||
`/apps/*` — Caddy in Produktion, nginx in Dev). So folgt Realtime jeder Domain-Änderung
|
||
ohne Neu-Bauen der Assets und ohne separat geöffneten Port.
|
||
- Server-seitiges Event-Publishing läuft intern direkt zum `reverb`-Dienst, ist damit
|
||
unabhängig von der öffentlichen Domain/dem Zertifikat.
|
||
|
||
### Sicherheit
|
||
- **Kein Aussperren.** Sicherer-Cookie-Schalter und HTTPS-Redirect richten sich nach der
|
||
tatsächlichen Anfrage (hinter Caddy via `X-Forwarded-*`, das nur in Produktion vertraut
|
||
wird). Der Zugriff per **IP über HTTP bleibt immer als Rückfallweg erreichbar**, falls
|
||
eine neue Domain (DNS/Zertifikat) noch nicht bereit ist.
|
||
- **Nur die aktive Domain liefert das Panel aus.** Bei gesetzter Domain wird das Panel per
|
||
Hostname ausschließlich über genau diese Domain (HTTPS) bedient; eine alte/fremde, auf den
|
||
Server gezeigte Domain wird abgewiesen (404) — auch wenn Caddy ihr Zertifikat noch hält.
|
||
|
||
## [0.3.0] - 2026-06-13
|
||
|
||
Zweisprachige Oberfläche: die gesamte UI gibt es jetzt auf Deutsch und Englisch, frei umschaltbar pro Konto.
|
||
|
||
### Hinzugefügt
|
||
- **Sprache wählbar (Deutsch / Englisch).** Ein DE/EN-Umschalter (oben rechts, sowie auf der
|
||
Login-Seite) stellt die Sprache um; die Wahl wird pro Konto gespeichert und gilt sofort für
|
||
die gesamte Oberfläche. Ohne Wahl greift die Standardsprache (Deutsch).
|
||
- Übersetzungen liegen strukturiert unter `lang/{de,en}/<gruppe>.php` — eine Gruppe je Feature
|
||
plus geteiltes `common`, Schlüssel in beiden Sprachen identisch.
|
||
|
||
### Geändert
|
||
- **Alle sichtbaren Texte sind lokalisiert.** Views, Komponenten und Backend-Services geben
|
||
Text ausschließlich über `__('gruppe.schlüssel')` aus, nie mehr fest verdrahtet — neue,
|
||
verbindliche Regel **R16**. Native Technik-Begriffe (`nginx.service`, `SSH`, `2FA`, Ports)
|
||
bleiben unverändert.
|
||
|
||
### Entfernt
|
||
- Erläuternde „Warum …?"-Texte auf der System-Seite — die Seite zeigt nur noch Funktion und
|
||
Status.
|
||
|
||
## [0.2.1] - 2026-06-13
|
||
|
||
Verfeinerungen an 0.2.0: vollautomatisches TLS ohne sichtbare Konfiguration und einheitliche Buttons.
|
||
|
||
### Geändert
|
||
- **TLS ist vollautomatisch.** Caddy stellt das Zertifikat aus, erneuert es und leitet
|
||
HTTP→HTTPS um — ohne manuelle Schritte. Die System-Seite zeigt nur noch den **Status**
|
||
(Domain, Zugriffsadresse) statt der erzeugten Caddy-Konfiguration und des
|
||
`caddy reload`-Befehls. Die Panel-Domain ist eine **Installations-Entscheidung**
|
||
(`APP_DOMAIN`) und bleibt damit konsistent mit URL, WebSocket (wss) und Cookie-Sicherheit;
|
||
zum Ändern `install.sh` mit der neuen Domain erneut ausführen.
|
||
- Härtungs-Checkliste: alle Aktions-Buttons im selben Stil (einheitlich `secondary`,
|
||
mit Rahmen) statt zustandsabhängig mal mit, mal ohne Rahmen.
|
||
|
||
### Entfernt
|
||
- Laufzeit-Override der App-URL aus der Datenbank und das dashboard-seitige Bearbeiten
|
||
von Domain/E-Mail (konnte URL/WebSocket/Cookies nicht konsistent zur Laufzeit umstellen).
|
||
Eine Migration entfernt die leeren Alt-Einträge; ein real konfigurierter Wert bleibt als
|
||
Verlauf erhalten. **Upgrade-Hinweis:** eine zuvor im Dashboard gesetzte Domain bitte einmalig
|
||
über `install.sh` setzen.
|
||
|
||
## [0.2.0] - 2026-06-13
|
||
|
||
Mehr-Betriebssystem-Verwaltung, echte Firewall- und fail2ban-Steuerung aus dem Dashboard sowie eine Tastatur-/Befehls-Bedienung.
|
||
|
||
### Hinzugefügt
|
||
- **OS-Abstraktion**: Updates, Härtung und Firewall laufen jetzt über **apt, dnf und
|
||
zypper** (Debian/Ubuntu, RHEL/Fedora/Rocky/Alma, openSUSE). Das Betriebssystem wird
|
||
erkannt und auf der Server-Detailseite angezeigt (Paketverwaltung/Firewall). Arch
|
||
und Alpine werden erkannt; nicht unterstützte Funktionen werden mit deutschem
|
||
Hinweis sauber deaktiviert statt fehlzuschlagen.
|
||
- **Firewall-Regeln (UFW)**: Regeln ansehen, hinzufügen und löschen samt
|
||
Standard-Anzeige — mit Aussperr-Schutz (SSH-Regeln/-Port, deny ohne Port). firewalld
|
||
wird nur angezeigt (Laufzeit aller aktiven Zonen inkl. Rich Rules); Regelverwaltung
|
||
bleibt vorerst UFW.
|
||
- **fail2ban-Status**: Jails mit Zählern, **gebannte IPs sehen und entsperren**,
|
||
IP manuell sperren (R5-Dialog, Aussperr-Schutz für Loopback + eigenen Zugang) und
|
||
**Whitelist (ignoreip)** verwalten.
|
||
- **Befehls-Palette (Strg/⌘-K)** + Tastenkürzel: Schnell-Navigation (Leader „g“),
|
||
Seitensuche („/“), Hilfe („?“).
|
||
|
||
### Geändert
|
||
- System-Updates verwenden je Distribution den passenden Paketmanager
|
||
(Audit-Aktion `system.package_upgrade`).
|
||
- fail2ban-Tuning und -Whitelist liegen in getrennten Drop-ins, damit Änderungen sich
|
||
nicht gegenseitig überschreiben; das frühere Einzel-Drop-in wird migriert.
|
||
- Server-Detailseite zeigt erkanntes System, Paketverwaltung und Firewall-Werkzeug.
|
||
- System-Seite erklärt jetzt, warum TLS über Caddy terminiert wird.
|
||
|
||
### Sicherheit
|
||
- Firewall: race-freies Löschen per Regel-Spezifikation (keine Regelnummern),
|
||
Whitelisting gegen Befehls-Injection, firewalld-Lockout-Schutz (Ports vor dem Start
|
||
in der permanenten Konfiguration).
|
||
- fail2ban: kanonischer (inet_pton) Schutz gegen das Sperren des eigenen Zugangs,
|
||
ignoreip wird verbatim erhalten (inkl. Hostnames/Fortsetzungszeilen).
|
||
|
||
## [0.1.1] - 2026-06-13
|
||
|
||
Wartungs-Release: vollständige Code-Auditierung, Entfernung von totem Code und ein behobenes Open-Redirect. Keine funktionalen Änderungen für Nutzer.
|
||
|
||
### Behoben
|
||
- Open-Redirect im Server-Switcher: ein manipulierter `Referer` konnte die
|
||
Weiterleitung nach dem Server-Wechsel auf eine fremde Adresse lenken. Die
|
||
Weiterleitung wird jetzt auf einen **gleich-origin** relativen Pfad reduziert
|
||
(fremde Schemata wie `javascript:`/`data:`, andere Hosts/Ports sowie
|
||
protokoll-relative Tricks `//host` / `/\host` werden abgewiesen).
|
||
- SSH-Zugang: eine Passphrase wurde unabhängig vom Auth-Typ gespeichert; sie wird
|
||
jetzt nur noch bei Schlüssel-Authentifizierung hinterlegt.
|
||
|
||
### Geändert
|
||
- Datei-Manager + Editor verwenden ein eigenes `file`-Symbol statt des
|
||
Audit-Symbols (semantisch korrekt).
|
||
- Code-Hygiene: toten Code entfernt (ungenutzte `FirewallService`-Methoden
|
||
`status/allow/deny`, `Server::auditEvents()`, `SshCredential::scopeActive()`,
|
||
ungenutztes `bell`-Icon), veraltete Doc-Blöcke/Kommentare korrigiert,
|
||
Exceptions sauber importiert, base64-Argument im Sudo-Pfad defensiv gequotet,
|
||
Null-sichere Nutzerabfrage in den Einstellungen. Pint + Codex-Review sauber.
|
||
|
||
## [0.1.0] - 2026-06-13
|
||
|
||
Erste geschnittene Version — die komplette v1-Basis inklusive Server- und Panel-Härtung als ein Release.
|
||
|
||
### Hinzugefügt
|
||
- Dashboard mit Live-Sparklines und poll-getriebenem Dual-Chart (KPIs + Tabelle).
|
||
- Server-Index + Detailseite, Dienste (systemd: Start/Stop/Restart + Journal),
|
||
Datei-Manager (SFTP: Up-/Download, Editor), Audit-Log.
|
||
- SSH-Schicht über phpseclib (exec + SFTP) mit Host-Key-Pinning (TOFU) und
|
||
Multi-Server-Switcher samt Fleet-Kontext.
|
||
- Echte Metriken (CPU/RAM/Disk/Load) inkl. Absolutwerten über Reverb.
|
||
- Authentifizierung + 2FA (TOTP) mit erzwungenem Onboarding.
|
||
- R5-Bestätigungsmodals (wire-elements/modal) für destruktive Aktionen.
|
||
- System-Seite mit Domain & TLS (Caddy Auto-TLS) und Release-Kanal.
|
||
- Echte Versions-Seite, die Version, Build-Hash und dieses Änderungsprotokoll liest.
|
||
- Deploy: `install.sh` + Caddy (Auto-TLS) + Produktions-Härtung.
|
||
- Selbst-gehostete Fonts (kein CDN), Split-Brand Login/2FA.
|
||
|
||
### Geändert
|
||
- Dienst-Steuerung läuft über das hinterlegte Sudo-Passwort (`sudo -S`) statt nur
|
||
passwortlosem sudo — Start/Stop/Restart + Journal funktionieren live.
|
||
- Lazy-Loading der Seiten (Skeletons), normalisierte Buttons + Spinner,
|
||
Detailseiten- und Einstellungs-Redesign, Schlüsselerzeugung.
|
||
- Vollständige Regel-Auditierung (R1–R14), neue Regel R14 (lokale Fonts).
|
||
|
||
### Behoben
|
||
- Datei-Editor: Klick löste einen Alpine-Fehler aus (`@js()` kompiliert nicht in
|
||
Komponenten-Attributen) — auf Index-Lookups umgestellt.
|
||
- Adversarial Review der SSH-Schicht (Escaping, Parser, Host-Key-Pinning).
|
||
- 500 durch `@disabled` auf `<x-btn>`; Modal über dem Backdrop; poll-getriebene
|
||
Metriken (Chart + Gauges) statt fiktiver Fleet-Daten; 2FA-Setup-QR als `<img>`.
|
||
- fail2ban/apt-Härtung schlug fehl, weil der 12s-SSH-Timeout den Paket-Install
|
||
abbrach — langer Timeout für apt-Aktionen.
|
||
|
||
### Sicherheit
|
||
- Server-Härtung aus dem Dashboard (Root-/Passwort-Login, fail2ban, UFW,
|
||
Auto-Updates) mit Befehls-Vorschau, Bestätigung und Aussperr-Schutz.
|
||
- Verwaltung hinterlegter SSH-Zugänge (Name, Sperren, Löschen); der Vault
|
||
verweigert gesperrte Zugänge. Dienst-Steuerung über hinterlegtes Sudo-Passwort.
|
||
- Panel-Selbst-Härtung: Security-Header + umgebungsbewusste CSP, 2FA-Brute-Force-
|
||
Drossel, Session-Cookie-Härtung.
|
||
- Release-/Versionierungsmodell: echte semantische Versionen + Git-Tags, Changelog
|
||
pro Version, Kanäle `stable`/`beta` (kein nutzer-seitiges `dev`).
|
||
|
||
[Unreleased]: https://git.bave.dev/boban/clusev/compare/v0.2.1...HEAD
|
||
[0.2.1]: https://git.bave.dev/boban/clusev/compare/v0.2.0...v0.2.1
|
||
[0.2.0]: https://git.bave.dev/boban/clusev/compare/v0.1.1...v0.2.0
|
||
[0.1.1]: https://git.bave.dev/boban/clusev/compare/v0.1.0...v0.1.1
|
||
[0.1.0]: https://git.bave.dev/boban/clusev/releases/tag/v0.1.0
|