Root Cause für den HTTP-500-Bug beim Manticore-Neustart über den Dienste-Tab: sudo war auf 132 gar nicht installiert, admin_services_handlers.go ruft aber für JEDE Dienst-Aktion sudo systemctl auf. Betraf nicht nur Manticore, sondern alle Dienste in der Whitelist - PROJ-67 hat es nur erstmals sichtbar gemacht. install.sh/update.sh installieren jetzt sudo (falls fehlend) und legen /etc/sudoers.d/archivmail mit NOPASSWD-Regeln für genau die Service- Whitelist an (archivmail, archivmail-web, manticore, postgresql@17-main, postfix, nginx) - validiert per visudo -c vor dem Einspielen, damit ein Bug im Generator nie eine kaputte sudoers-Datei live schaltet. update.sh zieht das als Backfill für Bestandsinstallationen nach, analog zum PROJ-67-Upgrade-Pfad-Muster. archivmail-nft-Helper (externe Zugriffskontrolle) fehlt auf 132 ebenfalls, aber bewusst nicht Teil dieses Tickets (vermutlich firewall-security-Skill- Verantwortung).
5.2 KiB
id, title, status, created
| id | title | status | created |
|---|---|---|---|
| PROJ-68 | sudo-Provisionierung für Admin-Dienststeuerung fehlte komplett | In Review | 2026-07-05 |
Kontext
Beim QA-Test der neuen Versions-Spalte im Dienste-Tab (siehe Commit
8564d7c) wurde ein Neustart-Versuch für manticore über
POST /api/admin/services/manticore getestet — Ergebnis: HTTP 500,
Dienst nicht neu gestartet.
Root Cause (verifiziert auf 192.168.1.132): sudo ist auf 132 gar nicht
installiert (kein /usr/bin/sudo, kein /etc/sudoers//etc/sudoers.d/).
internal/api/admin_services_handlers.go ruft aber für JEDE Dienst-Aktion
exec.Command("sudo", "/usr/bin/systemctl", action, name+".service") auf —
das schlägt fehl mit „executable file not found“, CombinedOutput() ist
leer, daher writeError(500, "") (leerer Body, schwer zu diagnostizieren).
Betrifft nicht nur Manticore — jede Dienst-Aktion (Start/Stop/Restart/
Enable/Disable) für ALLE Dienste in der Whitelist war auf 132 schon vorher
kaputt, das PROJ-67/Versions-Feature hat es nur erstmals sichtbar gemacht,
weil vorher niemand manticore (das jetzt neu in der Liste ist) über die
UI neugestartet hat — wahrscheinlich wurde die Dienststeuerung insgesamt nie
über die UI getestet, seit sie gebaut wurde.
install.sh legt den archivmail-Systembenutzer an (useradd --system --shell /bin/false ...), installiert aber nie sudo und legt nie eine
/etc/sudoers.d/archivmail-Regel an. Der Go-Code setzt eine
Server-Provisionierung voraus, die im Repo nirgends existiert — das war
vermutlich ein manueller, nie dokumentierter Schritt bei der Ersteinrichtung
von 131, der bei 132 (und jeder künftigen Neuinstallation) fehlt.
Separater, verwandter Fund: /usr/local/sbin/archivmail-nft (für die
"Extern sperren/freigeben"-Buttons beim archivmail-Dienst) fehlt auf 132
ebenfalls und wird von install.sh auch nicht deployt — das ist vermutlich
Teil des firewall-security-Skills und bewusst außerhalb dieses Tickets
(siehe Non-Goals).
User Stories
- Als Superadmin möchte ich Dienste (inkl. Manticore) über die Web-UI starten/stoppen/neustarten können, ohne mich per SSH einzuloggen.
- Als Betreiber möchte ich, dass eine frische Installation (
install.sh) die Dienststeuerung sofort funktionsfähig macht, ohne manuelle Nacharbeit auf dem Server.
Acceptance Criteria
install.shinstalliertsudo(falls nicht vorhanden) und legt/etc/sudoers.d/archivmailmitNOPASSWD-Regeln fürsystemctl {start,stop,restart,enable,disable}auf genau die Service-Whitelist ausinternal/api/admin_services_handlers.go(archivmail,archivmail-web,manticore,postgresql@17-main,postfix,nginx) an — keine allgemeineALL-Regel.- Sudoers-Datei wird vor dem Einspielen mit
visudo -c -fvalidiert (Syntaxfehler dürfen niemals eine funktionierende sudoers-Config kaputt machen). update.shzieht dieselbe Provisionierung nach (idempotent, prüft ob die Datei schon existiert/aktuell ist), damit auch 132 (und jede andere Bestandsinstallation) beim nächsten Deploy automatisch nachgerüstet wird — analog zum PROJ-67-Upgrade-Pfad-Muster.- Nach der Provisionierung: Start/Stop/Restart über
POST /api/admin/services/{name}funktioniert für alle Dienste in der Whitelist, verifiziert auf 132. archivmail-nft-Fehlen ist dokumentiert (nicht Teil dieses Tickets, siehe Non-Goals), damit es nicht als überraschender Folgefehler auftaucht.
Edge Cases
- Sudoers-Syntaxfehler durch einen Bug im Provisionierungs-Code → darf
niemals live installiert werden (
visudo -cVOR dem Kopieren nach/etc/sudoers.d/, bei Fehler abbrechen statt eine korrupte Datei zu hinterlassen, die den gesamten sudo-Mechanismus auf dem Server lahmlegen könnte). - Datei existiert schon (z.B. von einem früheren manuellen Setup mit
abweichendem Inhalt) → nicht blind überschreiben, sondern nur ergänzen
falls Einträge fehlen, oder zumindest den bestehenden Inhalt vor dem
Überschreiben sichern (
.bak). - 131 (Produktiv) hat vermutlich schon eine funktionierende, manuell angelegte sudoers-Config (sonst wären Service-Aktionen dort auch nie gegangen) — Provisionierung muss idempotent/additiv sein, darf eine funktionierende Config nicht durch einen abweichenden Regelsatz ersetzen und brechen.
Non-Goals
archivmail-nft-Helper-Script (externe Zugriffskontrolle für Port 8080) wird NICHT in diesem Ticket gebaut — vermutlich Verantwortungsbereich desfirewall-security-Skills, separates Ticket falls gewünscht.- Kein Umbau auf D-Bus/PolicyKit als Alternative zu sudo (größerer Architektur-Schnitt, nicht durch den akuten Bug gerechtfertigt).
Technical Requirements
- Betroffene Dateien:
install.sh,update.sh. - Whitelist im Sudoers-Generator muss mit
allowedServicesininternal/api/admin_services_handlers.gosynchron gehalten werden (bei künftigen neuen Diensten beide Stellen anfassen — Risiko, dass das wieder auseinanderläuft, wie es beimmanticore-Eintrag ja gerade passiert ist).
Implementation Notes
wird ergänzt.
QA Test Results
wird ergänzt.
Deployment
wird ergänzt.