Even with authenticatorAttachment=cross-platform, Bitwarden's extension intercepted navigator.credentials.create and offered to save a passkey. Add the WebAuthn L3 'hints: [security-key]' to both registration and assertion options; browsers and passkey managers that honor hints step aside and let the hardware key prompt through. Injected into the client payload only (the session copy used for server validation is unchanged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| app | ||
| bootstrap | ||
| config | ||
| database | ||
| docker | ||
| docs | ||
| lang | ||
| 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 | ||
| update.sh | ||
| vite.config.js | ||
README.md
Clusev
Self-hosted control panel for a fleet of Linux servers — one dashboard, agentless over SSH.
Clusev is the control plane: a modern, security-first web UI that administers your servers by talking to them directly over SSH (exec + SFTP via phpseclib). It installs nothing on the target machines and never reimplements their daemons. Multi-server management is free and never paywalled.
Features
- Dashboard & live metrics — CPU, memory, load and disk per server, streamed in real time.
- systemd services — list, start/stop/restart, live journal tail.
- SFTP file manager — browse, edit text files, preview images.
- Server details & hardening — resource gauges, volumes, interfaces, SSH keys; UFW/firewalld rules and fail2ban status with one-click controls; and a one-click "generate an SSH key and disable password login, safely" flow.
- Security — optional, pluggable 2FA (TOTP and/or hardware security keys, or off), one-time backup codes, an encrypted SSH-credential vault, and a complete, tamper-evident audit log.
- Multiple administrators — add further admin accounts; every action is attributed in the audit log; view and revoke active sessions (per device, per user, or globally).
- Domain, TLS & e-mail — run on a bare IP over HTTP, set a domain for automatic HTTPS, or put your own reverse proxy in front. Configure SMTP in-panel for password-reset e-mails.
The panel is built on Laravel 13, Livewire 3, Tailwind v4, Laravel Reverb (realtime), Redis, MariaDB and phpseclib — all running in Docker. The interface is in German (English available).
Requirements
- A Debian or Ubuntu server (a small VM is enough) with root access.
- A public IP. Optionally a domain whose DNS points at the server (for automatic HTTPS).
- Only git to fetch the repo (one line below) — the installer sets up Docker and everything else.
Install
sudo apt-get update && sudo apt-get install -y git # minimal images often lack git
git clone https://git.bave.dev/boban/clusev.git
cd clusev
sudo ./install.sh
The installer is idempotent (safe to re-run) and, in one pass:
- Installs Docker (Debian/Ubuntu, from Docker's official repository) if it isn't already present.
- Creates a dedicated
clusevsystem user — in thedockergroup, owning and running the stack — with a random password. - Asks for a domain (leave empty for IP access) and an admin e-mail (leave empty for the
default
admin@clusev.local), or readsCLUSEV_DOMAIN/CLUSEV_ADMIN_EMAILfrom the environment for an unattended install. If you give a domain it checks whether DNS already points here: if so a certificate is obtained automatically; if not, it warns you and lets you take the domain anyway (HTTP until DNS is correct) or continue on the IP. - Generates all secrets (once — never regenerated on re-run), builds the image, starts the stack,
runs the migrations, and creates the first administrator with the default password
clusev(you are forced to change it on first login). - Installs a themed host login banner (MOTD) showing the dashboard address and live stack status.
When it finishes, the terminal prints a single summary: the dashboard URL, the admin login
(your e-mail — admin@clusev.local if you left it empty — plus the default password clusev),
and the clusev host user + its random password (shown only once — note it down).
Log in with your admin e-mail (default admin@clusev.local) and the password clusev — the
panel then forces you to set a new password immediately. Do this right away: clusev is a known
default, so the account is only safe once you've changed it. You can change the login e-mail later
under Settings → Profile. 2FA is optional but recommended — enable TOTP and/or a security key
from Settings → Security whenever you like.
Access, domain & TLS
- Bare IP (no domain): served over plain HTTP at
http://<server-ip>. This address always stays reachable as a recovery path, even after a domain is configured. - With a domain: set it during install or later under System → Domain & TLS. The panel obtains and renews a Let's Encrypt certificate automatically and serves HTTPS — just point DNS at the server. (Let's Encrypt needs publicly reachable ports 80/443.)
- Behind your own reverse proxy (one that already terminates TLS): switch TLS-Terminierung to
Externer Reverse-Proxy in System → Domain & TLS. The panel then serves HTTP only and trusts the
proxy's forwarded scheme — set
TRUSTED_PROXY_CIDRto the proxy's address and firewall the HTTP port so only the proxy can reach it.
Domain/TLS changes apply on a stack restart — use the "Jetzt neu starten" button in System (no terminal needed; a small, scoped host service performs the restart).
Updating
cd clusev
sudo ./update.sh # pulls the latest code, then rebuilds, restarts and migrates
update.sh fast-forwards the repo (it never discards local changes), re-runs the idempotent
installer non-interactively, and updates itself if the script changed. Secrets and the configured
domain / e-mail are preserved. (The older two-step git pull && sudo ./install.sh still works.)
Account recovery
The forgot-password screen offers self-service recovery: an e-mail reset link (valid 15 minutes) when SMTP is configured, or an inline 2FA-proof reset (e-mail + TOTP or a backup code + new password) as a fallback.
Completely locked out (lost password and 2FA, no SMTP)? Recover from the host:
cd clusev
docker compose -f docker-compose.prod.yml exec app php artisan clusev:reset-admin
This clears the second factor so you can set a new password on the next login. The bare-IP
http://<server-ip> address is also always available if a domain becomes unreachable. (This command
is documented in-panel under Settings → Security and is deliberately not shown on the public
forgot-password screen.)
License
Open core, AGPL-3.0 — multi-server fleet management is always free; optional Pro modules (SSO/LDAP, RBAC, audit export, alerting) are separate. Project home: https://git.bave.dev/boban/clusev.