在 Linux 中以普通用户身份调用“ps”

在 Linux 中以普通用户身份调用“ps”

简单介绍一下我的问题:该命令ps将打印系统进程的信息。

但是当我登录时x并改变权限ps

chmod -x /bin/ps
chmod u+x /bin/ps
ls -l /bin/ps 
-rwxr--r-- 1 root root ...... ps

然后我创建一个新的 shell 脚本文件call_ps_via_root.sh

#!/bin/bash
ps

并设置x权限

chmod +x /bin/call_ps_via_root.sh
ls -l /bin/call_ps_via_root.sh
-rwxr-xr-x 1 root root ...... call_ps_via_root.sh

之后,我以普通用户登录萨米,然后我输入ps,它会打印

Permission denied

我输入/bin/call_ps_via_root.sh

仍然被否认。我怎样才能让它发挥作用call_ps_via_root.sh

答案1

你不能:如果你/bin/ps只让 root 可执行,那么它就只能由 root 执行。您不能仅将脚本包装在其周围以绕过权限检查。

设置用户 ID

如果您希望普通用户ps以 root 身份调用,则必须查看 set-uid 权限。来自setuid 文章在维基百科上:

setuid 和 setgid(分别是“执行时设置用户 ID”和“执行时设置组 ID”的缩写)1是 Unix 访问权限标志,允许用户以可执行文件所有者或组的权限运行可执行文件。它们通常用于允许计算机系统上的用户以临时提升的权限运行程序,以执行特定任务。虽然提供的假定用户 ID 或组 ID 权限并不总是提升,但至少它们是特定的。

另请参阅 chmod 的手册页

须藤

如果您希望普通用户仅通过 root 执行可执行文件sudo。它将允许您配置哪个用户将能够执行什么操作。

答案2

-rwxr--r-- 1 root root ...... ps

这表示拥有它的用户具有读取、写入和执行权限,而所有其他用户仅具有读取权限。所以除了 root 之外没有人可以执行ps

您编写的脚本可供所有人执行,但继承了调用它的人的权限,因此他在尝试执行该脚本时也会得到“权限被拒绝” ps,因为他仍然是普通用户。

我的猜测是,您希望阻止普通用户使用ps某些选项执行(这对我来说没有意义),但是您必须向脚本中添加setuid一点或一点(请参阅 的手册页)。当您执行此操作时,它不会从脚本的调用者那里获取权限,而是从拥有该脚本的人那里获取权限。setgidchmod

但要小心suid在脚本上设置位本质上是不安全的。您可以使用环境变量做很多事情,例如告诉 shell 执行命令 - 然后它们以 root 身份执行(这里带有粘性位的自定义 C 程序是更好的解决方案)。

编辑:另一种解决方案是使用sudo.您还可以在此处配置 ed 程序允许哪些参数sudo

编辑2:为什么我认为仅仅禁止用户执行不是一个好主意ps?据我所知,所有的信息ps输出也可以通过系统获取/proc- 所以如果你不做其他任何事情,它只是通过混淆来实现安全性(或任何你想要实现的目标)。

答案3

一般来说,最好使用“sudo”。如果您没有安装和配置 sudo

su - someuser -c "/yourscript.sh"

答案4

有时,您希望授予用户访问只能使用 root 工具才能获得的信息的权限,而不通过sudo.例如,提供 的信息,smartctl -A而不提供对 的全部功能的访问smartctl

以程序为例hddtemp。它从驱动器的 SMART 数据中读取给定硬盘驱动器的温度并将其打印到标准输出。虽然您通常需要 root 权限才能执行此操作,但它还提供了守护程序模式,程序将以 root 身份运行,在后台等待非 root 客户端请求,并在它们连接套接字时将输出转发给它们。通过这种方式,您可以实现一个守护进程(以 root 身份启动),该守护ps进程在客户端需要时运行并重定向其输出。

考虑这个 Python 示例(可能需要以 root 身份运行):

import socket, subprocess

HOST = '127.0.0.1'
PORT = 50006

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((HOST,PORT))
s.listen(1)

while True:
    conn,addr = s.accept()
    pipe = subprocess.Popen(["/bin/ps"],stdout=subprocess.PIPE).stdout
    for line in pipe:
        conn.send(line)
    conn.close()

然后你可以netcat localhost 50006在你的中输入一个call_ps_via_root.sh,你就完成了。

相关内容