从 0 到 1,吃透 Linux 权限管理的底层逻辑

发布于:2025-03-28 ⋅ 阅读:(27) ⋅ 点赞:(0)

Shell的运行原理:命令执行的起点

严格来说,Linux 是一个操作系统,其核心部分被称为 “kernel”。然而,普通用户无法直接使用 kernel,而是需要借助 kernel 的 “外壳” 程序 ——shell,来与 kernel 进行交互。

从技术角度来看,Shell 的最简定义是命令行解释器(command Interpreter)。它主要承担两项关键任务:

一方面,将用户输入的命令翻译为 kernel 能够理解的形式,以便 kernel 进行处理;

另一方面,把 kernel 的处理结果翻译为用户能够理解的信息,反馈给用户。

为了更好地理解这一过程,可以将其与 Windows 系统进行对比。在 Windows 系统中,我们并非直接操作 Windows 内核,而是通过图形接口,例如点击操作来完成任务。比如要进入 D 盘,通常是双击 D 盘盘符;要运行一个应用程序,也是通过点击相应图标。

在 Linux 系统中,Shell 起到了类似的作用。它主要负责对用户输入的指令进行解析,并将解析后的指令传达给 Linux 内核。内核运行出结果后,再由 Shell 将结果解析呈现给用户。

举个形象的例子来帮助理解:假设你是一位闷骚且害羞的程序员,Shell 就如同媒婆,而操作系统内核则是村头那位让你心动的漂亮姑娘小花。你看上了小花,却不好意思直接表白,于是让家人找媒婆帮忙提亲。在这个过程中,你所有的想法都直接与媒婆沟通,由媒婆将你的意思转达给小花。在 Linux 世界里,我们常用的 bash,就好比这位姓王的媒婆。

权限管理的基石:用户与用户组

Linux用户的分类与创建

在 Linux 系统中,存在两种类型的用户:超级用户(又称超级管理员,即 root)和普通用户。

超级用户拥有至高权限,能够在 Linux 系统中毫无限制地执行任何操作。

普通用户的操作权限则较为有限。

Tip: 超级用户的命令提示符是“#”,普通用户的命令提示符是“$”

命令:su [用户名]

功能:切换用户。

例如,要从root 用户切换到普通用户user,则使用 su user。 要从普通用户user切换到root用户则使用 su root(root可以省略),此时系统会提示输入root用户的口令(密码):

su可以切换到超级用户,su -也可以切换到超级用户,它们之间的区别是:

su 仅仅只是切换用户,并不会改变当前工作目录,而su -会切换用户并重新登入shell(会改变当前的工作目录)

命令:sudo

sudo是用来进行指令的短暂提权的!(第一次提权需要输入自己的密码)

比如:安装软件,安装到系统中,需要管理员root权限。其实只安装了一份,允许大家同时使用!

不过,我们新安装的Linux机器使用普通管理员的身份直接使用sudo进行提权一般都会报错 !   

Linux中有一个类似于白名单(被信任的人)的东西,只有出现在白名单的用户才能使用sudo进行提权!不然人人都会是root!

只有管理员root将指定用户添加到白名单后,该用户才能进行sudo提权:

  

权限的本质:理解rwx的含义

权限,究其本质,是对用户行为的一种界定,明确规定了用户 “能做什么” 以及 “不能做什么”。​

权限存在的核心意义在于管控用户行为,以此避免错误操作的发生。从根本上讲,权限首先针对的是不同角色的用户进行限制。同时,权限对操作目标也有着相应的属性要求,即只有当目标具备特定属性时,对应角色的用户才被允许进行操作。简而言之,权限可理解为 “角色” 与 “目标属性” 的结合体,即 权限 = 角色 + 目标属性 。

 文件权限的底层逻辑(读、写、执行)

Linux中包含三种角色:拥有者,所属组,other。 rw对应的权限是读写,x对应的权限是可执行!

怎么不见other呢?other就是除拥有者,所属组之外的角色。

为什么需要所属组呢?更精细化的身份角色是为了更精细化的权限管理。

因此我们可以这样描述上面的文件权限信息:

该文件的拥有者是root,有读写和执行的权限。所属组是root,有读和执行的权限,但没有写的权限。other有读和执行的权限,但没有写的权限。

目录权限的特殊性(r/w/x对目录的意义)

如果我想要进入一个目录,我需要什么权限?下面来做一个实验。

通过以上实验,我们会发现,想要进入一个目录,我们必须具备对应的x权限!

对于一个目录,其里面的文件和目录就是它的内容,所以:

如果没有r权限,我们就没有办法查看目录里面的文件。

如果没有w权限,我们就没有办法在目录里面删除或新建文件。

所以,我们新建一个目录,系统默认其都会有rwx权限。

权限配置的核心命令

chmod:修改文件权限的两种方式(符号法、数字法)

符号法:

在 Linux 系统的权限管理体系中,有几个关键要点需要深入理解:

  1. 用户权限修改范围:在 Linux 环境下,用户通常仅能对自己拥有的文件进行权限更改操作。例如,普通用户 user 创建了一个名为 “report.txt” 的文件,user 可以依据自身需求,利用 chmod 命令来调整该文件的权限,如设置为仅自己可读写(chmod 600 report.txt)。但如果 user 试图修改其他用户所拥有文件的权限,系统将予以拒绝,这是保障文件归属与权限管理秩序的重要机制。
  1. 权限不足导致访问受限:当用户尝试对文件或目录执行某项操作,却不具备对应的权限时,系统会明确拒绝此次访问。比如,user 对 “shared_folder” 目录仅有读权限,当 user 试图在该目录下创建新文件时,系统会提示权限不足的错误信息,阻止操作进行,以此确保数据的安全性与完整性,避免未经授权的修改。
  1. 权限判定顺序:在确定文件或目录的权限信息时,系统会按照特定顺序识别用户身份。首先判断用户是否为文件的拥有者;若不是,则接着判断用户是否属于文件的所属组;若都不匹配,那么用户将被认定为 “other”。在整个操作过程中,用户角色一旦确定,后续权限判定便依据该角色对应的权限设置进行。例如,对于文件 “project.doc”,拥有者 root 具有读写执行权限,所属组 “dev_team” 仅有读和执行权限,“other” 仅有读权限。当用户 “alice” 尝试访问该文件时,系统先判断 alice 并非拥有者 root,再查看 alice 是否属于 “dev_team” 组,若不属于,就将 alice 归入 “other” 类别,并按照 “other” 的权限来决定 alice 对 “project.doc” 的操作权限。
  1. root 权限的特殊性:root 作为 Linux 系统中的超级用户,拥有至高无上的权限,几乎不受常规权限设置的约束。这意味着 root 能够对系统内的任何文件、目录执行任意操作,包括修改权限、读取和写入受严格权限保护的数据等。例如,即使某个文件被设置为除拥有者外其他用户均无任何权限,root 依然可以直接访问和修改该文件,这种特殊权限赋予了 root 对系统进行全面管理与维护的能力。
  1. 可执行权限与实际执行:需要注意的是,一个文件被赋予可执行权限,并不意味着该文件一定能够被成功执行。可执行权限仅仅是系统允许用户尝试执行该文件的前提条件。例如,一个 Python 脚本文件 “script.py” 被赋予了可执行权限(chmod +x script.py),但如果系统中未安装 Python 解释器,或者脚本文件本身存在语法错误,当用户尝试执行该脚本时,依然会报错,无法正常运行。也就是说,除了可执行权限外,文件的执行还依赖于系统环境、文件本身的正确性等多种因素。

数字法:

我们会发现在9个权限位中,任何一个权限位都是两态的(即可或不可)。那这就可以用二进制的01序列来表示。如:

chownchgrp:修改文件归属角色

如果我们是普通用户,系统默认不允许我们把文件给别人!

我们可以提权!

如果我们想要修改所属组,使用chgrp即可 ,我们也可以使用chown来同时修改拥有者和所属组:

umask:缺省权限的计算与配置

对于普通文件来讲,它的起始权限是666实际是(664)。(默认不带可执行)

对于目录来讲,它的起始权限是777实际是(775)。(默认携带x)

为什么默认权限是我们看到的样子呢?

因为系统默认会存在一个叫权限掩码的概念!

最终权限= 起始权限&(~umask)

umask的目的是希望凡是在umask中出现的权限都不会在最终权限中出现。

为什么要有umask呢?

默认权限由os自主决定,无法在创建前进行修改 ——系统可配置,可以灵活满足需求的一种表现。

在特殊情况下,配置umask,可以控制文件的默认权限,让我们的代码是可控的! 

umask也是可配置的:

权限的进阶控制:特殊权限位

粘滞位(Sticky Bit):共享目录的安全卫士

一个文件是否可以被删除,与文件本身无关!与文件所处的目录w权限有关!举个栗子:

上面user2目录的拥有者和所属组都是user2,也就是说user2的目录竟然出现在用户user1里面。并且user1对其没有rwx的所有权限,但是我可以把这个文件删除!

究其原因,也就是在我的目录里面的所有文件我都有删除和新建的权限(即使这个文件我不能读,不能写),因为我对于这个目录有w权限!

下面抛出一个问题:如果两个用户要进行文件级别的写作呢?

比如user1负责进行数据的统计,而user2负责拿到user1的数据统计结果进行数据分析。

通过上面的实验,我们可以知道这个协作的文件不能放在任何一个私人账号。因为多用户之间有隔离,通常情况下,我连你的家目录都进入不了,更不用谈访问你的文件。但是我其实可以通过root或者sudo提权进入你的家目录,但我们通常不考虑这种情况。

所以我们就可以在共享类文件当中进行协作,所有人都可以在这个目录当中新建自己的文件,对不同的角色开放不同的权限!Linux中就有一个自带的这种临时共享文件tmp!

但这势必也会引起一个巨大的问题,因为这个共享目录对所有人的权限都是rwx,那也就意味着所有人都可以随便删除别人的文件(因为上面也实验过,删除一个文件与文件本身无关,与文件所处目录的w权限有关

此时,我们的需求之间就有了矛盾:我们即想要共享文件,又想要自己新建的文件不被别人删除。

而所有技术的出现都是建立在需求之上的!

为了解决这个不科学的问题,Linux引入了粘滞位的概念:

当一个目录被设置为"粘滞位"(用chmod +t),则该目录下的文件只能由

一、超级管理员删除

二、该目录的所有者删除

三、该文件的所有者删除

Linux默认自带的共享文件就可以完美解决以上的问题,所以我们一般不需要自己建立共享目录。

多用户环境下的权限隔离策略

通过上面用户目录的权限,我们可以得出结论:任何一个用户都无法进入其他用户的家目录。从而实现了多用户之间的隔离

 用户间的资源隔离原理

1. 权限管理机制

  • 文件系统权限:Linux 通过精细的文件和目录权限设置来隔离用户资源。每个文件和目录都有对应的所有者(owner)、所属组(group)以及其他用户(other)的权限标识。权限分为读(r)、写(w)和执行(x)三种。例如,普通用户创建的文件默认只有自己拥有读写权限,所属组和其他用户通常没有任何权限,这就从文件访问层面实现了用户资源的初步隔离。这种基于身份的权限控制,确保了用户只能在授权范围内访问和操作特定文件,防止了用户间的非法访问和数据篡改。
  • 访问控制列表(ACL):除了传统的所有者、所属组和其他用户的权限设置,Linux 还支持 ACL。ACL 允许管理员为特定用户或用户组设置更细致的文件访问权限。例如,可以针对某个文件为特定用户授予除所有者和所属组之外的额外读写权限,进一步细化了资源隔离策略,满足了复杂的共享和安全需求。

2. 用户命名空间(User Namespaces)

  • 隔离用户 ID 和组 ID:用户命名空间为每个进程提供了独立的用户 ID 和组 ID 映射视图。这意味着在不同的用户命名空间中,相同的用户 ID 或组 ID 可以对应不同的实际用户或组。例如,一个进程在其所属的用户命名空间中可能被视为 root 用户,但在系统全局命名空间中可能只是一个普通用户。通过这种方式,不同用户命名空间内的进程无法直接访问其他命名空间的资源,实现了用户间资源的强隔离,有效防止了进程间的越权访问和资源干扰。
  • 资源限制与隔离:结合 cgroups(控制组)技术,用户命名空间可以对不同用户或用户组的进程进行资源限制,如 CPU 使用率、内存使用量、磁盘 I/O 等。例如,可以为某个用户命名空间内的进程设置内存使用上限,防止该用户的进程过度占用系统资源,影响其他用户的正常使用,从而在资源分配层面实现了用户间的有效隔离。

3. 进程隔离

  • 独立的进程地址空间:每个用户的进程在 Linux 系统中都拥有独立的虚拟地址空间。这意味着不同用户的进程无法直接访问彼此的内存空间,防止了一个进程通过非法内存访问获取或修改其他用户进程的数据。例如,用户 A 的进程在其专属的地址空间中运行,即使出现内存越界等错误,也不会影响到用户 B 的进程运行,保障了用户进程间的隔离性和系统的稳定性。
  • 进程权限与能力(Capabilities):进程在运行时,其权限和能力由所属用户决定。Linux 将传统的 root 权限进行了细分,划分为多个具体的能力,如 CAP_NET_ADMIN 用于管理网络接口、CAP_SYS_MODULE 用于加载和卸载内核模块等。普通用户进程默认只拥有有限的能力,而 root 用户进程拥有全部能力。通过这种方式,限制了普通用户进程对系统关键资源和操作的访问,确保了系统资源在不同用户进程间的安全隔离。