Commit Graph

3 Commits (4e32f76d1bddf3c39bee4fcfb652f1b15ffe3c10)

Author SHA1 Message Date
boban ec1516184e i18n: complete DE/EN localization (modals, shell, backend) + v0.3.0
- modals: wire 5 hard-coded views + 10 components to lang/{de,en}/modals.php
- shell: command-palette (incl. app.js cmdk(nav,actions) refactor), server-item,
  toaster fallback
- backend: new lang/{de,en}/backend.php; localize Hardening/Firewall/Fail2ban/
  Maintenance services, OsProfile, plus FleetService + CredentialVault errors
- fix: localized page <title> on Dashboard/Servers index+show (->title(), the
  Livewire-3 way; the stray title() methods were never auto-called)
- fix: topbar inline @php() was swallowed by Blade's raw-block precompiler up to a
  later @endphp -> 500 on every authed page; converted to block @php ... @endphp
- versions: localize changelog section labels via a canonical heading map
- translation-quality pass: Unlock, Add credentials, clearer auth/notify copy

Bump 0.2.1 -> 0.3.0; CHANGELOG.

Verified: Pint clean; npm build OK; R12 all routes HTTP 200 + 0 console errors in
BOTH locales (titles/nav/labels switch language); 589 used keys resolve in de+en
with full group parity; Codex review clean; adversarial DE/EN audit (0 high).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 23:27:42 +02:00
boban e792e9a3af feat(fail2ban): jail status, banned-IP list + unban, manual ban, whitelist
Addresses "ich sehe nicht welche IPs gebannt sind / entsperren / whitelist". The
server-detail page gains a "fail2ban-Status" panel.

New Fail2banService (owns all fail2ban I/O):
- status(): jails with currently/total failed+banned + the banned IP list, plus the
  whitelist; sentinel-guarded, and a CLIENT_OK marker so an active service whose
  fail2ban-client query fails is reported as a read error, not "0 jails".
- unban() (idempotent: "not banned" = success), manual ban() GUARDED against loopback
  (whole 127.0.0.0/8 + ::1) and Clusev's own SSH source (canonical inet_pton compare).
- readConfig()/writeTuning()/writeIgnoreip(): tuning and whitelist live in SEPARATE
  zz- drop-ins and each writes only its own keys, so a whitelist change can never
  rewrite the ban policy (and vice-versa). The legacy single-file zz-clusev.local is
  removed on tuning save (migration). ignoreip is preserved VERBATIM (hostnames/CIDRs,
  continuation lines) — loopback always re-seeded; add/remove report no-ops so the
  audit only records real changes.

UI: jails + banned IPs each with "Entsperren" (direct, audited), whitelist editor
(add/remove, audited), "IP sperren" via an R5 modal (modals.fail2ban-ban). Jail/IP
args are Js::from()-encoded (remote-sourced, injection-safe). Direct handlers catch
SSH failures. Tuning modal migrated to Fail2banService.writeTuning.

MaintenanceService slimmed to package updates only (fail2ban moved out).

Pint clean; Codex review clean (IPv6 guard, verbatim ignoreip, decoupled drop-ins,
legacy migration, read-error detection all hardened); R12 — server-detail HTTP 200,
0 console errors, fail2ban panel + jail + whitelist render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 20:27:55 +02:00
boban 05f8ce49b4 feat: add-server, apt updates, fail2ban config; clean modals; drop storage internals
Operator feedback: no way to add servers; irrelevant storage-internals text; fail2ban
only on/off; raw shell commands shown; no apt update/upgrade.

- Add server: CreateServer modal (name, IP/host, SSH port, user, password|key, optional
  label) on the Servers index → creates server + encrypted credential ATOMICALLY (DB
  transaction). Strict IP/hostname validation (filter_var + hostname; rejects 999.x, ':').
- System updates (Debian/Ubuntu only): MaintenanceService + SystemUpdate modal — shows the
  pending-update count (or "unbekannt" when undeterminable) and runs apt update && upgrade
  as root; gated to apt hosts.
- fail2ban configuration: Fail2banConfig modal — Sperrdauer / Max. Fehlversuche / Zeitfenster,
  written to a Clusev-owned jail.d drop-in (zz-clusev.local, last-wins; never touches the
  operator's jail.local/jails). Durations kept verbatim in fail2ban's native grammar
  (600, 10m, 1h 30m, -1). Reads the EFFECTIVE [DEFAULT] across files; refuses to save when the
  current policy couldn't be read (no overwrite with unseen defaults); reloads fail2ban only
  when already active (never starts it).
- Modals: removed the raw "Befehle (als root)" preview + raw stdout dumps from the hardening
  modal — clean German description + result only.
- System page: dropped the .env/Datenbank storage-internals callout (irrelevant to the user).

R15 — Codex gate: `codex review --uncommitted` run iteratively; fixed every finding across 9
rounds (fail2ban jail clobbering, section/precedence, composite/-1 durations, reload-starting-
inactive, read-failure propagation, glob exit code, apt-count failure, atomic server create,
IP validation) until clean — 0 security issues throughout. Live-verified on 10.10.90.162;
R12: Servers/Detail/System 200 / 0 console errors, modals open, hardening modal shows no commands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:19:55 +02:00