fix(PROJ-68): sudo-Provisionierung für Admin-Dienststeuerung ergänzen
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).
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
---
|
||||
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._
|
||||
Reference in New Issue
Block a user