在系统范围内进行更改的程序需要sudo
除非我已经是root用户。
现在,问题是:如何确切地系统是否知道我是(不是)root?
可以:
检查我是否属于特定组?如果是这样,我需要加入哪个组?
检查 root 本身的众所周知的 ID(即“root 用户”被硬编码到源代码中)?
如果是这样,如果我的根帐户被损坏会发生什么?由于无法创建另一个具有 root 权限的帐户,我是否会被迫重新安装操作系统?根据某些文件的内容检查我的名称/组并授予正确的权限?如果是,哪个文件包含此信息?
做点别的事吗?如果是这样,它有什么作用?
答案1
Unix 上的用户名并不重要。只有数字用户 ID 是。 root 的数字 ID 始终为 0。这是在各处(在内核、实用程序等中)进行硬编码的。
您可以通过运行找到您的数字用户 ID id
。
请注意,您的数字用户 ID 是正在运行的进程的一个属性。当您登录时,您通过( login
、等)登录的进程sshd
将以 root (UID 0) 身份运行,一旦您的登录被授权,它就会切换到您的用户 ID 并运行您的 shell(在 /etc/passwd 中指定)。从那里,要使用sudo
、su
或其他东西来切换用户 ID,这些程序具有设定值位设置(chmod u+s
或chmod 4xxx
将设置该位),以便当它们执行时,进程以程序所有者的身份运行(root,UID 0)。同样,一旦您获得授权,他们就会sudo
以 root 身份运行任何程序(无论您告诉运行什么,shell 等)。 (在这种su
情况下,如果您指定要切换到的另一个用户,它将切换到该 UID,然后运行 shell 或其他内容。)
来回答您的其他问题是,root 帐户实际上没有办法“损坏”,因为它实际上只是一个数字,但可能有一些原因导致您不能仅以 root 身份登录(例如忘记密码)。这些都不需要重新安装操作系统,但它们可能需要一些技术技能来修复。 (例如,如果您忘记了 root 密码,您可以使用 sudo 使用您的密码访问 root,启动到单用户模式以重置密码,或者从实时媒体或救援环境启动。)
答案2
在与 Unix 打交道的 25 年中,我从未见过 root 帐户损坏而系统本身无法使用的情况。忘记的密码可以很容易地重置,我不认为这是损坏。在运行 BSD 的 Vax 上发生过一次令人难忘的事件,我不小心(别问)从 /dev 中删除了所有内容,包括磁带驱动器(1/4" 卷盘磁带)的条目。这使得从 /dev 恢复起来有点困难备份。
在 Unix 下,确实没有什么可以损坏的。登录过程只是启动一个 shell 并从 root 的主目录运行 rc 文件。除了 rc 文件之外,如果其余文件对 root 不起作用,那么它可能对其他人也不起作用。如果您以 root 身份登录图形系统(KDE 或 Gnome),我只能说“不要这样做”。
您可以拥有多个 uid 为 0 的帐户。当一台计算机有多个管理员时,这可以用作 sudo 的替代方法。缺点是您现在有多个根帐户需要保护。您也无法获得 sudo 为您所做的日志记录。
答案3
史蒂文·普理查德的回答很好,但我想我应该提供类似信息的不同呈现方式。
每个进程都以特定用户身份运行。用户由一个数字(即用户 ID)来标识,该数字存储在仅内核可用的进程信息中。用户ID为0的用户具有特殊的权限,通常称为root
;这个名称root
对于内核来说并不特殊(但是如果你改变它,你可能会混淆很多应用程序)。许多事情(例如加载内核模块、直接访问大多数硬件设备等)都要求执行操作的进程以用户 ID 0² 运行。
当系统启动时,内核启动的第一个进程以超级用户身份运行。该进程称为init
,最终启动许多系统服务(cron
、syslogd
、...)和登录程序(login
、sshd
、等)。
登录时,您输入凭据(名称、密码等),登录程序会检查这些凭据。如果凭据被接受,登录程序将更改为您的用户 ID(这是授予超级用户的权限之一)。
如果您搞砸了用户数据库(如果您不以 root 身份编辑或删除随机文件,则不太可能发生这种情况),您可能无法再登录。您仍然可以启动到单用户模式或从 Live CD 来修复系统。
该程序sudo
允许您以 root 身份运行命令。通常,如果您运行一个程序,它会继承启动它的进程的用户 ID。但sudo
设定值root:这是一个例外,由 上的权限位决定/usr/bin/sudo
,这使得它以用户 ID 0 的身份运行。sudo
检查是否允许调用它的用户以提升的权限运行命令(通过查阅/etc/sudoers
),然后运行该命令或发出错误信号。
1有时不止一个,但这不会出现在这个答案中。
²或有权利能力,但现在先不用管这个。
答案4
“root”权限的概念被传播到各种控制机制中:
- 硬件:Intel CPU(以及一般所有其他 CPU)具有各种“特权状态” - 在每种特权状态下,您可以或不能运行某些类别的汇编指令 - 通常,特权较高的状态将有权执行更多指令。
https://en.wikipedia.org/wiki/Protection_ring
而特权指令之一就是控制内存页表。这些不同的环还为您提供内核与用户空间执行线程。
- 从(1)开始,通过页表机制,你还将拥有各种类型的内存:环0或环3内存。
https://en.wikipedia.org/wiki/Kernel_page-table_isolation
https://manybutfinite.com/post/cpu-rings-privilege-and-protection/
Ring 0 将拥有更多权限,并存储您所有的敏感信息 - 其中包括您的 USERID 信息。如果你的userid=0,那么你就是特权用户,如果不是,那么你只是一个普通用户。每个用户 ID 在内核中都有不同的页表 - 这就是为什么每个进程不能直接修改彼此的内存。请记住,用户 ID 存储在 Ring0 内存中 - 在 Ring 3 中运行的进程将永远无法修改此信息,如果可以,那么您必须设法升级到内核来修改它(“权限升级”)。
要检查您是 root 还是非 root - 在内核中执行以下操作:
if (current_cred()->uid != 0)
return -EPERM;
如果您不在内核中,您将无法访问存储在内核中的所有凭据。并且一个进程无法读取另一个进程内存 - 因此,如果您不在内核中,则不需要进行此类检查,内核可以查看所有进程的所有内存。
总结一下:您正在运行的任何进程,始终以环 3 特权运行(对于英特尔),将在内核中保留用户 ID 信息 - 该信息最初必须是从另一个内核组件创建的,或根进程(userid = 0)。任何 root 拥有的进程(仍在 Ring3 上运行)都将具有功能(为什么?因为它是在 Linux 内核源代码本身中编写的:
https://stackoverflow.com/questions/15774548/check-for-user-root-within-linux-kernel)轻松过渡到ring 0特权。这解释了为什么无论你如何修改自己的内存(都在环 3 中运行),你将永远无法看到/更改你的用户 ID。
您询问所有权是否存储在文件中 - 是的,文件确实包含用户 ID 所有权。并且正在运行的进程(具有特定的用户 ID)无法修改具有不同用户 ID 的其他文件。安全性以这种方式划分在文件+正在运行的进程中(其中用户ID存储在内核内存中)。但您不能完全确定其他人无法读取您的物理文件。
如果你可以把硬盘带到另一台机器如果您拥有 root 控制权,则可以假设为读取硬盘上特定用户 ID 拥有的物理文件所需的任何用户 ID。即,如果您没有物理安全性,您可以绕过硬盘上的所有安全机制,除非它已加密。