Linux中的权限管理是如何实现的?
在Linux系统中,权限管理是通过一组复杂的机制来实现的,这些机制确保系统资源(如文件、目录、设备等)能够被正确地访问和控制。以下是Linux权限管理的一些核心概念和实现方式:
Linux 的权限管理是一个核心安全机制,主要通过以下几个方面协同实现:
1. 文件系统权限 (POSIX/DAC - Discretionary Access Control)
* **基础三元组:** 每个文件/目录都有三组权限:
* **属主权限 (User/Owner):** 文件所有者的权限。
* **属组权限 (Group):** 文件所属用户组的权限。
* **其他用户权限 (Others):** 既不是所有者也不在所属组中的其他用户的权限。
* **权限类型 (rwx):**
* **r (Read):** 读取文件内容 / 列出目录内容。
* **w (Write):** 修改文件内容 / 在目录中创建、删除、重命名文件。
* **x (Execute):** 将文件作为程序执行 / 进入目录 (使其成为当前工作目录或访问其内容)。
* **实现方式:**
* 权限信息存储在文件的 **inode** 数据结构中(`st_mode` 字段)。
* 使用 `ls -l` 命令查看:`-rwxr-xr-- 1 user group size date filename`
* 第一个字符 `-` 表示普通文件 (`d` 表示目录)。
* 接下来的 9 个字符:前 3 位 (rwx) 是属主权限,中间 3 位 (r-x) 是属组权限,后 3 位 (r--) 是其他用户权限。
* 命令:`chmod` (修改权限), `chown` (修改属主), `chgrp` (修改属组)。
2. **用户和用户组 (Users and Groups)**
* **用户 (Users):** 系统上的每个账户对应一个唯一的用户标识符 (**UID**)。超级管理员用户是 `root` (UID 0),拥有系统最高权限。
* **用户组 (Groups):** 用户可以被组织到组中,每个组有一个唯一的组标识符 (**GID**)。一个用户可以属于多个组。
* **主组 (Primary Group):** 用户创建文件时,该文件默认属于用户的主组。
* **附加组 (Supplementary Groups):** 用户所属的其他组,用于访问被这些组控制的资源。
* **实现方式:**
* 用户信息存储在 `/etc/passwd` (传统) 和 `/etc/shadow` (加密密码)。
* 组信息存储在 `/etc/group` (传统) 和 `/etc/gshadow` (组密码)。
* 命令:`useradd`, `usermod`, `userdel`, `groupadd`, `groupmod`, `groupdel`, `passwd`, `id`, `groups`, `newgrp`。
3. **进程凭证 (Process Credentials)**
* 当用户登录或执行程序时,会启动一个进程。每个进程都携带一组凭证,决定了它能访问哪些资源:
* **真实用户ID (Real UID - RUID):** 启动该进程的用户的 UID。
* **有效用户ID (Effective UID - EUID):** 决定进程访问文件/资源时权限的 UID。通常等于 RUID,除非程序设置了 `setuid` 位。
* **保存的设置用户ID (Saved set-user-ID - SUID):** 允许程序在 `setuid` 程序执行期间临时放弃特权 (`seteuid(getuid())`),稍后通过 `seteuid(geteuid())` 或 `seteuid(saved_uid)` 恢复特权。
* **真实组ID (Real GID - RGID):** 启动进程的用户的主组 GID。
* **有效组ID (Effective GID - EGID):** 决定进程访问文件/资源时权限的 GID。通常等于 RGID,除非程序设置了 `setgid` 位。
* **保存的设置组ID (Saved set-group-ID - SGID):** 类似于 SUID,用于组权限。
* **附加组ID列表 (Supplementary group IDs):** 进程所属的所有附加组的 GID 列表。
* **权限检查过程:** 当进程尝试访问一个文件时,内核会依次比较:
1. 进程的 EUID 是否等于文件的 UID?如果是,应用文件的 **属主权限**。
2. 如果 1 不成立,进程的 EGID 或任何一个附加组 GID 是否等于文件的 GID?如果是,应用文件的 **属组权限**。
3. 如果 1 和 2 都不成立,应用文件的 **其他用户权限**。
* **`setuid` 和 `setgid` 位:**
* **Setuid (s):** 设置在可执行文件上。当用户执行此程序时,进程的 **EUID** 会被临时设置为 **文件属主的 UID** (而不是执行用户的 UID)。这允许普通用户临时获得文件属主(通常是 root)的权限来执行特定任务(如 `passwd` 修改 `/etc/shadow`)。
* **Setgid (s):**
* 设置在可执行文件上:进程的 **EGID** 会被临时设置为 **文件属组的 GID**。用于共享组资源。
* 设置在目录上:在该目录下**新创建**的文件/目录,其**属组**会自动继承该目录的属组(而不是创建者的主组)。这对于共享目录(如 `/var/www` 或团队项目目录)非常有用。
* **粘滞位 (Sticky Bit - t):** 设置在目录上。只有文件的**属主**、**目录的属主** 或 **root** 才能删除或重命名该目录中的文件(即使其他用户对该目录有写权限)。常用于临时目录(如 `/tmp`),防止用户随意删除他人文件。
4. **访问控制列表 (ACLs - Access Control Lists)**
* **作用:** 扩展了基础的三元组 (u/g/o) 权限模型,允许为单个文件/目录设置更细粒度的权限,可以针对**特定用户**或**特定组**设置独立的 rwx 权限。
* **实现方式:**
* 文件系统需要支持 ACL (如 ext4, xfs, btrfs 默认支持)。
* 权限信息存储在文件的扩展属性中。
* 命令:`getfacl` (查看 ACL), `setfacl` (设置 ACL)。例如:`setfacl -m u:alice:rwx file.txt` 给用户 alice 赋予 file.txt 的 rwx 权限。
5. **能力机制 (Capabilities - Linux Capabilities)**
* **问题:** `setuid root` 程序拥有 root 的**全部**权限,一旦被利用,危害极大。
* **解决方案:** 将 root 的超级权限拆分成一系列独立的、细粒度的 **能力 (Capabilities)**。
* **作用:** 允许进程只拥有执行其特定任务所需的最小权限子集,而不是完整的 root 权限。例如:
* `CAP_NET_ADMIN`:执行网络管理操作。
* `CAP_SYS_ADMIN`:执行系统管理操作(范围广,需谨慎)。
* `CAP_DAC_OVERRIDE`:绕过文件读、写、执行权限检查。
* `CAP_KILL`:允许发送信号给不属于自己的进程。
* **实现方式:**
* 能力作为进程凭证的一部分。
* 可执行文件可以关联能力集 (`setcap` 命令)。
* 系统调用 `capset`/`capget` 用于管理进程能力。
* 命令:`getcap` (查看文件能力), `setcap` (设置文件能力)。
6. **强制访问控制 (MAC - Mandatory Access Control)**
* **作用:** 在 DAC (用户/组/权限) 基础上,增加一层由系统安全策略强制实施的、更严格的访问控制模型。策略由管理员定义,用户和程序无法覆盖。目标是限制进程和用户的操作范围,即使它们被攻破也能减少损害。
* **常见实现:**
* **SELinux (Security-Enhanced Linux):** Red Hat/Fedora/CentOS 等发行版默认启用。基于“主体(进程)-对象(文件/端口等)-操作”和策略规则进行决策。
* **AppArmor:** Ubuntu/Debian/openSUSE 等发行版常用。基于程序路径名定义访问控制配置文件。
* **工作方式:** 在 DAC 权限检查**通过后**,MAC 层(如 SELinux 或 AppArmor)会再次根据其安全策略进行访问裁决。只有两层都允许,访问才会被授权。
**总结流程 (简化):**
1. 用户尝试执行一个操作(如打开文件 `/etc/shadow`)。
2. 系统调用(如 `open()`)被触发。
3. **内核**介入进行权限检查。
4. 检查进程的凭证 (EUID, EGID, 附加组)。
5. 检查目标文件的权限位 (rwx for u/g/o)。
6. 如果文件系统支持并配置了 ACL,检查 ACL 规则。
7. 如果启用了 MAC (如 SELinux/AppArmor),应用 MAC 策略检查。
8. 如果**所有**检查都通过 (`DAC + (可选 ACL) + (可选 MAC)`),操作被允许执行。
9. 如果**任何一层**检查失败,操作被拒绝,并返回权限错误 (如 `EACCES`)。
这种分层、细粒度的权限管理机制是 Linux 系统安全、稳定和多用户环境支持的基石。理解这些机制对于系统管理员和安全人员至关重要。
END