Wie kann ich einen Prozess beenden, der mit einem anderen Benutzer gestartet wurde, ohne root oder sudoer zu sein?

20

In einer Linux-Umgebung muss ich einen Prozess beenden, der von Benutzer2 gestartet wurde, wenn ich Benutzer1 bin, ohne Sudoer zu sein oder root zu verwenden. Wissen Sie, ob es eine Möglichkeit gibt, dies beim Starten des Prozesses festzulegen? Wie eine Liste der Benutzer, die den Prozess beenden dürfen?

Tatsache ist, dass gleichzeitige Instanzen desselben Prozesses von verschiedenen Benutzern gestartet werden können. Deshalb ist es für mich nicht praktisch, die Gruppen-ID auf den Prozess festzulegen. Andere Benutzer, die nicht zur Gruppe gehören, können keinen zweiten parallelen Prozess starten.

Was ich habe, ist eine Liste von Benutzern, die den in der Datenbank definierten Prozess starten dürfen, bevor ich den Prozess starte. Ich überprüfe, ob der aktuelle Benutzer in der Liste ist, und wenn ja, starte ich den Prozess mit dem aktuellen Benutzer. Wenn ein zweiter Benutzer dies zulässt, möchte er den Vorgang abbrechen. Ich möchte, dass er dies zulässt, aber ich möchte nicht, dass es sich um Sudoer handelt.

Aus diesem Grund habe ich überlegt, einen Prozess zu erstellen, der als root ausgeführt wird und die Aufforderung zum Beenden von Prozessen von einem Benutzer erhält, prüft, ob der Benutzer den Prozess starten / stoppen und den Prozess beenden darf.

Glaubst du, es könnte die beste Lösung sein?

slhck
quelle
Willkommen bei SO. Ich denke nicht, dass dies möglich ist ... Wie auch immer, dies ist besser für die Schwestersite von SO geeignet, serverfault.com. Möglicherweise wird es bald migriert, ohne dass Sie etwas unternehmen müssen.
Pekka unterstützt GoFundMonica
Über was für ein Programm reden wir? Es wäre im Allgemeinen schwierig, aber in einigen Fällen (z. B. Apache oder eine App, die Sie selbst ändern können) wäre es einfacher.
Kim

Antworten:

14

Es tut mir leid, aber das ist einfach nicht möglich (das ist beabsichtigt). Wenn Benutzer1 jedoch Mitglieder einer allgemeinen Gruppe sind, kann er in eine Datei schreiben, die der Prozess von Benutzer2 überprüft und dem Prozess angibt, dass er beendet werden soll.

Oder Benutzer2 kann etwas im Hintergrund ausführen, das eine Datei überprüft und dann die entsprechenden Signale sendet. Benutzer1 muss dann einfach in diese Datei schreiben. Dies ist möglicherweise einfacher, da keine Änderungen an den Programmen von user2 erforderlich sind.

Herkömmlicherweise kann Benutzer1 keine POSIX-Signale an den Prozess von Benutzer2 senden.

Tim Post
quelle
Danke für deine Antwort. In meinem Fall verwende ich die Datei zwar nicht, aber wir verwenden ein System ( dim.web.cern.ch/dim ), das das entsprechende Signal senden kann. Dann kann ein Prozess aufgerufen werden, der prüft, ob der Benutzer dazu berechtigt ist Stoppen Sie den Prozess und beenden Sie den Prozess.
@ATelesca - Ich verwende etwas sehr Ähnliches, um unterprivilegierten Benutzern das Steuern / Starten / Stoppen von virtuellen Xen-Maschinen in einer ziemlich großen Farm zu ermöglichen. Im Grunde das Gleiche.
Tim Post
9

Sofern ACLs oder SELinux oder etwas anderes keine bessere Möglichkeit bieten, geschieht dies nach meinem Dafürhalten mit einem SetUID- Skript. Wie Sie sich vorstellen können, sind sie berüchtigt für ihre Sicherheitsrisiken.

Sagen Sie in Bezug auf Ihren Fall, dass procOwner der Benutzername für den Prozesseigner ist und userA (uid 1000), userB (uid 1201) und userC (uid 1450) die Personen sind, die den Prozess beenden dürfen.

killmyproc.bash:

#!/bin/bash
case ${UID} in
1000|1201|1450) ;;
*) echo "You are not allowed to kill the process."
   exit 1;;
esac

kill ${PROCESS_ID}
# PROCESS_ID could also be stored somewhere in /var/run.

Stellen Sie dann den Eigentümer und die Berechtigungen ein mit:

chown procOwner:procGroup killmyproc.bash
chmod 6750 killmyproc.bash

Fügen Sie außerdem userA, userB und userC in die Gruppe ein procGroup.


quelle
Ich habe es versucht und es hat nicht funktioniert. Dem Benutzer, der kein Eigentümer ist, wurde eine Berechtigung für den Befehl kill verweigert.
Javid Jamae
1
Ich möchte nur hinzufügen, warum lässt das System nicht die Berechtigungen für das Kill-Skript steuern? Eine Gruppe aus userA, userB und userC zu erstellen, dann das Killscript dieser Gruppe zuzuweisen und es auf g + x zu bringen, scheint mir viel aufgeräumter zu sein.
Leonid Shevtsov
1
Das setUid-Bit ist in Shell-Skripten nicht zulässig. Sie müssen ein einfaches Wrapper-kompiliertes Programm erstellen, um es auszuführen
El '
2

Nicht konventionell - es ist die ultimative Denial-of-Service-Sicherheitsanfälligkeit, wenn ein Benutzer die Prozesse eines anderen Benutzers beendet.

Dies kann erfolgen, wenn der Zielprozess zusammenarbeitet. Eine Möglichkeit wäre, auf ein externes Ereignis zu überwachen (z. B. eine in / var / tmp erstellte Datei oder eine Nachricht auf einem Socket) und sie anzuweisen, sich selbst zu beenden. Wenn Sie es dazu nicht schreiben können, können Sie einen Wrapper dafür schreiben, der es startet und dann die Überwachung durchführt, wobei der untergeordnete Prozess abgebrochen wird, wenn das Ereignis eintritt.


quelle
1

Nein, kannst du nicht.

Wenn Sie Prozesse für andere Benutzer freigeben möchten, sollten Sie den Prozess unter einer gemeinsamen Benutzer-ID starten.

Konerak
quelle
1

Natürlich können Sie das Programm so schreiben, dass es ordnungsgemäß beendet wird, wenn es ein bestimmtes Signal (ein Begriff, der lose verwendet wird, um "ein vorbestimmtes Ereignis" zu bedeuten, kein POSIX-Signal) von einem bestimmten Benutzer (einer Liste von Benutzern) empfängt.

drxzcl
quelle
Signale haben kein "Benutzer" -Feld. Sie sind nur Signale.
LtWorf
Deshalb habe ich "ein vorbestimmtes Ereignis, kein POSIX-Signal" gesagt.
drxzcl
1

Sie können ein suid-Programm schreiben, das nur Benutzer einer bestimmten Gruppe ausführen dürfen und das das entsprechende Signal an den Prozess sendet. Ich bin mir nicht sicher, ob du auch Suid ausschließen wolltest.

Kim
quelle
0

Das suid-Bit funktioniert nicht mit Bash-Skripten. imho, der beste Weg ist, ein Wrapper-Skript "killservice" zu schreiben. Angenommen, Ihr Dienst wird als Benutzer serviceuser ausgeführt

#!/bin/bash
sudo -u serviceuser /usr/bin/killserviceworker

dann

# addgroup servicekiller
# chown root:servicekiller /usr/bin/killservice
# chmod 750 /usr/bin/killservice
# adduser bob servicekiller

Dann müssen Sie nur noch die Regel in / etc / sudoers hinzufügen, damit sie / usr / bin / killserviceworker als Benutzer serviceuser ausführen können, ohne ein Kennwort abzufragen:

servicekiller        ALL = (serviceuser:serviceuser) NOPASSWD: /usr/bin/killserviceworker

killserviceworker kann so aussehen:

#!/bin/bash
kill ${cat /run/service.pid}
Das Eis
quelle