如何在 Linux 上使用 SUID、SGID 和 Sticky Bits

理解 Linux 中的 SUID、SGID 和粘滞位

在 Linux 系统中,SUID、SGID 和粘滞位是为可执行文件和目录设置的强大特殊权限。它们能够增强系统的安全性,同时也可能带来潜在的风险。本文将深入探讨这些权限的用途、优势以及需要注意的事项。

它们的工作原理

在多用户操作系统中,安全性是一个复杂的问题。例如,密码的存储和管理就是一个挑战。系统需要安全地存储密码,以便在用户登录时进行验证。由于密码的重要性,保护它们至关重要。Linux 通过加密密码并限制访问包含密码的文件(仅限 root 用户)来保护密码。然而,这也引出了一个问题:如果只有 root 用户才能访问密码文件,那么非 root 用户如何更改自己的密码?

权限提升:SUID

通常情况下,Linux 命令和程序会以启动用户的权限运行。例如,当 root 用户运行 passwd 命令来修改密码时,该命令会以 root 权限运行,从而可以访问存储密码的 /etc/shadow 文件。理想情况下,任何用户都应该能够运行 passwd 程序并保留 root 的提升权限,这样每个人都可以修改自己的密码。这就是用户 ID 位(SUID)的作用:它允许程序以文件所有者的权限运行,而不是以启动用户的权限运行。因此,passwd 程序可以以 root 权限运行,即使是由普通用户启动的。

安全风险与责任

SUID 机制允许应用程序在运行时临时借用权限,但它只是安全故事的一部分。防止用户篡改他人密码的控制机制实际上在 passwd 程序中实现,而不是在操作系统或 SUID 机制中。以提升的权限运行的程序,如果不是以安全为核心进行设计,可能会带来安全风险。这意味着在开发程序时,安全性必须是首要考虑的因素,而不是事后补救。开源软件的优势在于可以查看源代码或参考可信的同行评审,例如 passwd 程序的源代码包含检查,确保程序是否以 root 权限运行。如果是 root 用户(或使用 sudo 的用户),则允许执行不同的功能。

这段代码用于检测用户是否是 root。

以下是一个例子:root 用户可以更改任何用户的密码,因此程序无需检查用户是否有权更改密码。对于 root 用户,程序会跳过这些检查

核心的 Linux 命令和实用程序都经过了严格的安全审查和测试,但始终存在未知漏洞的风险。不过,一旦发现新的漏洞,通常会很快发布补丁或更新。对于第三方软件,尤其是不开源的软件,使用 SUID 时需要格外小心。要确保它们不会给系统带来安全风险。不要将权限提升给那些无法正确自我管理的程序和用户。

哪些命令使用 SUID

以下是一些在普通用户运行时使用 SUID 位赋予命令提升权限的 Linux 命令:

ls -l /bin/su
ls -l /bin/ping
ls -l /bin/mount
ls -l /bin/umount
ls -l /usr/bin/passwd

注意,文件名以红色突出显示,表示设置了 SUID 位。文件或目录的权限通常用三组三个字符表示:rwx,分别代表读、写和执行。如果有这些字母,则表示已授予相应权限;如果是连字符 (-),则表示未授予该权限。权限分为三组:文件所有者、文件所属组和其他用户。当在文件上设置 SUID 位时,所有者的执行权限会以 “s” 表示。如果 SUID 位设置在没有执行权限的文件上,则会以大写 “S” 表示。

SUID 示例

让我们来看一个例子。当普通用户 dave 键入 passwd 命令:

passwd

passwd 命令会提示 dave 输入他的新密码。我们可以使用 ps 命令查看正在运行的进程的详细信息。我们将 ps 命令与 grep 命令一起使用,并在不同的终端窗口中查找 passwd 进程。我们将使用 ps 中的 -e (每个进程)和 -f(全格式)选项。

我们输入以下命令:

ps -e -f | grep passwd

报告了两行,其中第二行是 grep 进程查找包含 “passwd” 字符串的命令。但我们感兴趣的是第一行,它是 dave 启动的 passwd 进程。我们可以看到,passwd 进程的运行方式与 root 用户启动它时相同。

设置 SUID 位

使用 chmod 命令可以轻松更改 SUID 位。u+s 符号模式用于设置 SUID 位,而 u-s 符号模式用于清除 SUID 位。为了演示 SUID 位,我们创建了一个名为 htg 的小程序。它位于 dave 用户的根目录中,并且未设置 SUID 位。运行时,它会显示真实和有效的用户 ID。真实 用户标识符 属于启动程序的用户。有效 ID 是程序运行时所拥有的帐户权限。

我们输入以下内容:

ls -lh htg
./htg

当我们运行程序的本地副本时,看到真实 ID 和有效 ID 都设置为 dave,因此它的行为就像普通程序一样。现在让我们将它复制到 /usr/local/bin 目录中,以便其他用户可以使用它。我们键入以下内容,使用 chmod 设置 SUID 位,然后检查它是否已设置:

sudo cp htg /usr/local/bin
sudo chmod u+s /usr/local/bin/htg
ls -hl /usr/local/bin/htg

程序已复制,并设置了 SUID 位。我们再次运行它,但这次运行的是 /usr/local/bin 文件夹中的副本:

htg

尽管 dave 启动了该程序,但有效 ID 设置为 root 用户。如果 Mary 启动该程序,也会发生同样的事情,如下所示:

htg

真实 ID 是 mary,有效 ID 是 root。程序以 root 用户的权限运行。

SGID 位

设置组 ID(SGID)位与 SUID 位非常相似。当在可执行文件上设置 SGID 位时,有效组会设置为该文件的组。该进程以文件组成员的权限运行,而不是启动它的人的权限。我们调整了 htg 程序,使其也显示有效组。我们将 htg 程序的组更改为用户 mary 的默认组,mary。我们还将使用 u-s 和 g+s 符号模式和 chown 来删除 SUID 位并设置 SGID 位。

为此,我们输入以下内容:

sudo chown root:mary /usr/local/bin/htg
sudo chmod u-s,g+s /usr/local/bin/htg
ls -lh /usr/local/bin/htg

您可以在组权限中看到由 “s” 表示的 SGID 位。另外,请注意组设置为 mary,文件名现在以黄色突出显示。在运行程序之前,我们先确定 dave 和 mary 属于哪些组。我们将使用带有 -G(组)选项的 id 命令,打印所有组 ID。然后,我们将以 dave 的身份运行 htg 程序。

我们输入以下命令:

id -G dave
id -G mary
htg

mary 的默认组 ID 是 1001,htg 程序的有效组是 1001。所以,尽管是 dave 启动的,但它是在 mary 组成员的权限下运行的。就像 dave 加入了 mary 的小组一样。

让我们将 SGID 位应用于目录。首先,我们创建一个名为 “work” 的目录,然后将其组更改为 “geek”。然后,我们在该目录上设置 SGID 位。

当我们使用 ls 检查目录的设置时,我们还会使用 -d (目录) 选项,以便我们可以看到目录的详细信息,而不是它的内容。

我们输入以下命令:

sudo mkdir work
sudo chown dave:geek work
sudo chmod g+s work
ls -lh -d work

SGID 位和 “geek” 组已经设置完成。这些设置将影响在 work 目录中创建的任何项目。我们输入以下内容,进入 work 目录,创建一个名为 “demo” 的目录,并检查其属性:

cd work
mkdir demo
ls -lh -d demo

SGID 位和 “geek” 组会自动应用到 “demo” 目录中。

接下来,我们输入以下内容,使用 touch 命令创建一个文件,并检查其属性:

touch useful.sh
ls -lh useful.sh

新文件的组会自动设置为 “geek”。

粘滞位

粘滞位因其历史用途而得名。当设置在可执行文件上时,它会向操作系统指示,将可执行文件的文本部分保存在交换空间中,以加快它们的重用速度。在 Linux 中,粘滞位只影响目录,在文件上设置它没有意义。当您在一个目录上设置粘滞位时,用户只能删除该目录中属于自己的文件,而不能删除属于其他用户的文件,无论文件上设置了什么样的权限组合。这允许您创建一个目录,所有用户和他们启动的进程都可以使用它作为共享文件存储。这些文件受到保护,因为用户无法删除不属于自己的文件。

我们创建一个名为 “shared” 的目录。我们将使用 o+t 符号模式和 chmod 设置该目录上的粘滞位。然后,我们查看该目录以及 /tmp 和 /var/tmp 目录的权限。

我们键入以下命令:

mkdir shared
sudo chmod o+t shared
ls -lh -d shared
ls -lh -d /tmp
ls -lh -d /var/tmp

如果设置了粘滞位,则“其他”文件权限集的可执行位设置为 “t”。文件名也以蓝色突出显示。 /tmp 和 /var/tmp 文件夹是目录的两个示例,它们为所有者、组和其他用户设置了所有文件权限(这就是它们以绿色突出显示的原因)。它们用作临时文件的共享位置。有了这些权限,理论上任何用户都可以做任何事情。但是,粘滞位会覆盖这些设置,确保任何用户都不能删除不属于他们的文件。

要点回顾

以下是对本文所涵盖内容的快速总结,供您参考:

SUID 仅适用于文件
SGID 可应用于目录和文件
粘滞位 仅可应用于目录
大写 “S”, “G”, 或 “T” 表示执行位 (x) 尚未设置