Skip to content

About

Ein Ticket System dieses komplett über die Weboberfläche läuft, auch die Abarbeitung per Web.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Repository files navigation

Ticket-System / Support Portal

Selbst gehostetes Ticketsystem mit Benutzerportal, Admin-Board, Aufgaben, Genehmigungen, Benachrichtigungen und Dokumentenvorschau. Daten werden serverseitig in MariaDB gespeichert.

Installation mit einem Befehl

Auf einem Debian-/Ubuntu-Server als root ausführen. Docker, Docker Compose und die benötigten Pakete werden automatisch installiert. Empfohlen: mindestens 3 GB RAM; für den optionalen Virenscanner zusätzlich 1-2 GB, für die Office-Oberfläche zusätzlich 4 GB. Die Grundinstallation verwendet die PDF-Vorschau; die Office-Oberfläche wird mit --enable-office-viewer aktiviert (Anleitung unten).

bash -c 'set -euo pipefail; if ! command -v curl >/dev/null; then apt-get update && apt-get install -y curl ca-certificates; fi; f=$(mktemp); trap "rm -f \"$f\"" EXIT; curl -fsSL https://raw.githubusercontent.com/ubodigat/Ticket-System-web/main/install.sh -o "$f"; printf "%s  %s\n" "47b286d028734801935bdc3ad5cf48b9e9d4d5abc850b05ff677b9503f2c411f" "$f" | sha256sum -c -; INSTALL_MANIFEST_SHA256=13e9750cc7fadd3217ac29df282ad5dca549fd01d6e985937465161fe2cd20c9 bash "$f"'

Der Befehl prüft das Installationsskript vor seiner Ausführung und anschließend die Dateien des gesamten Installationsstands gegen ein festgelegtes SHA-256-Manifest. Bei Abweichungen wird abgebrochen. Immer den vollständigen Befehl aus diesem README verwenden, nicht durch ein ungeprüftes curl | bash ersetzen. Skript, Manifest und README müssen gemeinsam veröffentlicht sein; vor dem Push ist der neue Befehl noch nicht verwendbar.

Nach erfolgreichem Start zeigt der Installer die Adresse und das Setup-Token an. Vor der Erfolgsmeldung prüft er die öffentliche Anmeldeseite, JavaScript-Module und Stylesheets über Caddy. Fehlen erforderliche Dateien oder startet der Webzugang nicht, bricht er mit einer Fehlermeldung ab. /health ist öffentlich absichtlich gesperrt (404); dieser Pfad wird nur intern für den Container-Healthcheck verwendet. Adresse öffnen, Token eingeben und das erste Superadmin-Konto einrichten. Installation: /opt/ticket-system; Konfiguration: ops/docker/.env.

Zugriff: Ports 80/443 müssen vom Arbeitsplatz aus erreichbar sein. Bei Zugriff über eine lokale IP verwendet Caddy ein internes Zertifikat; dessen CA muss auf den Endgeräten als vertrauenswürdig eingerichtet werden. Ein gesunder Container allein bestätigt noch nicht die Erreichbarkeit durch eine externe Firewall oder den Proxmox-Host.

Mit eigener Domain

DNS muss bereits auf den Server zeigen. Beispielwerte im Befehl ersetzen:

bash -c 'set -euo pipefail; if ! command -v curl >/dev/null; then apt-get update && apt-get install -y curl ca-certificates; fi; f=$(mktemp); trap "rm -f \"$f\"" EXIT; curl -fsSL https://raw.githubusercontent.com/ubodigat/Ticket-System-web/main/install.sh -o "$f"; printf "%s  %s\n" "47b286d028734801935bdc3ad5cf48b9e9d4d5abc850b05ff677b9503f2c411f" "$f" | sha256sum -c -; INSTALL_MANIFEST_SHA256=13e9750cc7fadd3217ac29df282ad5dca549fd01d6e985937465161fe2cd20c9 bash "$f" --domain=support.example.com --acme-email=admin@example.com'

Was enthalten ist

  • Benutzerkontoanfragen, optionale Kontogültigkeit, Rollen und serverseitige Berechtigungsprüfung.
  • Ticket-Board und Listenansicht, Prioritäten, Fristen, Geschäftszeiten, Archiv und Störungen.
  • Nachrichten, Anhänge, Teilaufgaben, eigene/geteilte/wiederkehrende Aufgaben und Genehmigungen.
  • Ticket-Sichtbarkeit wird serverseitig durchgesetzt: normale Konten sehen eigene Tickets, Admins nicht zugewiesene, eigene, beteiligte und Tickets ihrer Gruppe (inklusive Ober- und Untergruppen) sowie die Kategorie „Allgemein“, Superadmins alles. Genehmigen kann jedes aktive Konto; die prüfende Person sieht dabei nur Ticketkopf, Zusatzfelder, direkte Anhänge und die Begründung. Anfrage und Entscheidung bleiben als Verlauf am Ticket (Migration 0063). Ohne vorgesetzte Person greift zuerst die Ersatzperson der Ticket-Kategorie, dann die der Gruppe, dann die allgemeine.
  • Benutzer werden über einen Assistenten angelegt (Konto, Organisation, Kontakt und Arbeitszeiten, Rechte, Übersicht) – identisch beim Annehmen einer Kontoanfrage. Zusatzangaben wie Personalnummer, Kostenstelle, Gebäude/Raum, Eintrittsdatum und Arbeitstage liegen verschlüsselt (Migration 0064).
  • PDF-Vorschau und optionale, schreibgeschützte Office-Oberfläche über isolierte Dokumentendienste.
  • SMTP mit verschlüsselter, dauerhafter Versandqueue; LDAP und Outlook nach Einrichtung.
  • Argon2id, widerrufbare Sitzungen, MFA mit TOTP/Passkeys, CSRF-Schutz und Feldverschlüsselung.
  • Benutzerbezogenes Design über mehrere Geräte und Ticket-Timer mit verpflichtender Tätigkeitsdokumentation.
Office-Oberfläche aktivieren (nur lesen)

Die Office-Ansicht nutzt einen zusätzlichen ONLYOFFICE-Dienst: Tabellen mit Arbeitsblättern, Word-Dokumente und Präsentationen werden in dessen Office-Oberfläche geöffnet. Die Ansicht ist schreibgeschützt; Änderungen am Original sind gesperrt. Fehlende Schriftarten oder besondere Office-Funktionen können weiterhin zu Abweichungen von Microsoft Office führen. Neue Office-Uploads sind für DOCX, XLSX, PPTX und ODT/ODS/ODP freigegeben; die zusätzlichen Formate müssen zur erkannten Dateistruktur passen. Makroformate bleiben gesperrt.

Die Office-Oberfläche läuft aus Sicherheitsgründen unter einer eigenen Subdomain (Standard: office.<deine-domain>, abweichend mit --office-domain=…). So kann eine Schwachstelle im Office-Dienst nicht auf die Anmeldung im Ticketsystem zugreifen. Deshalb ist eine echte Domain nötig (--domain=… --acme-email=…), und für die Subdomain muss ein DNS-Eintrag (A/AAAA) auf denselben Server zeigen. Mit einer reinen IP-Adresse lässt sich die Office-Oberfläche nicht aktivieren; die PDF-Vorschau funktioniert weiterhin.

Bei der Erstinstallation diesen verifizierten Befehl verwenden und --domain=… --acme-email=… hinter --enable-office-viewer ergänzen:

bash -c 'set -euo pipefail; if ! command -v curl >/dev/null; then apt-get update && apt-get install -y curl ca-certificates; fi; f=$(mktemp); trap "rm -f \"$f\"" EXIT; curl -fsSL https://raw.githubusercontent.com/ubodigat/Ticket-System-web/main/install.sh -o "$f"; printf "%s  %s\n" "47b286d028734801935bdc3ad5cf48b9e9d4d5abc850b05ff677b9503f2c411f" "$f" | sha256sum -c -; INSTALL_MANIFEST_SHA256=13e9750cc7fadd3217ac29df282ad5dca549fd01d6e985937465161fe2cd20c9 bash "$f" --enable-office-viewer'

Bei einem bereits aktualisierten Checkout auf dem Server:

cd /opt/ticket-system
bash install.sh --enable-office-viewer --domain=support.example.com --acme-email=it@example.com

Der Installer aktiviert das Compose-Profil office-viewer, erstellt ein dauerhaftes JWT-Geheimnis, legt die Caddy-Site für die Office-Subdomain an (ops/docker/caddy-sites/office.caddy) und startet den Dienst ohne öffentliche Zusatzports in einem eigenen Netz. Beim ersten Start braucht ONLYOFFICE einige Minuten. Bis er bereit ist, bleibt die PDF-Vorschau verfügbar. Mindestens etwa 7 GB RAM für den gesamten Stack vorsehen, mit Virenscanner entsprechend mehr. Dateien über 15 MiB bleiben auf den Download beschränkt. Die Dokumentendienste halten entschlüsselte Arbeitskopien im Container; Zugriff auf Docker/Server bleibt deshalb privilegiert.

Technische Grundlage: ONLYOFFICE Docker-Installation und JWT-Absicherung.

MFA, Gerätefreigabe und Wiederherstellung

Unter Systemeinstellungen → Sicherheit → MFA-Methoden stehen nach dem Passwort TOTP, Passkey, TOTP oder Passkey sowie TOTP + Passkey zur Auswahl. Die Pflicht kann für alle Konten, Admins inklusive Superadmins oder Benutzer gelten. Bei TOTP + Passkey beträgt die zusätzliche Gerätefreigabe standardmäßig 14 Tage; 0 verlangt den Passkey bei jeder Anmeldung. Das Gerät wird über ein HttpOnly-Cookie und einen benutzergebundenen Datenbanknachweis erkannt. Ein neues Gerät benötigt einen neuen Nachweis. Eine reine Passkey-Regel verlangt den Passkey weiterhin bei jeder Anmeldung.

Passkeys benötigen einen Domainnamen mit vertrauenswürdigem HTTPS, nicht nur eine LAN-IP. PUBLIC_URL wird vom Installer inklusive HTTPS-Port gesetzt und als WEBAUTHN_ORIGIN an die App übergeben. Nach einer Domainänderung Installer erneut ausführen; Passkeys sind an ihre bisherige Domain gebunden und müssen bei einer anderen Domain neu registriert werden. Die Pflicht zu Passkeys kann nur über die passend konfigurierte HTTPS-Domain aktiviert werden. Bestehende Sitzungen behalten ihre normale Laufzeit; die neue Anmelderegel greift bei der nächsten Anmeldung.

Eigene Verfahren unter Persönliche Einstellungen → Sicherheit → MFA / Passkeys verwalten einrichten. Zuerst TOTP aktivieren. Neue Passkeys sowie das Entfernen von Schlüsseln oder Erzeugen neuer Wiederherstellungscodes verlangen das aktuelle Passwort und einen frischen TOTP-Code. Handy-Passkeys, Computer und FIDO2-Sicherheitsschlüssel werden über den Browser ausgewählt; SMS/Push sind ohne zusätzlichen Anbieter nicht enthalten. Für Passkeys wird Benutzerverifikation verlangt (z. B. Geräte-PIN oder Biometrie).

Die zehn Wiederherstellungscodes werden nur einmal angezeigt und gehasht gespeichert. Offline aufbewahren. Passwort + ein unbenutzter Code setzen bisherige MFA-Verfahren und Sitzungen zurück; vor dem Login müssen die vorgeschriebenen Verfahren neu eingerichtet werden. Neue Codes ersetzen alle alten. Ohne Code kann ein entsprechend berechtigter Superadmin zurücksetzen. Als letzter Rettungsweg auf dem Server:

cd /opt/ticket-system
docker compose -f ops/docker/docker-compose.yml --env-file ops/docker/.env exec app node dist/cli/unlock.js admin --reset-mfa

Dieser explizite Serverbefehl widerruft die bisherigen Verfahren/Sitzungen des genannten Kontos und wird protokolliert. Er ersetzt kein Passwort und deaktiviert keine globale MFA-Regel. Protokollimplementierung: SimpleWebAuthn.

Persönliches Design, einklappbare Einstellungen und Ticket-Timer

Design, Akzentfarbe, Sprache und eigenes Hintergrundbild liegen für angemeldete Personen verschlüsselt in MariaDB. Ein anderer Browser desselben Kontos übernimmt diese Werte. Änderungen werden einzeln zusammengeführt, damit eine neue Akzentfarbe kein Bild überschreibt. Vor der Anmeldung bleiben die Einstellungen browserbezogen. Vorhandene, nicht eindeutig einem Konto zuordenbare Browserbilder werden nicht automatisch in ein fremdes Konto importiert; das gewünschte Bild nach dem Update einmal im eigenen Konto auswählen.

Unterüberschriften der Systemeinstellungen lassen sich auf-/zuklappen. Ihr Zustand wird sofort für das jeweilige Konto gespeichert und beim nächsten Öffnen vom Server geladen.

Admins starten die Zeiterfassung über das Play-Icon im Ticketkopf. Das Stop-Icon hält die Zeit an und öffnet die Tätigkeitsdokumentation. Ohne eine nicht leere Beschreibung lässt sich die Erfassung nicht abschließen. Optionale Lösungsschritte werden als interne Lösungsnotiz gespeichert. Zeit und Notiz werden gemeinsam in einer Transaktion geschrieben; angefangene Minuten zählen als volle Minuten. Pro Admin kann ein Timer aktiv oder noch undokumentiert sein. Laufende und angehaltene Timer bleiben nach Neuladen erhalten. Ein Browser/Tab selbst kann geschlossen werden; beim nächsten Besuch erscheint die noch ausstehende Dokumentation erneut.

Die Schema-Erweiterungen sind Migrationen 0050 und 0051. Der Installer führt sie vor dem App-Start aus; eine reine Ersetzung von Frontend-Dateien reicht für dieses Update nicht.

Passwortregeln und große Anhänge

Passwortregeln: Unter Systemeinstellungen → Sicherheit lassen sich Mindestlänge (14–128 Zeichen) und Mindestanzahl an Klein-/Großbuchstaben, Ziffern und Sonderzeichen festlegen. Sie gelten beim Anlegen und Ändern von Passwörtern; bestehende Passwörter werden nicht rückwirkend ungültig. Für das erste Setup gelten mindestens 14 Zeichen.

Anhänge: Die maximale Dateigröße stellt der Superadmin unter Systemeinstellungen > Allgemein ein (500 bis 2000 MB, Standard 1 GB). Sie gilt für Ticket-Anhänge, Chat-Nachrichten, interne Kommunikation und die Wissensdatenbank. Erlaubt sind PDF, PNG, JPG, DOCX, XLSX, PPTX, ODT, ODS, ODP, TXT, CSV und LOG; die Oberfläche lehnt andere Typen sofort mit Begründung ab. Dateien über 15 MB werden blockweise übertragen und verschlüsselt in MariaDB gespeichert (Migrationen 0049 und 0062); die Freigabe erfolgt erst nach vollständiger Prüfung. Das Tageskontingent beträgt für normale Konten einmal, für Admins viermal die eingestellte Dateigröße, für die gesamte Installation mindestens 20 GB. Dateien über 15 MB werden heruntergeladen statt vorgerendert. Die abschließende Prüfung hält jede Datei einmal im Arbeitsspeicher, höchstens zwei gleichzeitig: Bei 1 GB mindestens 6 GB RAM einplanen, bei 2000 MB mindestens 8 GB. Die In-App-Datenbanksicherung (Systeminfo) ist auf 512 MB begrenzt; Installationen mit großen Anhängen zusätzlich auf Datenbankebene sichern (mariadb-dump).

Optionaler vollständiger 500-MiB-Test (isolierte Datenbank-Nachbildung, ca. 1–2 GB RAM):

RUN_LARGE_UPLOAD_TEST=1 npm run test --workspace=apps/server -- test/uploads.test.ts

Der reguläre Testlauf überspringt diesen großen Test. Der MariaDB-CI-Test prüft separat das Schema-Upgrade und einen echten verschlüsselten 8-MiB-Datenblock.

Browser-Benachrichtigungen: In den persönlichen Einstellungen unter Benachrichtigungen einschalten und die Browser-Abfrage erlauben. Die Freigabe gilt pro Konto und Browser-Gerät. Neue In-App-Meldungen erscheinen dann auch als Desktop-Mitteilung; ein Klick öffnet das zugehörige Ticket bzw. die Aufgabenliste. Voraussetzung sind ein unterstützter Desktop-Browser und vertrauenswürdiges HTTPS (bei lokalen IPs Caddy-CA installieren). Ein Tab des Ticket-Systems muss geöffnet bleiben, auch im Hintergrund. Die Prüfung erfolgt alle 30 Sekunden, bei Verbindungsfehlern mit längeren Abständen. Bei geschlossener App gibt es keinen Web-Push. Alte Meldungen werden beim Aktivieren nicht nachträglich eingeblendet.

SMTP, LDAP und Microsoft Graph benötigen eigene Zugangsdaten. Für Graph muss die Anwendungsberechtigung im Tenant auf das vorgesehene Postfach begrenzt werden. Tickettermine dürfen nur Admins erstellen, auch mit externen E-Mail-Adressen (maximal 20 Teilnehmende und 20 Terminerstellungen pro Stunde). Im persönlich verbundenen Outlook-Kalender gelten dieselben Empfänger-/Ratenlimits für das eigene Konto.

Outlook einrichten und E-Mail-Vorlagen

Unter Systemeinstellungen → Outlook Tenant-ID, Client-ID und das gültige Client-Secret der eigenen Microsoft-Entra-App speichern. Auch der zentrale Speichern-Button übernimmt das neu eingegebene Secret. Für persönliche Kalender muss die Redirect-URI https://DEIN-HOST/api/v2/outlook/callback einschließlich eines abweichenden Ports exakt registriert sein; delegierte Berechtigungen: Calendars.ReadWrite, offline_access, User.Read. Für Tickettermine zusätzlich App-only-Kalenderberechtigungen und ein begrenztes Supportpostfach einrichten. Ohne diese externen Zugangsdaten ist keine echte Microsoft-Verbindung möglich.

E-Mail-Vorlagen unterstützen {{subject}}, {{message}}, {{recipient}}, {{recipientName}}, {{username}}, {{company}}, {{portalName}}, {{portalUrl}}, {{supportEmail}}, {{date}}, {{time}} und {{year}}. Die Schaltflächen über der Vorlage fügen Variablen an der Cursorposition ein. Name und Benutzername stehen bei Kontobenachrichtigungen zur Verfügung; sonst dient die Empfängeradresse als Name. Datum und Uhrzeit verwenden die ausgewählte Unternehmenszeitzone. Die Signatur wird anschließend ergänzt. Externe Einladungen benötigen kein Portal-Konto. Die optionalen ClamAV-Einstellungen für große Dateien liegen in ops/docker/clamav/clamd.conf (offizielle Konfigurationsdokumentation).

Verwaltung, Wartefristen und geplante Abwesenheiten

Bei „Warten auf Benutzer“ beginnen beide Fristen mit dem Beginn der Wartephase. Eine optionale Erinnerung erfolgt einmal nach der ersten Frist. Für die zweite Frist ist wählbar, ob automatisch geschlossen und benachrichtigt wird oder das Ticket offen bleibt. Standard bleibt das bisherige Verhalten: Erinnerung nach 2, Schließen nach 7 Tagen. Eine Antwort beendet die Wartephase.

Textbausteine lassen sich bearbeiten und durchsuchen. Neuanlage steht bei Textbausteinen, Wissensartikeln und wiederkehrenden Tickets vor der jeweiligen Liste. „Wissensdatenbank ansehen“ öffnet eine eigene Leseansicht mit Suche und Filtern. Teilaufgaben in der Todo-Liste öffnen ihr Ticket durch Anklicken des Titels oder über die Tastatur.

Admins können in den persönlichen Einstellungen mehrere Abwesenheitszeiträume im Voraus anlegen und einzeln entfernen. Überschneidungen werden abgelehnt. Geplante Zeiträume übertragen keine Tickets vor ihrem Beginn. Die Wartung aktiviert Vertretungen und beendet abgelaufene Zeiträume beim nächsten Lauf (standardmäßig alle 5 Minuten und beim Serverstart). Ist die hinterlegte Vertretung dann gesperrt, archiviert oder abgelaufen, gehen die offenen Tickets ohne persönliche Zuweisung zurück an das Team. Bereits übertragene Tickets können über die vorhandene Rückkehrfunktion zurückgenommen werden.

Aktualisieren

Vorher ein Backup erstellen. In einem bewusst geprüften lokalen Repository:

cd /opt/ticket-system
bash ops/docker/backup.sh
bash ops/verify-and-pull.sh
bash install.sh

verify-and-pull.sh holt neue Commits und bricht ab, falls weder der neue Stand noch ein darauf zeigender Release-Tag mit einem bekannten Schlüssel signiert ist (Security-Audit R-14) -- bis ein öffentlicher Signaturschlüssel importiert ist (gpg --import ...), muss die Änderung dann bewusst manuell geprüft werden, statt ungeprüft übernommen zu werden.

Der Installer übernimmt bestehende Daten und Schlüssel, prüft das Laufzeit-Datenbankkonto und führt die Migrationen aus. Während der Datenmigration wird die alte App angehalten, damit sie keine Klartextwerte mehr nachschreiben kann. Schlägt die Migration fehl, bleibt die App bis zur Fehlerbehebung angehalten. Keine Volumes löschen und keine neuen Schlüssel über alte Schlüssel schreiben. Migrationen dürfen nicht im dauerhaft laufenden App-Container ausgeführt werden: Dieser besitzt absichtlich keine DDL-Zugangsdaten.

Online-Updates: Standardmäßig deaktiviert. Der optionale Updater läuft als systemd-Dienst direkt auf dem Server; kein Container erhält Zugriff auf den Docker-Socket. Er übernimmt ausschließlich Stände, deren Commit oder Release-Tag mit einem vom Betreiber hinterlegten Schlüssel signiert ist. Ohne Schlüssel bleiben Updates gesperrt. Details unten.

Betrieb, Fehlersuche, optionale Dienste und Entwicklung

Docker Compose

Befristete Benutzerkonten

In der Benutzerverwaltung beim Anlegen oder Bearbeiten das optionale Feld Gültig bis einschließlich setzen. Das Konto bleibt bis zum Ende dieses Tages nutzbar (Europe/Berlin), danach werden Anmeldung und bestehende Sitzungen abgewiesen. Ein leeres Datum bedeutet unbegrenzte Gültigkeit. Das Datum kann mit Benutzerverwaltungsrechten geändert oder entfernt werden; normale Benutzer können es nicht selbst verlängern. Der letzte dauerhaft verfügbare Superadmin darf nicht befristet werden. Bestehende Konten bleiben ohne Datum gültig.

Die neue Spalte wird beim regulären Installer-/Update-Lauf durch Migration 0045 angelegt.

Container verwalten

Alle Befehle im Installationsverzeichnis ausführen:

docker compose -f ops/docker/docker-compose.yml --env-file ops/docker/.env ps
docker compose -f ops/docker/docker-compose.yml --env-file ops/docker/.env logs --tail=100 app mariadb caddy
docker compose -f ops/docker/docker-compose.yml --env-file ops/docker/.env restart app

Der Stack enthält App, MariaDB, Caddy und Gotenberg. Datenbank und Office-Dienst haben keine veröffentlichten Host-Ports. Images und Node-Basisimages sind per Digest festgelegt; Sicherheitsaktualisierungen der Digests müssen bewusst geprüft und eingepflegt werden.

Wenn das Proxy-Netz kollidiert, EDGE_SUBNET in ops/docker/.env auf ein freies privates Subnetz setzen. Compose und Proxy-Vertrauen verwenden denselben Wert.

Bestehende Installation startet nicht / Datenbankanmeldung scheitert

bash install.sh erhält Passwörter einschließlich aller =-Zeichen. Es richtet das eingeschränkte Laufzeitkonto mit Root-Rechten ein und prüft dessen Anmeldung über TLS, bevor die App neu gestartet wird. DDL-Zugangsdaten gelangen nicht in die laufende App.

Bei älteren Installationen wird das ursprünglich von MariaDB generierte Root-Passwort aus den vorhandenen Containerlogs übernommen. Sind diese nicht mehr vorhanden, muss das tatsächliche bestehende Root-Passwort einmalig als DB_ROOT_PASSWORD in ops/docker/.env eingetragen werden. Der Installer kann ein verlorenes Passwort nicht rekonstruieren und bricht dann ab, ohne Daten oder Volumes zu löschen.

Online-Updater bewusst aktivieren

Der Updater ist ein systemd-Dienst auf dem Host (ops/host-updater). Die App legt lediglich eng begrenzte Anfragen (Status, Update auf den angezeigten Commit, Migration, Rollback) in /var/lib/ticket-system-update/requests ab; der Dienst prüft vor jedem Update die Signatur des Ziel-Commits bzw. eines darauf zeigenden Release-Tags (v… oder release-…). Kein Container hat Zugriff auf den Docker-Socket.

Den öffentlichen Release-Signaturschlüssel über einen vertrauenswürdigen Kanal beziehen und seinen Fingerprint unabhängig prüfen. Anschließend auf dem Host importieren:

mkdir -p ops/docker/update-keys
chmod 700 ops/docker/update-keys
gpg --homedir "$PWD/ops/docker/update-keys" --import /root/release-signing-key.asc
bash install.sh --enable-updates

Der Installer kopiert den Schlüsselbund nach /etc/ticket-system-updater/keys (nur für root lesbar). Nach Schlüsseländerungen bash install.sh erneut ausführen. Unsignierte Stände und unbekannte Signaturen werden abgelehnt. Rollbacks mit Schemaänderungen sind gesperrt und erfordern eine Wiederherstellung mit passendem Datenbank-Backup.

Den Fingerprint vor dem Import mit gpg --show-keys --with-fingerprint /root/release-signing-key.asc anzeigen und über einen zweiten, unabhängigen Kanal vergleichen. Commits, die direkt auf GitHub entstehen (Copilot Autofix, Merge-Button), sind mit GitHubs eigenem Schlüssel signiert und werden abgelehnt, solange kein signierter Release-Tag darauf zeigt.

Releases signieren (Maintainer): entweder jeden Commit signieren (git config commit.gpgsign true) oder Releases als signierten Tag veröffentlichen (git tag -s v1.2.3 -m "Release 1.2.3" && git push origin v1.2.3). Den Fingerprint des Signaturschlüssels an einer zweiten, unabhängigen Stelle veröffentlichen.

Online-Updater wieder deaktivieren

Entfernt den systemd-Dienst samt Konfiguration und setzt UPDATE_ALLOW_MAIN_DEPLOY=false. Daten und Einstellungen bleiben erhalten. Ein noch vorhandener Updater-Container älterer Versionen wird bei jedem Installer-Lauf entfernt:

cd /opt/ticket-system
bash install.sh --disable-updates

Ein Lauf von install.sh ohne diese Optionen behält den jeweiligen Zustand bei.

Weitere Optionen

  • --enable-updates / --disable-updates: Online-Updater (systemd-Dienst auf dem Host) ein- bzw. vollständig wieder ausschalten, siehe oben.
  • --enable-office-viewer und optional --office-domain=office.example.com: Office-Oberfläche unter eigener Subdomain, siehe oben.
  • --enable-antivirus: ClamAV aktivieren; ohne funktionierenden Scanner schlagen Uploads bei aktivierter Prüfung fehl.
  • --dev: lokale Testkonfiguration, nicht für öffentliche Produktionsinstallationen.
  • --domain=... --acme-email=...: öffentlich vertrauenswürdiges HTTPS über ACME.
  • --no-assume-yes: Paketinstallationen nicht automatisch bestätigen.

Backups und Mailzustellung

bash ops/docker/backup.sh
bash ops/docker/restore.sh

Backup-Anweisungen und erforderliche Parameter in den Skripten beachten. KEK, Installations-ID, Datenbank und Konfiguration gehören zusammen; ein Datenbankdump ohne passenden KEK ist nicht wiederherstellbar.

Mails werden verschlüsselt in jobs gespeichert und getrennt vom HTTP-Request versendet. Fehler werden mit Wartezeiten bis zu fünfmal versucht; erschöpfte Jobs haben Status dead. Abgeschlossene Nutzdaten werden sofort entfernt, tote Jobs nach sieben Tagen gelöscht. Bei einem Absturz direkt nach der SMTP-Annahme kann eine Mail doppelt zugestellt werden (At-least-once-Zustellung). Serverlogs enthalten Job-ID und Versuchszahl, keinen Mailinhalt.

Entwicklung und Verifikation

Node.js 24+, für Integrationstests eine separate MariaDB-Testdatenbank:

npm ci
npm run typecheck --workspace=apps/server
npm run test --workspace=apps/server
npm run build --workspace=apps/server
npm audit --audit-level=high
bash ops/tests/installer-security.sh

CI prüft zusätzlich den Upgrade-Pfad von Schema 0037 mit Bestandsdaten gegen MariaDB. Ein lokaler grüner Unit-Testlauf ersetzt keinen erfolgreichen Compose-/Upgrade-Test.

Nach Quellcodeänderungen vor Veröffentlichung:

node ops/create-install-manifest.mjs
node ops/create-install-manifest.mjs --check

Der erste Befehl aktualisiert Manifest und Installationsbefehle im README. Alle Änderungen gemeinsam veröffentlichen. CI weist ein veraltetes Manifest zurück. Das README ist als Hash-Vertrauensanker selbst nicht Teil des Manifests.

Architektur, Grenzen und Sicherheitsentscheidungen: docs, Sicherheitsmodell, aktueller Reparaturstand.

Lizenz

CPAL-1.0. Originalprojekt Ticket-System-web von U:Bodigat. Siehe LICENSE, NOTICE.md und CONTRIBUTORS.md.

About

Ein Ticket System dieses komplett über die Weboberfläche läuft, auch die Abarbeitung per Web.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages