我正在努力理解 SUID 位的概念以及它们为何有用。
例如,假设我有一个程序:
-rwsr-xr-x 1 root root 12364 Jan 12 2013 /usr/bin/foo
我的理解是,s
用户所有者的in execute位本质上意味着该文件可以由具有文件所有者权限的其他用户执行。
我为什么想要这样的东西?为什么不直接更改文件的组,以便它适用于所有用户所属的组?
答案1
Setuid 和 setgid(以及 setcap(如果存在))是提升权限的唯一方法。除了通过这种机制之外,进程可以放弃特权,但永远不会获得它们。因此,您将无法执行任何需要额外权限的操作。
例如,程序su
需要sudo
能够以任何用户身份运行命令。因此,无论哪个用户调用它们,它们都需要以 root 身份运行。
另一个例子是ping
。 TCP 和 UDP 套接字可供任何用户访问,因为这些协议有端口的概念,并且进程可以控制端口(这称为绑定端口),因此内核知道将数据包发送到哪里。 ICMP 没有这样的概念,因此只有以 root 身份运行(或具有适当功能)的程序才允许请求将 ICMP 数据包分派给它们。为了让任何用户都能够运行ping
,该ping
程序需要具有额外的权限,因此它是 setuid root(或 setcap)。
作为组权限的示例,请考虑将本地高分存储在文件中的游戏。由于只有用户获得的实际高分才应该存储在分数文件中,因此分数文件必须是玩家不可写入的。仅允许游戏程序写入分数文件。所以游戏程序设为 setgid games
,并且分数文件是组可写的games
,但玩家不可写。
还有一种提升权限的替代方法,即从特权启动程序启动需要额外权限的程序。当用户想要执行需要额外权限的任务时,他会运行一个前端程序,该程序使用某种形式的进程间通信来执行特权操作。这对于某些用例来说效果很好,例如ping
(一个ping
解析选项和报告进度的程序,以及ping-backend
发送和接收数据包的服务),但不适用于其他用例,例如游戏高分文件。
答案2
最常见的原因是可执行文件可以以 root 身份运行。例如:
find /bin/ -type f \( -perm -4000 -o -perm -2000 \) -ls | awk '{print $3,$NF}'
-rwsr-xr-x /bin/su
-rwsr-xr-x /bin/mount
-rwsr-xr-- /bin/fusermount
-rwsr-xr-x /bin/ping6
-rwsr-xr-x /bin/ping
-rwsr-xr-x /bin/umount
这些都是普通用户可以运行但需要提升权限的命令。mount
是一个完美的例子,您可以安装任何user
设置了类似选项的磁盘,/etc/fstab
但安装需要root
特权,因此设置了 SUID 位。
答案3
suid(或 sgid)位使可执行文件以与调用它的用户不同的用户/组运行。
如果这样做的唯一原因是访问特定文件,是的,您可以使用其他机制使该文件可写。但是,用户可以这样做任何事物到文件 - 而不是仅您的程序允许的事情。
例如,您可以让您的程序仅允许以某种格式向文件追加一行。但如果您只使用文件系统权限,用户也可以从文件中删除行。或者放入格式错误的行。
基本上,suid 程序可以强制执行任意策略。文件系统权限不能。例如,您的系统有一个 suid 程序/bin/su
。它为您提供 root shell(例如),但前提是您首先满足策略 — 通常需要输入 root 密码。仅凭权限是无法做到这一点的。