116 lines
6.2 KiB
Markdown
116 lines
6.2 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
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:
|
|
|
|
1. Installs **Docker** (Debian/Ubuntu, from Docker's official repository) if it isn't already present.
|
|
2. Creates a dedicated **`clusev`** system user — in the `docker` group, owning and running the stack —
|
|
with a random password.
|
|
3. Asks for a **domain** (leave empty for IP access) and an **admin e-mail** (leave empty for the
|
|
default **`admin@clusev.local`**), or reads `CLUSEV_DOMAIN` / `CLUSEV_ADMIN_EMAIL` from 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.
|
|
4. 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).
|
|
5. 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_CIDR` to 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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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>.
|