chore: release 0.9.27 — Anmeldeschutz (control-plane brute-force IP ban)

feat/v1-foundation v0.9.27
boban 2026-06-20 18:58:24 +02:00
parent 6c81ea7fd1
commit 77d50d44e5
2 changed files with 23 additions and 1 deletions

View File

@ -13,6 +13,28 @@ getaggte Releases (Kanal `stable`, optional `beta`) — niemals Entwicklungs-Bui
_Keine offenen Änderungen — der nächste Stand wird hier gesammelt und als `vX.Y.Z` getaggt._
## [0.9.27] - 2026-06-20
### Hinzugefügt
- **Anmeldeschutz — Brute-Force-Sperre für das Panel-Login selbst.** Nach zu vielen fehlgeschlagenen
Anmelde- oder 2FA-Versuchen wird die Quell-IP zeitlich gesperrt (Standard: 10 Versuche in 10 Min →
60 Min Sperre). Durchgesetzt auf HTTP-Ebene für **nicht angemeldete** Anfragen — eingeloggte
Operatoren werden nie geblockt und können ihre eigene IP weiterhin im Panel entsperren. (Eigenständig
von der Flotten-fail2ban-Verwaltung, die entfernte Server härtet.)
- **Neuer Einstellungs-Reiter „Anmeldeschutz"** (Einstellungen → Anmeldeschutz): An/Aus, max. Versuche,
Zeitfenster, Bann-Dauer, Whitelist (IP/CIDR), Liste aktiver Sperren mit Entsperren / Alle entsperren,
plus „Meine IP zur Whitelist hinzufügen".
- **Host-Befehl `clusev unban <ip>` (`--all`)** als Notfall-Ausweg, falls man sich aussperrt — analog
zu `clusev reset-admin`.
- Fehlgeschlagene Logins und 2FA-Versuche sowie Sperren/Entsperrungen landen jetzt im **Audit-Log**
(`auth.login_failed`, `auth.2fa_failed`, `auth.ip_banned`, `auth.ip_unbanned`).
### Sicherheit
- Loopback und private Netze sind standardmäßig ausgenommen (gegen Selbst-Aussperrung). Der
IP-Vergleich erfolgt kanonisch (inet_pton; IPv4-mapped-IPv6 wird auf die IPv4-Form zusammengefasst),
damit eine Sperre nicht über zwei Schreibweisen derselben Adresse umgangen werden kann. Sperren sind
immer zeitlich begrenzt — es gibt keinen permanenten Lockout.
## [0.9.26] - 2026-06-20
### Hinzugefügt

View File

@ -2,7 +2,7 @@
return [
// First tagged release is v0.1.0 (semantic, not -dev).
'version' => '0.9.26',
'version' => '0.9.27',
// Deployed commit + branch. install.sh bakes these into .env from the host's .git (the prod
// image ships no .git); the Versions page prefers them and falls back to a live .git read in