访问控制与身份认证
基于通用操作系统概念 · 核于 2026-08
速查
- 访问控制三要素:主体(Subject,发起访问的用户/进程)+ 客体(Object,被访问的资源:文件/设备/内存段)+ 访问权限(Right,读/写/执行)。访问控制就是回答"主体 S 能否以权限 R 访问客体 O"。
- 访问控制矩阵(Access Matrix):行=主体,列=客体,单元格=权限。理论模型清晰但稀疏(大部分单元格空),实际不直接存,而是按行或列拆开存储。
- ACL(访问控制表,按列存):每个客体附带一张"哪些主体能对它做什么"的表。代表:Unix 文件权限、Windows NTFS。便于查"谁能访问这个文件",不便于查"某用户能访问哪些文件"。
- capability(能力,按行存):每个主体持有一组"能对哪些客体做什么"的令牌(不可伪造的句柄)。代表:Linux 的文件描述符、seccomp、Capsicum。便于查"某用户能访问哪些文件",便于按主体授权传递,但不便于查"谁能访问这个文件"。
- ACL vs capability 核心:ACL 是"按客体的名单",capability 是"按主体的令牌"——前者类似"门上贴一张谁能进的告示",后者类似"每人手里攥一串钥匙"。
- Unix 权限模型:
rwxrwxrwx三组(属主/属组/其他)+chmod/chown;root 绕过权限检查;sudo临时提权;setuid让普通用户以文件属主身份执行(如passwd以 root 改 /etc/shadow)。 - 身份认证三因素:①你知道什么(口令/PIN);②你拥有什么(令牌/手机/U盾);③你是什么(指纹/人脸等生物特征)。多因素认证(MFA)= 至少两种结合,大幅提升安全性。
- DAC vs MAC:**自主访问控制(DAC)**由客体属主决定谁能访问(Unix/Windows 默认);**强制访问控制(MAC)**由系统策略统一强制(SELinux/AppArmor,主体与客体都打安全标签)。
- 口令存储:绝不存明文,存加盐哈希(salt + bcrypt/scrypt/Argon2);早期 Unix 用 DES,/etc/shadow 现在只 root 可读。
- 易错:ACL 与 capability 不是"谁更先进",而是"不同查询方向各有优势",工程上常混用(Unix 文件描述符是 capability,文件权限位是 ACL)。
- 进阶:理解 ACL/capability 后,下一步看缓冲区溢出与防御(即便有权限控制,内存攻击也能绕过)。
一、访问控制矩阵:理论模型
访问控制的最一般化模型是访问控制矩阵(Access Matrix):行是主体(用户/进程),列是客体(文件/设备),单元格写权限:
文件A 文件B 打印机
用户Alice 读写 读 打印
用户Bob 读 -- --
用户Carol -- 读写 --- 问题:矩阵极其稀疏——一个系统有上万用户、上百万文件,但每个用户实际能访问的文件寥寥。存整个矩阵既浪费又低效。
- 解法:按行或按列拆开存储,得到两种实现模型——**capability(按行)**与 ACL(按列)。
二、ACL:访问控制表(按客体)
ACL(Access Control List,访问控制表):每个客体附带一张表,列出"哪些主体能对它做什么"。
文件 /etc/passwd 的 ACL:
Alice: 读
Bob: 读
root: 读写- 优点:①查看"谁能访问这个文件"很容易(直接读 ACL);②撤销某主体对某客体的权限很简单(从 ACL 删一行);③客体属主可自主管理(DAC 风格)。
- 缺点:①查看"某用户能访问哪些文件"很难(要遍历所有文件的 ACL);②每访问一个客体都要查整张 ACL,客体被大量主体访问时 ACL 很长、查找慢;③ACL 可能被恶意修改(除非内核保护)。
- 代表:Unix 文件权限位(
rwxrwxrwx是简化的 ACL)、Windows NTFS ACL、POSIX ACL(getfacl/setfacl)。
三、capability:能力(按主体)
capability(能力):每个主体持有一组不可伪造的令牌(句柄),每个令牌代表"对某客体有某种权限"。capability 本质是"带权限的指针"——持有它就拥有访问权。
c
// Linux 的文件描述符就是 capability
int fd = open("/etc/passwd", O_RDONLY); // 内核颁发一个"只读该文件"的能力
read(fd, buf, 1024); // 出示 fd 这个令牌即可访问
// fd 是个小整数,用户态无法伪造(必须通过 open 由内核颁发)- 不可伪造:capability 由内核颁发,用户态拿到的只是句柄(如 fd),无法凭空造出一个有效的 capability。这是它与 ACL(一张字符串名单)的根本区别。
- 优点:①查看"某用户能访问哪些文件"很容易(列出它持有的 capability);②权限可传递(父进程把 fd 传给子进程,即授予它访问权);③按主体授权天然符合"最小权限";④查找快(出示令牌即可,不用扫名单)。
- 缺点:①查看"谁能访问这个文件"很难(要遍历所有主体的 capability);②撤销权限难(内核要回收已散布在各进程的 capability,而 ACL 只需删一行)。
- 代表:Linux 的文件描述符(fd)、seccomp(限制进程能调用哪些 syscall)、Capsicum(FreeBSD 的细粒度 capability)、Chrome 的站点隔离。
四、ACL vs capability 对比
| 维度 | ACL(访问控制表) | capability(能力) |
|---|---|---|
| 存储方式 | 按客体(列)存 | 按主体(行)存 |
| 类比 | 门上贴"谁能进"的告示 | 每人手里攥一串钥匙 |
| 易查 | 谁能访问这个文件 | 某用户能访问哪些文件 |
| 撤销权限 | 易(从 ACL 删一行) | 难(要回收散布的令牌) |
| 权限传递 | 难(属主改 ACL) | 易(传递 fd/令牌) |
| 伪造风险 | ACL 可能被篡改 | 令牌不可伪造(内核颁发) |
| 天然契合 | DAC(属主自主管理) | 最小权限(按需授予) |
| 代表 | Unix 权限位、NTFS | Linux fd、seccomp、Capsicum |
- 不是二选一:真实系统常混用。Linux 文件用 ACL(权限位 + POSIX ACL),而进程持有的文件描述符是 capability——两者协同:ACL 决定
open时能否颁发 capability,capability 决定持有后能否继续访问。
五、Unix 权限模型:rwx、root 与 sudo
Unix/Linux 用一套简洁的 ACL 模型管理文件:
$ ls -l /etc/passwd
-rw-r--r-- 1 root root ... /etc/passwd
└┬┘└┬┘└┬┘
属主 属组 其他
rwx rwx rwx- 三组权限:
rwx分别对应属主(owner)、属组(group)、其他(other)。r=读、w=写、x=执行(目录的 x = 可进入)。 - 八进制表示:
rwx= 7,rw-= 6,r--= 4。chmod 755 file=rwxr-xr-x。 chmod改权限,chown改属主/属组。- root 绕过权限检查:UID=0 的 root 进程不受 rwx 限制,能读写任何文件——这是 Unix 安全的"上帝模式",也是最小权限原则要避免长期以 root 运行的原因。
sudo(临时提权):普通用户在/etc/sudoers授权后,可用sudo临时以 root 身份执行单条命令——比直接登录 root 更安全(有日志、有时限、可限定命令)。setuid(设置用户 ID):可执行文件带setuid位时,无论谁执行,进程都以文件属主身份运行。典型:passwd命令属主是 root 且带 setuid,普通用户执行它时进程有 root 权限去改/etc/shadow(只能改自己的密码条目)。setuid 是最小权限的精妙运用,但也是著名攻击面(setuid 程序的漏洞 = 提权漏洞)。
六、身份认证:证明"你是谁"
访问控制的前提是先确认主体身份——这就是身份认证(Authentication)。三大因素:
| 因素 | 类别 | 举例 | 风险 |
|---|---|---|---|
| 你知道什么 | 知识 | 口令、PIN、密保问题 | 可被猜解/钓鱼/泄露 |
| 你拥有什么 | 持有 | U 盾、手机短信验证码、硬件令牌 | 可丢失/被盗/被复制 |
| 你是什么 | 生物 | 指纹、人脸、虹膜、声纹 | 难更改(一旦泄露永久失守) |
- 单因素(只用口令)脆弱:弱口令可暴力破解,相同口令跨站泄露,钓鱼可骗取。
- 多因素认证(MFA / 2FA):至少结合两种不同类别的因素(如口令 + 手机验证码),攻击者即使拿到口令也缺第二个因素,安全性大幅提升。
- 口令存储铁律:绝不存明文,存加盐哈希——用慢哈希(bcrypt/scrypt/Argon2)+ 随机盐,让暴力破解成本高到不可行。早期 Unix 用 DES(已淘汰),现代用 SHA-512 + 多轮或 bcrypt。
/etc/shadow:口令哈希单独存在 shadow 文件,只有 root 可读——把口令哈希与公开的/etc/passwd分离,避免普通用户拿到哈希离线爆破。
下一步
掌握了访问控制与身份认证后,下一步看缓冲区溢出与防御——即便权限控制做对,内存层面的攻击仍能绕过它们,于是有了 ASLR/DEP/Canary/CFI 等纵深防御机制。