# 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.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 `
` 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}/.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 ``; Modal über dem Backdrop; poll-getriebene Metriken (Chart + Gauges) statt fiktiver Fleet-Daten; 2FA-Setup-QR als ``. - 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