Files
deskhub/plugin-webseite
2026-10-25 17:58:33 +00:00
..
2026-10-25 17:58:33 +00:00
2026-10-25 17:58:33 +00:00
2026-10-21 16:55:37 +00:00
2026-10-21 16:55:37 +00:00
2026-10-16 18:42:18 +00:00
2026-10-16 18:42:18 +00:00
2026-10-16 18:42:18 +00:00
2026-10-25 17:58:33 +00:00
2026-10-25 17:58:33 +00:00
2026-10-21 16:55:37 +00:00
2026-10-25 17:58:33 +00:00
2026-10-16 18:42:18 +00:00
2026-10-16 18:42:18 +00:00
2026-10-21 16:55:37 +00:00
2026-10-21 16:55:37 +00:00
2026-10-21 16:55:37 +00:00
2026-10-16 18:42:18 +00:00
2026-10-25 17:58:33 +00:00
2026-10-16 18:42:18 +00:00
2026-10-16 18:42:18 +00:00
2026-10-25 17:58:33 +00:00
2026-10-16 18:42:18 +00:00
2026-10-16 18:42:18 +00:00
2026-10-16 18:42:18 +00:00
2026-10-16 18:42:18 +00:00
2026-10-21 16:55:37 +00:00
2026-10-25 17:58:33 +00:00

DeskHub Plugin- und Theme-Webseite

Eigenständige Webseite, von der DeskHub-Installationen Plugins und Kundenportal-Themes laden können. Sie ist unabhängig von DeskHub: eigener Webspace, eigene Datenbank (SQLite), keine DeskHub-Dateien nötig.

Was sie kann

  • Verwaltung mit allen Paketen, Versionen, Signaturstatus und Download-Zähler (keine öffentliche Übersichtsseite: Die Startseite führt zur Verwaltung)
  • Katalog für DeskHub: catalog.php?type=plugins und catalog.php?type=themes
  • Verwaltung (admin.php): Pakete hochladen, Versionen entfernen, Vorschaubilder
  • Prüft jedes Paket beim Hochladen (Dateitypen, Pfade, plugin.json, Berechtigungen) und signiert es automatisch mit eurem privaten Schlüssel
  • Veröffentlichte Versionen sind unveränderlich: Für Änderungen gibt es eine neue Version

Voraussetzungen

PHP 8.1 oder neuer mit den Erweiterungen zip, openssl, pdo_sqlite; Apache (.htaccess mitgeliefert) oder nginx. HTTPS ist Pflicht, DeskHub lädt nur über https.

Einrichten

  1. Den Ordner plugin-webseite auf euren Webspace hochladen (eigene Domain oder Unterdomain, z. B. plugins.example.de).

  2. Auf dem Server (oder lokal und dann hochladen) ausführen:

    php einrichten.php
    

    Das Skript fragt Name, öffentliche Adresse und Admin-Zugang ab, erzeugt den Signierschlüssel und schreibt config.php. Den Ordner mit dem privaten Schlüssel legt es bewusst außerhalb des Webverzeichnisses an.

  3. Den privaten Schlüssel herausgeber-privat.pem sichern (Passwortmanager oder verschlüsselte Sicherung) und nie weitergeben. Geht er verloren, müssen alle Admins einen neuen öffentlichen Schlüssel eintragen.

  4. Unter https://eure-domain/admin.php anmelden und das erste Paket veröffentlichen.

nginx: Zugriff auf inc/, storage/, config.php, config.example.php und einrichten.php sperren (z. B. location ~ ^/(inc|storage)/ { deny all; } und location ~ ^/(config|config\.example|einrichten)\.php$ { deny all; }).

Nur geprüfte Plugins für eure Kunden

Setzt den Katalog dieser Webseite als offiziellen Katalog eurer DeskHub-Version: php einrichten.php und die Verwaltung („Einstellungen für DeskHub“) geben den Inhalt für includes/catalog_defaults.php aus. Nach dem Eintragen und Bauen eines Releases installieren eure Kunden Katalog-Plugins nur noch mit eurer Signatur, also nur, was ihr hier veröffentlicht habt. Eigene, unsignierte Plugins können Kunden weiterhin selbst hochladen; sie sind als „Eigenes Plugin“ markiert. Der Katalog ist per Zugangsschlüssel geschützt: Beim Docker-Bau erzeugt docker-build die Datei schluessel/katalog-zugangsschluessel.txt und gibt den Schlüssel aus. Er gehört als access_key in includes/catalog_defaults.php. Ohne ihn antworten catalog.php, download.php, preview.php und publisher-key.php mit 401 (health.php bleibt offen).

Pakete veröffentlichen

Plugin: ZIP mit plugin.json (slug, name, version, optional description, author, requires, permissions), siehe die DeskHub-Anleitung. Alle Angaben liest die Webseite aus der plugin.json.

Sprachpaket (Mehrsprachigkeit): ein normales Plugin ohne Berechtigungen, dessen plugin.json zusätzlich "language": {"code": "en", "name": "English", "flag": "flag.svg", "strings": "strings.json"} enthält. Die Webseite prüft den Sprachcode (en, pt-br …), merkt sich Code und Name und nennt sie im Katalog (language); DeskHub zeigt dann „🌐 Sprache: English“ und blendet nach der Aktivierung die Flagge zum Umschalten ein. Flagge und Texte liegen im Paket. Fertige Pakete: Plugins/plugins/lang-en-1.0.0.zip und lang-de-1.0.0.zip, passende Vorschaubilder in theme/vorschaubilder/plugin-lang-en.png und plugin-lang-de.png. Nach einem Update dieser Webseite legt sie die neue Spalte beim ersten Aufruf selbst an.

Theme: ZIP mit theme.css im Stammverzeichnis (nur CSS, Bilder und Schriften, kein PHP). Kennung, Name und Beschreibung tragt ihr beim Hochladen ein. Autor und Version stehen am besten im CSS-Kopf:

/*
 * Author: Name
 * Version: 1.0.0
 */

In DeskHub nutzen

Der Katalog dieser Webseite ist in DeskHub fest eingebaut (includes/catalog_defaults.php). Admins müssen nichts eintragen: Unter Plugins und Einstellungen → Design erscheint das Angebot automatisch. Den Inhalt der Datei liefern php einrichten.php und die Verwaltung unter „Einstellungen für DeskHub“.

Docker (externes Hosting mit fest eingebauten Zugangsdaten)

Für den Betrieb auf einem externen Server gibt es ein Docker-Image. Admin-Zugang und Signierschlüssel werden beim Bauen fest in das Image geschrieben. Im laufenden Container lassen sie sich weder per Umgebungsvariable noch per Volume oder Konfigurationsdatei ändern (config.php ist schreibgeschützt und „gesperrt“). Zum Ändern wird das Image neu gebaut.

Bauen (nur Docker nötig, PHP muss nicht installiert sein; auf dem Rechner, nicht auf dem Server):

.\docker-build.ps1 -BaseUrl https://plugins.example.de      # Windows
./docker-build.sh https://plugins.example.de                 # Linux / macOS

Das Skript fragt das Admin-Passwort ab (mindestens 12 Zeichen), erzeugt bei Bedarf den Signierschlüssel (schluessel/herausgeber-privat.pem, sichern, nie weitergeben) und baut das Image deskhub-plugins:latest. Passwort-Hash und Schlüssel werden als BuildKit-Secrets übergeben und stehen nicht im Image-Verlauf (docker history).

Betreiben (auf dem Server, z. B. im Ordner /home/docker/plugin-deskhub; das Image dort bauen oder per docker save/docker load aus einer privaten Quelle laden):

cd /home/docker/plugin-deskhub
docker compose up -d                     # Webseite auf Port 3040 (http)

Die Webseite ist danach unter http://SERVER:3040 erreichbar. DeskHub lädt Plugins nur über https, deshalb braucht die öffentliche Adresse (BASE_URL, die ihr beim Bauen angegeben habt) einen HTTPS-Proxy, der auf Port 3040 weiterleitet. Zwei Wege:

Im Bereich admin.php gibt es außerdem „DeskHub-Apps veröffentlichen“ für Android-APK- und Windows-EXE-Releases. Tragt pro Upload eine neue Versionsnummer ein; DeskHub bezieht anschließend die aktuelle Version und die Datei über den geschützten App-Endpunkt. Für Windows-Setups muss PHP Uploads bis mindestens 300 MB erlauben (im Docker-Image und im Caddy schon eingestellt; bei einem eigenen Proxy dort ebenfalls, z. B. nginx client_max_body_size 320m) (upload_max_filesize und post_max_size); die Dateien landen wie andere Pakete im geschützten storage-Verzeichnis.

  • Euer eigener Proxy (nginx, Traefik, Nginx Proxy Manager …): https://plugins.example.de → http://127.0.0.1:3040.
  • Mitgelieferter Caddy (besorgt das Zertifikat selbst; Ports 80 und 443 frei, Domain zeigt auf den Server): PLUGINS_DOMAIN=plugins.example.de docker compose --profile https up -d.

Der Container läuft mit schreibgeschütztem Dateisystem und ohne unnötige Rechte; beschreibbar ist nur das Volume plugin_daten (veröffentlichte Pakete und Datenbank). Port 3040 sollte von außen nur über den Proxy erreichbar sein (Firewall), sonst läuft die Verwaltung auch unverschlüsselt.

Wichtig: Das Image enthält den Passwort-Hash und den privaten Signierschlüssel. Wer das Image besitzt, besitzt beides. Nur in eine private Registry oder direkt auf den Server übertragen, nie öffentlich hochladen. Ein neues Passwort oder ein neuer Schlüssel bedeutet: neu bauen und das Image austauschen (bei einem neuen Schlüssel müssen alle DeskHub-Installationen den neuen öffentlichen Schlüssel erhalten).

Push-Dienst für die Android-App (push.php)

Die Webseite ist auch der zentrale Push-Dienst der Android-App aus dem Store. Der Firebase-Schlüssel (Dienstkonto) liegt nur hier; die App und die DeskHub-Server der Kunden enthalten ihn nie.

  1. Firebase-Konsole → Projekteinstellungen → Dienstkonten → „Neuen privaten Schlüssel generieren“ → die Datei als schluessel/firebase-dienstkonto.json ablegen (neben dem Signierschlüssel; der Ordner schluessel/ ist von Git und vom Docker-Build ausgeschlossen). In der Firebase-Konsole muss die Firebase Cloud Messaging API (V1) aktiv sein.
  2. Image neu bauen (docker-build.ps1 bzw. docker-build.sh): Das Skript erkennt die Datei und baut sie als BuildKit-Secret fest ein (schreibgeschützt, nicht im Image-Verlauf). Ohne die Datei läuft die Webseite wie bisher, push.php antwortet dann mit 503.
  3. DeskHub leitet die Adresse selbst aus der Katalog-Adresse ab (https://<katalog-host>/push.php). Jedes DeskHub meldet sich beim ersten Senden mit dem Zugangsschlüssel des Katalogs an (access_key in includes/catalog_defaults.php) und bekommt eine eigene Installations-ID samt Geheimnis (nur als Hash gespeichert).

Was der Dienst tut und nicht tut: Er nimmt nur Geräte-Token und Ticketnummer an (Betreff/Kundenname nur, wenn der Kunde „Details anzeigen“ einschaltet), baut den Text selbst, begrenzt auf 2000 Nachrichten je Installation und Stunde und 20 Anmeldungen je Adresse und Stunde und meldet abgemeldete Geräte zurück. Eine Installation sperren: in storage/katalog.sqlite (Volume plugin_daten) in Tabelle push_installs blocked = 1 setzen. Datenschutz: Der Dienst und Google verarbeiten Geräte-Token und Ticketnummern; das gehört in eure Datenschutzerklärung für die App.

Sicherung

./backup.sh /home/docker/backups 14 sichert das Volume plugin_daten (Pakete, Katalog- und Push-Datenbank) als .tar.gz und löscht Sicherungen, die älter als 14 Tage sind. Als Cronjob z. B. täglich um 03:15. Die Schlüssel im Ordner schluessel/ sind nicht enthalten und müssen getrennt gesichert werden. Die Wiederherstellung steht im Kopf des Skripts.

Pakete selbst signieren (ohne automatische Signatur)

Wer den Schlüssel nicht auf dem Server haben möchte, lässt signing_key_file leer und signiert lokal mit dem Werkzeug tools/plugin-sign.php aus dem DeskHub-Paket. Die Webseite veröffentlicht dann unsignierte Pakete.

Sicherheit

  • Anmeldung mit Passwort-Hash, CSRF-Schutz, Sperre nach 5 Fehlversuchen pro 15 Minuten und IP
  • Pakete liegen in storage/ (per .htaccess gesperrt) und werden nur über download.php ausgeliefert
  • Der Katalog liefert für jedes Paket Prüfsumme und Signatur; DeskHub prüft beides vor der Installation
  • Plugins sind Programmcode: Veröffentlicht nur Pakete, deren Inhalt ihr geprüft habt