Jak zabić proces rozpoczęty przez innego użytkownika bez uprawnień użytkownika root lub sudoer?

20

w środowisku Linuksa muszę zabić proces rozpoczęty przez użytkownika 2, jeśli jestem użytkownikiem 1, nie będąc sudoerami ani korzystając z roota. Czy wiesz, czy istnieje sposób na ustawienie tego podczas uruchamiania procesu? Takich jak lista użytkowników, którzy mogą zabić proces?

Faktem jest, że współbieżne wystąpienia tego samego procesu mogą być uruchamiane przez różnych użytkowników, dlatego nie jest dla mnie wygodne ustawienie identyfikatora grupy na proces. Inni użytkownicy, którzy nie należą do grupy, nie będą mogli rozpocząć drugiego równoległego procesu.

To, co mam, to lista użytkowników, którzy mogą rozpocząć proces, zdefiniowana w bazie danych, przed rozpoczęciem procesu sprawdzam, czy aktualny użytkownik na liście, a jeśli tak, rozpoczynam proces od bieżącego użytkownika. Jeśli drugi użytkownik może to zrobić, chce zabić proces, chciałbym, aby to zrobił, ale nie chcę, aby to był sudoers.

Dlatego zastanawiałem się nad stworzeniem procesu działającego jako root, który odbiera żądanie zabicia procesów od użytkownika, sprawdza, czy użytkownik może uruchomić / zatrzymać proces i zabija proces.

Czy uważasz, że to może być najlepsze rozwiązanie?

slhck
źródło
Witamy w SO. Nie sądzę, aby było to możliwe ... W każdym razie jest to bardziej odpowiednie dla siostrzanej strony SO, serverfault.com. Może wkrótce zostać tam migrowany, nie trzeba nic robić.
Pekka obsługuje GoFundMonica
O jakim programie mówimy? W ogólnym przypadku byłoby to trudne, ale w niektórych przypadkach (takich jak apache lub aplikacja, którą możesz samodzielnie zmodyfikować) byłoby łatwiej.
Kim

Odpowiedzi:

14

Przykro mi, ale po prostu nie jest to możliwe (jest to zgodne z projektem). Jeśli jednak członkowie wspólnej grupy, użytkownik 1 mógłby zapisać do pliku, który proces użytkownika 2 sprawdza, wskazując procesowi, że powinien się zakończyć.

Lub użytkownik 2 może uruchomić w tle coś, co sprawdza plik, a następnie wysyła odpowiednie sygnały. Użytkownik 1 musi wtedy po prostu zapisać do tego pliku. Może to być łatwiejsze, ponieważ nie wymagałoby żadnej modyfikacji programów użytkownika 2.

Konwencjonalnie nie, użytkownik 1 nie może wysyłać sygnałów POSIX do procesu użytkownika 2.

Tim Post
źródło
Dziękuję za odpowiedź. W moim przypadku rzeczywiście nie używam pliku, ale używamy systemu ( dim.web.cern.ch/dim ), który może wysłać odpowiedni sygnał, a następnie można wywołać proces sprawdzający, czy użytkownik może zatrzymać proces i zabija proces.
@ATelesca - Używam czegoś bardzo podobnego, aby umożliwić nieuprzywilejowanym użytkownikom kontrolowanie / uruchamianie / zatrzymywanie maszyn wirtualnych Xen na dość dużej farmie. Zasadniczo to samo.
Tim Post
9

O ile ACL, SELinux lub coś innego nie ma lepszego sposobu na zrobienie tego, tak jak widziałem to za pomocą skryptu SetUID . Jak możesz sobie wyobrazić, są niesławni z powodu zagrożeń bezpieczeństwa.

Jeśli chodzi o twoją sprawę, powiedz, że procOwner to nazwa użytkownika właściciela procesu, a użytkownik A (identyfikator użytkownika 1000), użytkownik B (identyfikator użytkownika 1201) i użytkownik C (identyfikator użytkownika 1450) to ludzie, którzy mogą zabić proces.

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.

Następnie ustaw właściciela i uprawnienia za pomocą:

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

A także umieścić Usera, UserB i userC w grupie procGroup.


źródło
Próbowałem tego i nie zadziałało. Użytkownik niebędący właścicielem otrzymał odmowę dostępu do polecenia kill.
Javid Jamae,
1
Chciałbym tylko dodać, dlaczego nie pozwolić systemowi kontrolować uprawnień do skryptu zabijania? Utworzenie grupy z użytkownika A, użytkownika B i użytkownika C, a następnie przeglądanie killscript w tej grupie i chmoddingowanie go do g + x wydaje mi się dużo bardziej uporządkowane.
Leonid Szewcow
1
bit setUid nie jest dozwolony w skryptach powłoki, musisz uruchomić prosty program skompilowany z otoki, aby go uruchomić
El '
2

Nie umownie - przyjazd dowolnego użytkownika i zabicie procesów innej osoby jest największą podatnością na atak typu „odmowa usługi”.

Można to zrobić, jeśli proces docelowy współpracuje. Jednym ze sposobów byłoby monitorowanie zewnętrznego zdarzenia (takiego jak plik tworzony w / var / tmp lub komunikat w gnieździe), instruując go, aby sam się zabił. Jeśli nie możesz tego napisać, możesz napisać opakowanie, które go uruchomi, a następnie wykona monitorowanie, zabijając proces potomny, jeśli wystąpi zdarzenie.


źródło
1

Nie możesz

Jeśli chcesz współdzielić procesy z innymi użytkownikami, powinieneś rozpocząć proces pod wspólnym identyfikatorem użytkownika.

Konerak
źródło
1

Oczywiście możesz napisać program w taki sposób, że z wdziękiem kończy się, gdy odbiera określony sygnał (termin używany luźno w znaczeniu „z góry określone zdarzenie”, a nie sygnał POSIX) od określonego (listy) użytkowników.

drxzcl
źródło
Sygnały nie mają pola „użytkownik”. To tylko sygnały.
LtWorf
Dlatego powiedziałem „z góry określone zdarzenie, a nie sygnał POSIX”.
drxzcl
1

Możesz napisać program Suid, który mogą wykonywać tylko użytkownicy w określonej grupie i który wysyła odpowiedni sygnał do procesu. Nie jestem pewien, czy chciałeś też wykluczyć suid.

Kim
źródło
0

bit suid nie działa ze skryptami bash. imho, najlepszym sposobem jest napisanie jakiegoś skryptu opakowującego „killservice”. Załóżmy, że Twoja usługa działa jako użytkownik usługi użytkownika

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

następnie

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

następnie wystarczy dodać regułę w / etc / sudoers, aby umożliwić im uruchomienie / usr / bin / killserviceworker jako użytkownika usługi bez pytania o hasło:

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

killserviceworker może wyglądać następująco:

#!/bin/bash
kill ${cat /run/service.pid}
Lód
źródło