Security pivot — make server hardening, SSH access, firewall, dashboard domain/TLS and the release channel controllable from the dashboard (no SSH needed), with guards so a remote change can never lock the operator out. Foundation - ssh_credentials gains name + disabled_at + last_used_at; CredentialVault refuses a disabled credential. New key/value Setting model. FleetService::runPrivileged() / runPlain() — central sudo-aware exec (base64-wrapped sh -c), live-verified as root. A · control-plane self-hardening - SecurityHeaders middleware: env-aware CSP (allows the Vite dev origin in dev, strict same-origin in prod), X-Frame-Options DENY, nosniff, Referrer/Permissions-Policy, HSTS when secure. 2FA brute-force throttle (5/60s). install.sh sets SESSION_SAME_SITE=strict + EXPIRE_ON_CLOSE + SECURE_COOKIE (only behind TLS). B · SSH credential management - name/label on the access; a credential card on the server page with Bearbeiten / Sperren-Entsperren (kill-switch) / Löschen (R5), all audited. C · server hardening from the dashboard (guards + confirmation) - HardeningService (PermitRootLogin no, PasswordAuthentication no, fail2ban, unattended-upgrades) + FirewallService (UFW). HardeningAction modal previews the exact root commands before applying. GUARDS: refuse to disable password-login when Clusev itself logs in by password or no key exists; UFW opens the real sshd port + 80/443 before enabling. Live-verified non-destructively (previews, the password guard refusing, ufw status read). D+E · System page (/system) - Dashboard Domain + Let's-Encrypt email (Setting) -> DeploymentService renders the matching Caddy site block (honest: stages the file + shows the reload command, never fakes TLS). Release channel (stable|beta|dev) configurable; Versions reads it. Built largely by 4 parallel agents into disjoint files; shared files integrated + the security-critical bits hardened by hand (the password-auth lock-out guard + env-aware CSP). Verified (R12): /system + server detail + all 8 routes 200 / 0 console errors (CSP does not break Livewire/Alpine/Vite); credential card + 5 hardening "Anwenden" buttons render; the hardening modal opens with the command preview; System persists domain/channel + renders valid Caddy config; runPrivileged runs as root + the vault refuses disabled creds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| app | ||
| bootstrap | ||
| config | ||
| database | ||
| docker | ||
| docs | ||
| public | ||
| resources | ||
| routes | ||
| storage | ||
| tests | ||
| .dockerignore | ||
| .editorconfig | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| Dockerfile | ||
| README.md | ||
| artisan | ||
| composer.json | ||
| composer.lock | ||
| docker-compose.prod.yml | ||
| docker-compose.yml | ||
| handoff.md | ||
| install.sh | ||
| kickoff-prompt.md | ||
| package-lock.json | ||
| package.json | ||
| phpunit.xml | ||
| rules.md | ||
| vite.config.js | ||
README.md
Clusev
Self-hosted control panel to administer a fleet of Linux servers from one dashboard, agentless over SSH. Clusev is the control-plane (UI + orchestration); it talks to real servers with phpseclib (exec + SFTP) — it never reimplements daemons. Security-first: 2FA, encrypted SSH-credential vault, and a full audit log. Multi-server is free and never paywalled.
Status: v1 — dashboard/live metrics, systemd services, SFTP file manager, server details, auth + 2FA. UI copy is German; meta-docs are English.
Stack: Laravel 13 · Livewire 3 · Tailwind v4 · Reverb (realtime) · Redis · MariaDB · phpseclib3.
Everything runs in Docker. See CLAUDE.md for architecture and rules.md for the hard conventions.
Development
The host needs only Docker (no PHP/Composer/Node). The dev app container runs php-fpm + nginx +
Vite via supervisor; reverb, queue, mariadb, redis are their own services.
cp .env.example .env # then set DB_PASSWORD / DB_ROOT_PASSWORD
docker compose up -d --build # app on :80, Vite HMR on :5173
docker compose run --rm --no-deps -u "${HOST_UID:-1002}:${HOST_GID:-1002}" app php artisan key:generate
docker compose exec app php artisan migrate --seed
Run any tooling inside the container, e.g.
docker compose exec app php artisan make:livewire Servers/Show (class-based — never Volt).
Production install
One host, only Docker + a sudo user. Caddy is the single host-exposed service: auto-TLS when a
domain is set, plain HTTP on the bare IP otherwise. install.sh is idempotent — it generates
secrets once (never regenerates), brings up the prod stack, migrates, and creates the first admin
with a one-time random password printed only on the terminal.
git clone https://git.bave.dev/boban/clusev.git && cd clusev
./install.sh
Prompts (non-interactive: set CLUSEV_DOMAIN / CLUSEV_ADMIN_EMAIL in the environment):
Domain (empty = access by IP over HTTP): clusev.example.com
Admin e-mail (login + Let's Encrypt): admin@example.com
The closing banner shows the URL + the one-time admin password. On first login Clusev forces a password change and 2FA enrolment before the panel unlocks.
One knob: APP_DOMAIN
APP_DOMAIN |
proxy | URL | Reverb |
|---|---|---|---|
| (empty) | Caddy serves plain HTTP on APP_PORT |
http://<ip> |
ws://<ip>/app/* |
clusev.example.com |
Caddy gets a Let's Encrypt cert, forces HTTPS | https://… |
wss://…/app/* |
SITE_ADDRESS, APP_URL, REVERB_* are derived from it by the installer — nothing hardcoded.
Bare-IP mode serves 2FA/audit over cleartext HTTP; the installer warns loudly. Let's Encrypt needs
publicly reachable 80/443 — a private (RFC1918) target needs a DNS-01 Caddy build instead.
Manual deploy (for operators who don't curl | bash)
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d
docker compose -f docker-compose.prod.yml exec -u app app php artisan migrate --force
docker compose -f docker-compose.prod.yml exec -u app app php artisan clusev:install --email=admin@example.com
In-dashboard updates (signed intent file + host-side updater, digest-pinned, cosign-verified, 2FA-gated, with backup + rollback) are designed in
docs/install-update-design.mdand land in v1.x — they are intentionally not shipped yet.
License
AGPL core + commercial Pro modules (open-core). Multi-server fleet management is always free.