diff --git a/README.md b/README.md index 4fa4247..3b8fc5e 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,19 @@ Auf dem Proxmox-Host als root: ```bash git clone pvesnap && cd pvesnap -./install.sh +./install.sh # nur der Snapshot-Dienst +./install.sh --with-webexplorer --port 8823 # zusätzlich die Web-Oberfläche +./install.sh --help # alle Optionen ``` +| Option | | +|---|---| +| `--with-webexplorer` | Web-Oberfläche als Dienst einrichten (**erfordert `--port`**) | +| `--port ` | Port der Web-Oberfläche | +| `--bind ` | Adresse, auf der sie lauscht (Vorgabe `0.0.0.0`) | +| `--no-start` | installieren, aber Dienste nicht starten | +| `--force` | auch ohne erkanntes Proxmox VE installieren | + Das Skript legt an: | Pfad | Inhalt | @@ -38,7 +48,9 @@ Das Skript legt an: | `/usr/local/bin/pvesnap-web` | Web-Oberfläche | | `/etc/pvesnap/pvesnap.conf` | Konfiguration (wird bei Updates **nicht** überschrieben) | | `/var/lib/pvesnap/state.json` | merkt sich die letzten Läufe | -| `/etc/systemd/system/pvesnap.service` | systemd-Unit | +| `/etc/systemd/system/pvesnap.service` | systemd-Unit des Snapshot-Dienstes | +| `/etc/systemd/system/pvesnap-web.service` | Unit der Web-Oberfläche (nur mit `--with-webexplorer`) | +| `/etc/pvesnap/web.conf` | Port und Anmeldeart der Web-Oberfläche | In der mitgelieferten Beispielkonfiguration sind alle Gruppen auf `enabled = no` gesetzt — es passiert also erst etwas, wenn du eine Gruppe aktivierst. @@ -389,37 +401,71 @@ bleiben Verweise. ### `pvesnap-web` — im Browser herunterladen +Als Dienst (empfohlen, überlebt Neustarts): + +```bash +./install.sh --with-webexplorer --port 8823 +``` + +Danach läuft die Oberfläche dauerhaft auf `http://:8823/`. Port, Adresse +und Anmeldeart stehen in `/etc/pvesnap/web.conf`: + +``` +PVESNAP_WEB_ARGS=--bind 0.0.0.0 --port 8823 --auth pve +``` + +Nach Änderungen `systemctl restart pvesnap-web`. Oder von Hand für einen +einzelnen Einsatz: + ```bash pvesnap-web # Gast und Snapshot im Browser wählen pvesnap-web 802 # diesen Snapshot gleich öffnen -pvesnap-web --port 8080 --bind 10.0.0.5 +pvesnap-web --path /verzeichnis # beliebiges Verzeichnis (ohne Proxmox) ``` -Beim Start wird eine Adresse mit Zugangsschlüssel ausgegeben: +**Anmeldung mit den Proxmox-Benutzern.** Die Oberfläche zeigt dieselbe +Anmeldemaske wie Proxmox — Benutzername, Passwort, Realm-Auswahl. Geprüft wird +über `POST /access/ticket` auf der lokalen Proxmox-API, also genau den Weg, den +auch das Proxmox-Webinterface geht. Alle Realms (`pam`, `pve`, LDAP, AD …) +funktionieren damit automatisch. Zwei-Faktor-Anmeldungen werden abgewiesen statt +halb durchgewinkt. + +**Wer darf was sehen?** Ein gültiges Passwort allein reicht nicht — sonst könnte +jeder Proxmox-Benutzer sämtliche Dateien aller Gäste lesen. Zusätzlich muss der +Benutzer auf dem jeweiligen Gast das Recht **`VM.Snapshot`** besitzen (geprüft +auf `/`, `/vms`, `/vms/` und dem Pool des Gastes). In der Gastliste tauchen +nur Gäste auf, für die das zutrifft; `root@pam` sieht wie in Proxmox alles. +Anpassen mit: ``` - http://192.168.1.50:8823/?token=zGo-1RW7eYyf_YCPvTIOLtOp +--require-privilege VM.Backup # anderes Recht verlangen +--allow-user backup@pve # einzelne Benutzer generell zulassen +--auth token # stattdessen Schlüssel in der Adresse +--auth none # ohne Anmeldung (nur im vertrauten Netz) ``` -Diese Adresse an einem anderen Rechner im Browser öffnen. Dort lässt sich der -Snapshot durchklicken; **einzelne Dateien** werden direkt heruntergeladen, -**Verzeichnisse und Mehrfachauswahl** als ZIP (im Strom erzeugt, es wird nichts -zwischengespeichert). +Ohne Proxmox (`--path`) gibt es keine Benutzer — dort wird automatisch ein +Zugangsschlüssel erzeugt und beim Start als Adresse ausgegeben. + +**Bedienung:** Snapshot anklicken, durchklicken; **einzelne Dateien** werden +direkt heruntergeladen, **Verzeichnisse und Mehrfachauswahl** als ZIP (im Strom +erzeugt, es wird nichts zwischengespeichert). Zur Sicherheit: -* Ohne den Zugangsschlüssel gibt es nichts zu sehen (er wandert nach dem ersten - Aufruf in ein Cookie). `--no-token` schaltet das ab — nur in einem Netz - benutzen, dem du vertraust. * Es wird ausschließlich **gelesen**. Die Oberfläche kann nichts ändern oder löschen. * Pfade außerhalb des eingebundenen Snapshots werden abgewiesen — über die Adresszeile kommt man nicht an den Rest des Hosts. -* Die Verbindung ist unverschlüsseltes HTTP. Über unsichere Netze besser einen - SSH-Tunnel legen: - `ssh -L 8823:localhost:8823 root@pve` und dann `pvesnap-web --bind 127.0.0.1`. +* Fehlgeschlagene Anmeldungen landen mit Absender-IP im Journal + (`journalctl -u pvesnap-web`). +* Die Verbindung ist unverschlüsseltes HTTP — Passwörter gehen im Klartext über + das Netz. Über unsichere Netze deshalb besser einen SSH-Tunnel legen: + `ssh -L 8823:localhost:8823 root@pve`, dazu in `web.conf` + `--bind 127.0.0.1` setzen. -Beendet wird mit `Strg-C`; der Snapshot wird dabei wieder ausgehängt. +Beim Beenden (`Strg-C` oder `systemctl stop pvesnap-web`) wird ein offener +Snapshot wieder ausgehängt. --- diff --git a/install.sh b/install.sh index 594ddd2..09f20e3 100755 --- a/install.sh +++ b/install.sh @@ -2,9 +2,25 @@ # --------------------------------------------------------------------- # pvesnap - Installation # -# ./install.sh installieren, Dienst aktivieren und starten -# ./install.sh --no-start installieren, aber Dienst nicht starten -# ./install.sh --force auch ohne erkanntes Proxmox VE installieren +# Aufruf: ./install.sh [Optionen] +# +# --with-webexplorer Web-Oberflaeche zusaetzlich als Dienst +# einrichten (pvesnap-web.service). +# Erfordert --port. +# --port Port fuer die Web-Oberflaeche, z.B. 8823 +# --bind Adresse, auf der sie lauscht +# (Vorgabe: 0.0.0.0 = alle) +# --no-start installieren, aber Dienste nicht starten +# --force auch ohne erkanntes Proxmox VE installieren +# -h, --help diese Hilfe +# +# Beispiele: +# ./install.sh +# ./install.sh --with-webexplorer --port 8823 +# ./install.sh --with-webexplorer --port 8443 --bind 10.0.0.5 +# +# Die Web-Oberflaeche meldet Benutzer gegen Proxmox VE an - dieselben +# Zugangsdaten und Realms wie im Proxmox-Webinterface. # --------------------------------------------------------------------- set -euo pipefail @@ -15,25 +31,64 @@ CONF="${CONF_DIR}/pvesnap.conf" STATE_DIR="/var/lib/pvesnap" DOC_DIR="/usr/share/doc/pvesnap" UNIT="/etc/systemd/system/pvesnap.service" +WEB_UNIT="/etc/systemd/system/pvesnap-web.service" +WEB_CONF="${CONF_DIR}/web.conf" SRC="$(cd "$(dirname "$0")" && pwd)" START=1 FORCE=0 -for arg in "$@"; do - case "$arg" in +WEB=0 +WEB_PORT="" +WEB_BIND="0.0.0.0" +while [ $# -gt 0 ]; do + case "$1" in + --with-webexplorer) WEB=1 ;; + --port) WEB_PORT="${2:-}"; shift ;; + --port=*) WEB_PORT="${1#*=}" ;; + --bind) WEB_BIND="${2:-}"; shift ;; + --bind=*) WEB_BIND="${1#*=}" ;; --no-start) START=0 ;; --force) FORCE=1 ;; - -h|--help) sed -n '2,8p' "$0" | sed 's/^#[[:space:]]\{0,1\}//'; exit 0 ;; - *) echo "Unbekannte Option: $arg" >&2; exit 1 ;; + -h|--help) sed -n '2,24p' "$0" | sed 's/^#[[:space:]]\{0,1\}//'; exit 0 ;; + *) echo "Unbekannte Option: $1" >&2 + echo "Hilfe mit: $0 --help" >&2; exit 1 ;; esac + shift done info() { printf '\033[1;32m==>\033[0m %s\n' "$*"; } warn() { printf '\033[1;33m==>\033[0m %s\n' "$*" >&2; } fail() { printf '\033[1;31m==>\033[0m %s\n' "$*" >&2; exit 1; } +# --- Web-Oberflaeche: Angaben pruefen --------------------------------- +if [ "$WEB" -eq 1 ]; then + if [ -z "$WEB_PORT" ]; then + fail "--with-webexplorer benoetigt einen Port. + Beispiel: ./install.sh --with-webexplorer --port 8823 + Hilfe mit: $0 --help" + fi + case "$WEB_PORT" in + ''|*[!0-9]*) fail "--port erwartet eine Zahl, bekommen: '$WEB_PORT'" ;; + esac + if [ "$WEB_PORT" -lt 1 ] || [ "$WEB_PORT" -gt 65535 ]; then + fail "--port muss zwischen 1 und 65535 liegen (bekommen: $WEB_PORT)" + fi + if [ "$WEB_PORT" -eq 8006 ]; then + fail "Port 8006 gehoert dem Proxmox-Webinterface - bitte einen anderen waehlen." + fi + if ss -ltn 2>/dev/null | grep -qE "[:.]${WEB_PORT}[[:space:]]"; then + warn "Auf Port ${WEB_PORT} lauscht bereits etwas - der Dienst wird sich " + warn "moeglicherweise nicht starten lassen." + fi + [ -n "$WEB_BIND" ] || fail "--bind erwartet eine Adresse" +elif [ -n "$WEB_PORT" ]; then + fail "--port wirkt nur zusammen mit --with-webexplorer." +fi + [ "$(id -u)" -eq 0 ] || fail "Bitte als root ausfuehren (sudo ./install.sh)." + + command -v python3 >/dev/null 2>&1 || fail "python3 wird benoetigt." python3 - <<'PY' || fail "Python 3.7 oder neuer wird benoetigt." import sys @@ -107,13 +162,45 @@ else warn "Dienst konnte nicht aktiviert werden - bitte 'systemctl enable pvesnap' pruefen." fi +# --- Web-Oberflaeche als Dienst --------------------------------------- +if [ "$WEB" -eq 1 ]; then + info "Richte Web-Oberflaeche als Dienst ein (Port ${WEB_PORT})" + cat > "${WEB_CONF}" </dev/null 2>&1; then + info "Web-Oberflaeche beim Systemstart aktiviert" + else + warn "pvesnap-web konnte nicht aktiviert werden." + fi +fi + if [ "$START" -eq 1 ]; then info "Starte Dienst" systemctl restart pvesnap.service sleep 1 systemctl --no-pager --lines=5 status pvesnap.service || true + if [ "$WEB" -eq 1 ]; then + info "Starte Web-Oberflaeche" + systemctl restart pvesnap-web.service + sleep 1 + systemctl --no-pager --lines=3 status pvesnap-web.service || true + fi else - warn "Dienst wurde nicht gestartet." + warn "Dienste wurden nicht gestartet." fi cat <:${WEB_PORT}/ + Anmeldung : Benutzer von Proxmox VE (gleiche Zugangsdaten wie dort) + Einstellungen : ${WEB_CONF} + Status : systemctl status pvesnap-web + Protokoll : journalctl -u pvesnap-web -f + +Sichtbar ist ein Gast nur fuer Benutzer mit dem Recht VM.Snapshot darauf; +root@pam sieht alles. Anzupassen in ${WEB_CONF}. +EOF +fi + if [ "${NEW_CONFIG:-0}" -eq 1 ]; then cat <