如何在没有root或sudoer的情况下终止由其他用户启动的进程?


20

在Linux环境中,如果我是user1,而没有使用sudoers或使用root,则需要杀死一个由user2启动的进程。您是否知道启动过程时是否有设置方法?比如允许用户杀名单的进程?

事实是,可以从不同的用户启动同一进程的并发实例,这就是为什么我不方便为进程设置组ID的原因。不在该组中的其他用户将无法启动第二个并行进程。

我所拥有的是允许启动数据库中定义的进程的用户列表,在启动进程之前,我检查了列表中的当前用户,如果是,则与当前用户一起启动进程。如果第二个允许这样做的用户想要终止该进程,那么我希望它被允许这样做,但我不希望它成为麻烦的人。

因此,我正在考虑创建一个以root用户身份运行的进程,该进程接收来自用户的杀死进程的请求,检查是否允许用户启动/停止该进程并杀死该进程。

您认为这可能是最好的解决方案吗?


欢迎来到SO。我认为这不可能...无论如何,这更适合SO的姊妹站点serverfault.com。它可能很快就会迁移到那里,无需执行任何操作。
Pekka支持GoFundMonica 2010年

我们在谈论什么样的程序?在一般情况下这很困难,但是在某些情况下(例如apache或您可以修改自己的应用程序)会更容易。

Answers:


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
我只想补充一下,为什么不让系统控制kill脚本的权限?用userA,userB和userC创建一个组,然后将killscript绑到该组上,然后将其切成g + x,这对我来说似乎很整齐。
Leonid Shevtsov 2012年

1
setuid位不是在shell脚本允许,ü需要箱子简单的包装编译PROGRAMM运行它
厄尔尼诺”

2

传统上并非如此-任何用户来杀害其他人的进程都是最终的拒绝服务漏洞。

如果目标过程合作,就可以完成。一种方法是监视外部事件(例如,在/ var / tmp中创建的文件或套接字上的消息),以指示其杀死自身。如果您不能编写它来执行此操作,则可以为其编写包装程序以启动它,然后进行监视,如果事件发生,则杀死子进程。


1

不,你不能。

如果要与其他用户共享进程,则应使用通用用户ID启动该进程。


1

当然,您可以编写程序,使其在从某些(列表)用户接收到某个信号(宽松地表示“预定事件”,而不是POSIX信号)时正常终止。


信号没有“用户”字段。它们只是信号。
LtWorf 2014年

这就是为什么我说“预定事件,而不是POSIX信号”。
drxzcl 2014年

1

您可以编写一个suid程序,只有特定组中的用户才能执行,并将适当的信号发送到该进程。不确定您是否也打算排除suid。


0

suid位不适用于bash脚本。恕我直言,最好的方法是编写一些包装器脚本“ 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中添加规则,即可允许他们以用户serviceuser的身份运行/ usr / bin / killserviceworker而不要求输入密码:

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

killserviceworker可能如下所示:

#!/bin/bash
kill ${cat /run/service.pid}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.