真实用户 ID、有效用户 ID 和保存用户 ID 的区别

我已经知道了 真正的用户 ID,它是系统中用户的唯一编号。

在我的系统里,我的 uid

$ echo $UID
1014
$

另外两张身份证代表什么?

有效用户 ID保存的用户 ID的用途是什么? 我们在系统的什么地方使用它们?

101092 次浏览

真实用户标识和有效用户标识之间的区别是因为您可能需要临时获取另一个用户的标识(大多数情况下,这是 root,但它可以是任何用户)。如果您只有一个用户 id,那么以后就没有办法再变回原来的用户 id 了(除非您认为这是理所当然的,如果您是 root,那么使用 root的特权可以变回任何用户)。

所以,真正的用户 ID 是你真正的身份(拥有进程的人) ,而有效的用户 ID 是操作系统在决定是否允许你做某些事情时所看到的(大多数时候,有一些例外)。

当您登录时,login shell 将真实和有效的用户 id 设置为密码文件提供的相同值(您的真实用户 id)。

现在,还需要执行一个 setuid 程序,除了作为另一个用户(例如 root)运行之外,setuid 程序是 还有,它应该代表您执行某些操作。这是怎么回事?
在执行 setuid 程序之后,它将拥有您的真实 id (因为您是进程所有者)和文件所有者的有效用户 id (例如 root) ,因为它是 setuid。

该程序使用超级用户权限完成它需要完成的任何工作,然后希望以您的名义做一些事情。这意味着,尝试做一些你不应该能够做 应该会失败的事情。它是怎么做到的?很明显,通过将它的有效用户标识改为真正的用户标识!

现在 setuid 程序无法切换回来,因为内核只知道 id 和... 你的身份证。砰,你死了。

这就是保存的 set-user id 的用途。

我将尝试用一些例子逐步解释。

背景简短

每个进程都有自己的“进程凭证”,包括 PIDPPIDPGIDsession ID等属性,以及真正有效的用户和组 ID: RUIDEUIDRGIDEGID.

我们会关注这些的。


第1部分: 理解 UID 和 GID

现在,我将用我的凭证登录到一个 shell 中,然后运行:

$ grep $LOGNAME /etc/passwd
rotem:x:1000:1000:rotem,,,:/home/rotem:/bin/bash

您可以看到我的日志名(rotem) ,UIDGID都是1000,以及其他细节,比如我登录的 shell。


第2部分: 理解 RUID 和 RGID

每个进程都有一个所有者,属于一个组 。 在我们的 shell 中,我们现在运行的每个进程将继承我的用户帐户的特权,并使用相同的 UID 和 GID 运行。

让我们运行一个简单的命令来检查它:

$ sleep 10 & ps aux | grep 'sleep'

并检查进程 UID 和 GID:

$ stat -c "%u %g" /proc/$pid/
1000 1000

它们是 程序真的 用户名(RUID)和实际 组别编号(RGID)。

(*)检查 查看 UID 和 GID 的其他选项如何在一行中得到这个

现在,接受这样一个事实,即 EUIDEGID属性是“冗余的”,只等于幕后的 RUIDRGID


第3部分: 理解 EUID 和 EGID

让我们以 ping命令为例。

使用 which命令搜索二进制位置,然后运行 ls -la:

-rwsr-xr-x  1 root root   64424 Mar 10  2017  ping

您可以看到文件的所有者和组是 root。这是因为 ping命令需要打开一个特殊的套接字,而 Linux 内核需要 root特权。

但是如果我没有 root特权,我怎么能使用 ping呢?

请注意文件权限的所有者部分中的 “ s”字母而不是“ x”。

这是特定二进制可执行文件(如 pingsudo)的特殊权限位,称为 赛图伊德

这就是 EUIDEGID发挥作用的地方。

当执行 ping这样的 赛图伊德二进制文件 进程将其有效用户 ID (ABC1)从默认的 ABC2更改为这个特殊的二进制可执行文件的所有者,在本例中为 -root时,会发生什么情况。

所有这些都是由这个文件具有 setuid位这一简单事实完成的。

内核通过查看进程的 EUID来决定这个进程是否拥有特权。因为现在 EUID指向 root,所以内核不会拒绝该操作。

注意 : 在最新的 Linux 版本中,ping命令的输出看起来会有所不同,因为它们采用了 Linux 能力方法而不是 赛图伊德方法——对于那些不熟悉的人来说——读取 给你

第4部分: SUID 和 SGID 怎么样?

The Saved user ID (SUID) is being used when a privileged process is running (as root for example) and it needs to do some unprivileged tasks.

在这种情况下,之前的有效 UID (EUID)将保存在 SUID中,然后更改为无特权任务。当非特权任务完成后,EUID将从 SUID的值中取出,并切换回特权帐户。

我是这么理解的。用户执行的文件(相当于启动一个进程)将有一个与该用户的 id 相等的 RUID。这里需要注意的是,创建文件的 uid 与执行文件的 uid 不同。它们可以是相同的,也可以是不同的。因此,RUID 可能会根据执行文件的 UID 而有所不同。当文件具有 setuid 位时,无论何时 uid 执行该文件,该 uid 都将被替换为文件所有者的 uid。因此,如果我们有一个由 uid 456拥有的文件,并且上面有 setuid 位,那么每当 uid 123执行该文件时,该文件将使用 uid 456执行。在这个场景中,uid123是 RUID,uid456是 EUID。

真正的用户 id 是生成进程的用户。

有效的用户 id 是由正在执行的二进制文件上的 setuid 位确定的用户。

下面是一些关于 uid 和 euid 的真理,以及它们的手工资料来源:

当你作为 root 用户生成时,你可以使用 euid,你需要暂时放弃特权,但是仍然可以恢复 root 用户的特权,就像 man setuid (2) :

Thus, a set-user-ID-root program wishing to temporarily drop root privileges, as‐
sume the identity of an unprivileged user, and then regain root privileges after‐
ward cannot use setuid().  You can accomplish this with seteuid(2).

您还可以使用它来提高 setuid 程序的特权。如果你的有效用户 id 是 root,那么一切都会像你是 root 一样,除了我认为唯一的例外是文件访问检查会检查你的真实用户 id 而不是有效用户 id,这是一个混淆的来源,就像 man access (2) :

The check is done using the calling process's real UID and GID,  rather
than the effective IDs as is done when actually attempting an operation
(e.g., open(2)) on the file.  Similarly, for the root user,  the  check
uses the set of permitted capabilities rather than the set of effective
capabilities; and for non-root users, the check uses an  empty  set  of
capabilities.

在调用 bash 时,除非像 man bash (1)那样传递 -p,否则它不会传播 euid:

If the shell is started with the effective user (group) id not equal to the  real
user  (group)  id,  and the -p option is not supplied, no startup files are read,
shell functions are not inherited from the environment, the SHELLOPTS,  BASHOPTS,
CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored,
and the effective user id is set to the real user id.  If the -p option  is  sup‐
plied  at invocation, the startup behavior is the same, but the effective user id
is not reset.

在使用 sudo 时,有效用户 ID 和实际用户 ID 都设置为 man sudo (8) :

When sudo executes a command, the security policy specifies the execution environ‐
ment for the command.  Typically, the real and effective user and group and IDs are
set to match those of the target user, as specified in the password database, and
the group vector is initialized based on the group database (unless the -P option
was specified).