
Ich versuche, einen Dienst zu erstellen, der einen Prozess startet.
Ich möchte, dass beim Start des Prozesses einige Befehle als Root ausgeführt werden können und der Rest des Prozesses dann als nicht-menschlicher Benutzer mit weniger Privilegien ausgeführt werden kann.
Beispiel: Ich weiß, dass der apache
Benutzer Root-Rechte benötigt, um einige Webserver-Konfigurationen mit Ports vorzunehmen und verschiedene Serverprozesse zu starten, aber er läuft nicht immer als Root. Ich kann keinen Code finden, der etwas Ähnliches tut, und frage mich, ob es andere Beispiele gibt, die ich verwenden kann.
Im Wesentlichen lautet meine Frage:wie erteile ich einem Nicht-Root-Benutzer temporäre Root-Berechtigungen zum Ausführen bestimmter nur Root-Prozesse?
Oder denke ich da falsch:Gewähre ich dem Benutzer keine Root-Berechtigungen und lasse den Root-Benutzer stattdessen die für Root erforderlichen Prozesse ausführen?
Antwort1
Es gibt eine ganze Reihe von Optionen, je nachdem, was Sie als Root-Benutzer genau tun. Bei automatisierten Diensten („wie Apache“) starten Sie jedoch normalerweise als Root und wechseln dann zu einem eingeschränkten Benutzer.
Eine Konfiguration im Debian-Stil (einschließlich Ubuntu und Mint) hätte dann eine Datei in /etc/default/mein-DienstnameEinstellung, zu welchem Benutzer gewechselt wird. Andere Linux-Distributionen haben einen anderen Ort, um die Einstellung zu speichern, aber die Technik ist letztlich dieselbe.
Wenn Sie das Serviceprogramm selbst schreiben, verwenden Siesetuid(). Sobald Sie setuid aufgerufen haben, kann der Prozess nicht mehr auf Root-Privilegien zurückgreifen. Sie müssenSuchen Sie den Benutzer nach Namenund auchLegen Sie die Gruppen für den Benutzer fest.
Vereinfachung eines Codes, den ich vor langer Zeit geschrieben habe:
int lockToUser(const char * user) {
# Look up the username in /etc/passwd
struct passwd * pwd = getpwnam(user);
if (!pwd) {
# Failed... Could not find user, see errno
return 0;
}
# setuid sets the user
# setgid sets the main group similar to the group in /etc/passwd
# Sets the other groups which will grant additional permissions.
# similar to the groups in /etc/groups
if (initgroups(user, pwd->pw_gid) || setgid(pwd->pw_gid) || setuid(pwd->pw_uid)) {
# Failed... Could not lock down to user, see errno
return 0;
}
return 1;
}