真实用户ID、有效用户ID、保存用户ID的区别
- 2024-10-29 08:35:00
- admin 原创
- 66
问题描述:
我已经知道了真实的用户 ID。它是系统中用户的唯一编号。
在我的系统上,我的uid
是
$ echo $UID
1014
$
另外两个 ID 代表什么?
那么有效用户ID和已保存的用户ID有什么用处以及我们在系统中的什么地方使用它们?
解决方案 1:
之所以区分真实用户 ID 和有效用户 ID,是因为您可能需要暂时使用其他用户的身份(大多数情况下是 ,root
但也可以是任何用户)。如果您只有一个用户 ID,那么之后就无法更改回您的原始用户 ID(除非您相信您的承诺,如果您是root
,则可以使用root
的权限更改为任何用户)。
所以,真实用户 ID 就是您的真实身份(拥有该进程的人),而有效用户 ID 是操作系统用来决定是否允许您执行某项操作的(大多数情况下,也有一些例外)。
当您登录时,登录 shell 会将真实用户 ID 和有效用户 ID 设置为与密码文件提供的相同的值(您的真实用户 ID)。
现在,您还会执行 setuid 程序,除了以另一个用户身份运行(例如root
),setuid 程序还应该代表您执行某些操作。这是如何工作的?
执行 setuid 程序后,它将具有您的真实 ID(因为您是进程所有者)和文件所有者的有效用户 ID(例如root
),因为它是 setuid。
该程序利用超级用户权限执行所需的任何魔法,然后想要代表您执行某些操作。这意味着,尝试执行您不应该执行的操作应该会失败。它是如何做到这一点的?嗯,显然是通过将其有效用户 ID 更改为真实用户 ID!
现在 setuid 程序没有办法切换回来,因为内核只知道你的 id 和...你的 id。砰,你死定了。
这就是保存的设置用户 ID 的用途。
解决方案 2:
我将尝试通过一些例子逐步解释。
简短背景
每个进程都有自己的“进程凭证”,其中包括、、等属性,以及PID
真实PPID
有效PGID
的session ID
用户和组 ID:
RUID
、、、。EUID
`RGID`EGID
我们将重点关注这些。
第 1 部分:了解 UID 和 GID
现在我将使用我的凭据登录到 shell 并运行:
$ grep $LOGNAME /etc/passwd
rotem:x:1000:1000:rotem,,,:/home/rotem:/bin/bash
您可以看到我的登录名 (rotem)、UID和GID(均为 1000)以及其他详细信息(例如我登录的 shell)。
第 2 部分:了解 RUID 和 RGID
每个进程都有一个所有者并属于一个组。在我们的 shell 中,我们现在运行的每个进程都将继承我的用户帐户的权限,并以相同的 UID 和 GID 运行。
让我们运行一个简单的命令来检查它:
$ sleep 10 & ps aux | grep 'sleep'
并检查进程 UID 和 GID:
$ stat -c "%u %g" /proc/$pid/
1000 1000
这些是进程的真实 用户ID(RUID
)和真实组ID(RGID
)。
(*)检查其他选项以查看 UID 和 GID以及如何在一行中获取这些信息。
现在,接受这个事实:EUID
和属性是“多余的”,并且只是在后台EGID
等于RUID
和。RGID
第 3 部分:了解 EUID 和 EGID
我们以该ping
命令为例。
使用命令搜索二进制位置which
然后运行ls -la
:
-rwsr-xr-x 1 root root 64424 Mar 10 2017 ping
您可以看到文件的所有者和组是root
。这是因为该ping
命令需要打开一个特殊的套接字,而 Linux 内核需要root
特权才能做到这一点。
ping
但如果我没有权限该如何使用root
?
请注意文件权限的所有者部分中的“s”字母而不是“x”。
ping
这是针对特定二进制可执行文件(如和)的特殊权限位,sudo
称为setuid。
这就是EUID
和EGID
发挥作用的地方。
当执行类似的setuid二进制文件时ping
,该进程会将其有效用户 ID ( EUID
) 从默认值更改RUID
为这个特殊二进制可执行文件的所有者,在本例中为 -root
。
这一切都是通过这个文件有位这一简单事实来实现的setuid
。
EUID
内核通过查看进程的来决定此进程是否具有权限。由于现在EUID
指向root
,因此内核不会拒绝该操作。
注意:在最新的 Linux 版本中,命令的输出ping
看起来会有所不同,因为它们采用了Linux 功能方法而不是这种setuid方法 - 对于不熟悉的人,请阅读此处。
第 4 部分:SUID 和 SGID 怎么样?
SUID
当特权进程正在运行(例如root
)并且需要执行一些非特权任务时,将使用已保存的用户 ID( )。
这样的话,之前的有效UID(EUID
)会保存在里面SUID
,然后切换到非特权任务,当非特权任务完成后,会EUID
从 的值中取出SUID
,然后切换回特权账户。
解决方案 3:
我的理解是这样的。用户执行的文件(相当于启动一个进程)将具有与该用户 ID 相等的 RUID。这里要注意的重要一点是,创建文件的 uid 与执行文件的 uid 不同。它们可以相同或不同。因此,RUID 可能因执行文件的 UID 而异。当文件上有 setuid 位时,每当 uid 执行该文件时,该 uid 将暂时替换为文件所有者的 uid。因此,如果我们有一个由 uid 456 拥有的文件,并且该文件上有 setuid 位,每当 uid 123 执行该文件时,该文件将以 uid 456 执行。在这种情况下,uid 123 是 RUID,uid 456 是 EUID。
解决方案 4:
真实用户 ID 是生成该进程的用户。
有效用户 ID 是由正在执行的二进制文件上的 setuid 位确定的用户。
这里有一些关于 uids 和 euids 的事实,以及每个事实的手册来源:
当你以 root 身份生成并且需要暂时放弃权限之后仍然能够重新获得 root 权限时,你可以使用 euid,如 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 时,它不会传播 euid,除非你-p
像在 man bash(1) 中那样传递:
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).
解决方案 5:
@Rotem jackoby 的回答很好。作为后续,您可以查看我对这篇文章的回答。它包含一个您可以运行的示例 C 程序,以便亲眼看看 Linux 中进程的真实用户 ID (RUID)、有效用户 ID (EUID) 和已保存用户 ID (SUID) 之间的区别。
这里我只想指出,所有类 Unix 系统(当然也包括 Linux)的官方文档The Open Group Base Specifications Issue 7, 2018 版(请参阅此处的“3. 定义” )指出,RUID、EUID 和 SUID 的概念适用于“当用户身份与进程相关联时” (请参阅此处的3.436 用户 ID )。换句话说,如果用户没有启动或生成任何进程,那么谈论 RUID、EUID 或 SUID 是没有意义的,只能谈论用户 ID(UID),仅此而已。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件