Ausführen des init.d-Dienstes unter systemd ohne root auth (aktualisiert)

7578
user5860663

Mein Unternehmen hat einige Software eingerichtet, die als Dienst unter Verwendung von init.d auf einer älteren Version von SLES ausgeführt wird. Wir haben vor kurzem mit dem Einrichten einer neuen Umgebung für eine SLES 12-Instanz in Amazons EC2 begonnen und festgestellt, dass SLES 12 jetzt systemd anstelle von init.d verwendet. Es sieht jedoch so aus, als könnten Dienste, die in init.d-Skripts (dh in /etc/init.d) definiert sind, weiterhin normal gestartet werden, da systemd im Hintergrund etwas Magie im Umgang mit bereits vorhandenen init.d-Skripts vornimmt, was großartig ist.

Wir möchten unseren Service jedoch nicht als Root-Benutzer ausführen. Stattdessen erstellen wir einen neuen Benutzer, um unseren Service auszuführen. Das Problem ist, dass wenn wir versuchen, unseren Service als Nicht-Root-Benutzer zu starten, das, was systemd tut, um sich auf die Ausführung eines alten init.d-Dienstes vorzubereiten, die Root-Authentifizierung anfordert, die unserer Meinung nach nicht notwendig sein sollte. In der älteren SLES-Umgebung (unter Verwendung von init.d) können wir den Dienst ohne Probleme als Benutzer ohne Rootberechtigung starten. Soweit ich das beurteilen kann, sind die Berechtigungen und die Besitzrechte von Nicht-Root-Benutzern in beiden Umgebungen gleich.

Ich denke, das liegt in der unter der Haube liegenden Behandlung alter init.d-Dateien von systemd darin, dass das Skript zum Starten unseres Dienstes eine Textzeile unmittelbar vor dem eigentlichen Befehl zum Starten / Stoppen des Dienstes wiedergibt. Diese Zeile ist jedoch nicht Keine Ausgabe, dh wir werden vor der Echo-Anweisung nach root auth gefragt. Die Authentifizierung ist für ein bestimmtes Paket / Modul in systemd erforderlich, aber ich kann mich im Moment nicht an seinen Namen erinnern.

Beachten Sie, dass wir möglichst vermeiden möchten, eine service-spezifische .service-Datei für unseren Service zu erstellen - wir möchten bei unserem init.d-Skript bleiben und es als Nicht-Root-Benutzer ausführen. Außerdem möchten wir den Dienst ohne die Verwendung von sudo ausführen (in der alten Umgebung ist Sudo nicht erforderlich).

Ich entschuldige mich für das Fehlen von Einzelheiten in dieser Frage - Ich werde sie mit spezifischeren Details aktualisieren, sobald ich wieder im Büro bin und die spezifischen Details nehmen kann. Dies scheint jedoch ein allgemeines Problem zu sein, daher hoffe ich, dass es jemand gibt kann ein wenig Licht auf dieses werfen.

Im Einzelnen: Wir möchten einen Dienst ausführen, der mit einem alten init.d-Skript als Benutzer ohne Rootberechtigung definiert wurde, der systemd unter SLES 12 verwendet.

(Update 1) Das genaue Ergebnis des Versuchs, unser Skript /etc/init.d/my_service stop auszuführen, lautet:

/etc/init.d/my_service stoppt die
Umleitung zu systemctl stop stop electrum-gateway-main.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units === Zum Stoppen von 'my_service.service' ist eine Authentifizierung erforderlich.
Authentifizierung als: root
Passwort:

Der Dienst wurde nicht ausgeführt, als wir versuchten, ihn zu stoppen, aber das ist für das Auth-Problem nicht relevant.

Ich habe etwas mehr in unserem Skript gesucht und das Skript erreicht die folgende Zeile, bevor ich nach auth frage:

. /etc/rc.status 

Hier liegt also das Problem. Sollte man root-Rechte benötigen, um /etc/rc.status aufzurufen?

5

2 Antworten auf die Frage

6
grawity

In systemd (und anderen modernen init-Systemen) ist der Start des Dienstes streng in zwei Schritte unterteilt:

  1. Benutzerwerkzeuge (z. B. systemctl) fragen remote (init 1), einen bestimmten Dienst zu starten.
  2. Init liest die Dienstkonfiguration, richtet die Umgebung ein (einschließlich des Wechselns zum gewünschten Benutzerkonto) und führt die ausführbare Datei aus.

Aufgrund dieser Umstellung haben Dienste garantiert immer dieselbe Umgebung, unabhängig davon, von wem und wie sie gestartet wurden. (Bisher waren Benutzerumgebungen wie Gebietsschema, Pfad oder SELinux-Kontexte, die in Dienste eingedrungen sind, ein häufiges Problem.)

(Bei init.d-Skripten enthält die lsb-Funktionsdatei der Distribution die magischen Weiterleitungen zu 'systemctl start', so dass sie auch dieselbe Umleitung erhalten.)

Dies bedeutet auch, dass Sie einen Dienst nicht "als denselben Benutzer" starten können - Sie müssen einen bestimmten Benutzernamen in der entsprechenden systemd-.service-Datei konfigurieren (und wenn es keinen gibt, sollten Sie wirklich einen schreiben).

Der Aufruf "Dienst starten" ist normalerweise privilegiert, aber Sie können eine Regelregel schreiben, die es pro Benutzer oder pro Dienst zulässt (wenn die systemd-Version neu genug ist):

/* /etc/polkit-1/rules.d/allow-whatever.rules */  polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.systemd1.manage-units") { var verb = action.lookup("verb"); var unit = action.lookup("unit"); if (subject.user == "manager" && unit == "app.service" && (verb == "start" || verb == "stop" || verb == "restart")) { return polkit.Result.YES; } } }); 

Alternativ kann es möglich sein, die Indirektion im init.d-Skript zu deaktivieren, aber dann würden Sie auch das Service-Tracking von systemd vollständig verlieren - Ihr Daemon wird wie ein normaler Benutzerprozess aussehen.

Da ich also keinen Benutzer über eine .service-Datei angegeben habe, versucht systemd, den Dienst mit root für den Befehl start service zu starten. user5860663 vor 7 Jahren 0
Ja. Aber das hat absolut nichts mit Ihrer angezeigten Passwortabfrage zu tun. Sie benötigen root (oder polkit permissions) für _ask_ systemd, um einen Dienst zu starten. grawity vor 7 Jahren 0
Klappt wunderbar! flotto vor 6 Jahren 0
0
Mark Stosberg

Das Ausführen Ihrer Dienste als Benutzer ohne Rootberechtigung ist eine gute Idee. Neben dem Vorschlag von Polkit in der anderen Antwort gibt es ein paar konventionellere Möglichkeiten, einen Dienst nicht als root zu starten:

  1. Verwenden Sie Sudo . Eine Sudo-Regel kann es einem bestimmten Benutzer ermöglichen, die Befehle startund restartfür einen bestimmten Dienst auszuführen, führt jedoch keine Aktionen als Root aus und bietet dieselbe Art von eingeschränkten Berechtigungen.
  2. Verwenden Sie den systemd- userModus . systemd bietet Benutzern die Möglichkeit, Dienste unter der Kontrolle des Benutzers mit einer systemd-Instanz für jeden Benutzer zu verwalten, sodass Benutzer ihre eigenen Einheiten starten, stoppen, aktivieren und deaktivieren können.

Ich denke, dass der systemd-Benutzermodus möglicherweise mehr für Desktop-Anwendungsfälle existiert. Für einen Server empfehle ich die Verwendung der sudoLösung. In der systemd- .serviceDatei können Sie auch die User=Direktive festlegen, um den Benutzer anzugeben, den der Dienst ausführt. Möglicherweise derselbe Benutzer, mit dem Sie ihn gestartet haben.

Die "Polkit" -Lösung ist eine Action-in-Distance-Lösung - es scheint schwierig zu sein, zu verstehen, was dem Benutzer erlaubt, den Dienst zu starten. Doch mit sudoIhnen klar fordern, fordern sudo, und mit systemd user mode, werden Sie deutlich, dass die Funktion.

Wenn ich in einer Umgebung wäre, in der die Lösung von Polkit eingerichtet wurde, hätte ich keine Ahnung, warum der Service überhaupt gestartet wurde, es sei denn, ein Mitarbeiter hat eine Dokumentation darüber hinterlassen.