简单介绍一下我的问题:该命令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
一点或一点(请参阅 的手册页)。当您执行此操作时,它不会从脚本的调用者那里获取权限,而是从拥有该脚本的人那里获取权限。setgid
chmod
但要小心: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
,你就完成了。