Как убить процесс, запущенный с другим пользователем, не будучи пользователем root или sudoer?


20

в среде Linux мне нужно убить процесс, который был запущен пользователем user2, если я пользователь user1, но не являюсь пользователем sudoers и не использую root. Знаете ли вы, есть ли способ установить это при запуске процесса? Например, список пользователей, которым разрешено убивать процесс?

Дело в том, что одновременные экземпляры одного и того же процесса могут запускаться от разных пользователей, поэтому мне не удобно устанавливать идентификатор группы для процесса. Другие пользователи, не входящие в группу, не смогут запустить второй параллельный процесс.

У меня есть список пользователей, которым разрешено запускать процесс, определенный в базе данных, перед началом процесса я проверяю, есть ли текущий пользователь в списке, и, если да, я запускаю процесс с текущим пользователем. Если второй пользователь разрешил сделать это, хочет убить процесс, я бы хотел, чтобы ему разрешили это сделать, но я не хочу, чтобы это было sudoers.

Поэтому я думал о создании процесса, работающего от имени пользователя root, который получает запрос на удаление процессов от пользователя, проверяет, разрешено ли пользователю запускать / останавливать процесс, и убивает процесс.

Как вы думаете, это может быть лучшим решением?


Добро пожаловать в ТАК. Я не думаю, что это возможно ... Во всяком случае, это больше подходит для дочернего сайта SO, serverfault.com. Это может быть перенесено туда скоро, не нужно ничего делать.
Пекка поддерживает GoFundMonica

О какой программе мы говорим? В общем случае это будет сложно, но в некоторых случаях (например, apache или приложение, которое вы можете изменить самостоятельно) это будет проще.
Ким

Ответы:


14

Извините, но это просто невозможно (так задумано). Однако, если члены общей группы, user1 может записать в файл, который проверяет процесс user2, указывая процессу, что он должен завершиться.

Или user2 может запустить что-то в фоновом режиме, что проверяет файл, а затем отправляет соответствующие сигналы. Затем User1 просто должен записать в этот файл. Это может быть проще, так как это не потребует какой-либо модификации программ user2.

Обычно нет, user1 не может отправлять сигналы POSIX процессу user2.


Спасибо за Ваш ответ. В моем случае, действительно, я не использую файл, но мы используем систему ( dim.web.cern.ch/dim ), которая может отправлять соответствующий сигнал, затем может быть вызван процесс, который проверяет, что пользователю разрешено остановить процесс и убивает процесс.

@ATelesca - я использую что-то очень похожее, чтобы позволить малообеспеченным пользователям управлять / запускать / останавливать виртуальные машины Xen на довольно большой ферме. В основном то же самое.
Тим Пост

9

Если ACL, SELinux или что-то еще не имеют лучшего способа сделать это, то, как я видел, это делается с помощью скрипта SetUID . Как вы можете себе представить, они печально известны своей угрозой безопасности.

Что касается вашего случая, скажите, что procOwner - это имя пользователя для владельца процесса, а userA (uid 1000), userB (uid 1201) и userC (uid 1450) - люди, которым разрешено уничтожать процесс.

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.

Затем установите владельца и разрешения с помощью:

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

А также поместите userA, userB и userC в группу procGroup.


Я попробовал это, и это не сработало. Пользователь, не являющийся владельцем, получил запрещение на команду kill.
Джавид Джамаэ

1
Я бы просто добавил, почему бы не позволить системе контролировать разрешения для сценария уничтожения? Создание группы из userA, userB и userC, затем добавление киллскрипта в эту группу и изменение его в g + x кажется мне более уместным.
Леонид Шевцов

1
Бит setUid не разрешен в сценариях оболочки, для его запуска необходимо создать простую скомпилированную программу-обертку
El '

2

Традиционно - когда какой-либо пользователь приходит и убивает чужие процессы, это предельная уязвимость отказа в обслуживании.

Это может быть сделано, если целевой процесс сотрудничает. Один из способов - отслеживать внешнее событие (например, файл, создаваемый в / var / tmp или сообщение в сокете), инструктируя его убить себя. Если вы не можете написать это для этого, вы можете написать для него оболочку, которая запускает его, а затем выполняет мониторинг, убивая дочерний процесс в случае возникновения события.


1

Нет, ты не можешь.

Если вы хотите поделиться процессами с другими пользователями, вы должны запустить процесс под общим идентификатором пользователя.


1

Конечно, вы можете написать программу таким образом, чтобы она грациозно завершала работу, когда получала определенный сигнал (термин, использованный свободно для обозначения «заранее определенного события», а не сигнала POSIX) от определенного (списка) пользователей.


Сигналы не имеют поля пользователя. Они просто сигналы.
LtWorf

Вот почему я сказал «предопределенное событие, а не сигнал POSIX».
drxzcl

1

Вы можете написать программу suid, которую могут выполнять только пользователи в определенной группе и которая посылает соответствующий сигнал процессу. Не уверен, что вы хотели исключить suid, хотя.


0

бит suid не работает со скриптами bash. imho, лучший способ - написать скрипт-оболочку "killservice". Предположим, что ваш сервис работает как пользователь serviceuser

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

тогда

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

тогда вам просто нужно добавить правило в / etc / sudoers, чтобы они могли запускать / usr / bin / killserviceworker от имени пользователя serviceuser без запроса пароля:

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

killserviceworker может выглядеть так:

#!/bin/bash
kill ${cat /run/service.pid}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.