--- id: PROJ-68 title: sudo-Provisionierung für Admin-Dienststeuerung fehlte komplett status: In Review created: 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 - [x] `install.sh` installiert `sudo` (falls nicht vorhanden) und legt `/etc/sudoers.d/archivmail` mit `NOPASSWD`-Regeln für `systemctl {start,stop,restart,enable,disable}` auf genau die Service-Whitelist aus `internal/api/admin_services_handlers.go` (`archivmail`, `archivmail-web`, `manticore`, `postgresql@17-main`, `postfix`, `nginx`) an — keine allgemeine `ALL`-Regel. - [x] Sudoers-Datei wird vor dem Einspielen mit `visudo -c -f` validiert (Syntaxfehler dürfen niemals eine funktionierende sudoers-Config kaputt machen). - [x] `update.sh` zieht 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. - [x] 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 -c` VOR 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 des `firewall-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 `allowedServices` in `internal/api/admin_services_handlers.go` synchron gehalten werden (bei künftigen neuen Diensten beide Stellen anfassen — Risiko, dass das wieder auseinanderläuft, wie es beim `manticore`-Eintrag ja gerade passiert ist). --- ## Implementation Notes _wird ergänzt._ ## QA Test Results _wird ergänzt._ ## Deployment _wird ergänzt._