自主访问控制(DAC):概念、优缺点与典型实现
讲权限模型,DAC 是个绕不开的起点。很多人把它叫作「随意的访问控制」,其实说白了——资源的所有者说了算。你创建了一个文件,你就可以决定谁能读、谁能写、谁能删。这种直觉式的模型,在早期 Unix 系统里就深深扎下了根。
我记得刚入行时接手过一个内部 OA 系统的权限模块,项目负责人说:「你就照着 Linux 文件权限做就行了」。那时候我还觉得挺简单的,结果后来……踩了不少坑。今天咱们就把 DAC 拆开揉碎了讲,你会看到它到底好在哪、坑在哪,以及企业系统里为什么经常拿它做底层。
什么才是真正的 DAC?
自主访问控制的核心只有一句话:拥有资源的用户,有权把该资源的访问权限授予给其他用户。这个「自主」两个字很关键——它不是系统管理员定的,也不是角色约束死的,而是资源持有者个人说了算。
我习惯把它类比成房子的钥匙。你买了房子,你可以给家人配钥匙,也可以给朋友一把临时钥匙,甚至哪天想换锁了就把之前的授权全部作废。这就是 DAC 的直觉感。
主体(用户/进程)→ 客体(文件/数据/对象)→ 权限(读/写/执行/删除等)
权限传递路径由资源所有者控制。
但这种自由带来一个问题:权限容易扩散。你想想看,A 给了 B 权限,B 又给了 C,到最后连 A 自己都不清楚有多少人能访问那个文件了。我曾经在审计报表里发现一个共享目录,权限链长达 15 层,而且中间有 3 个人已经离职……这就是典型的 DAC 副作用。
DAC 的优缺点:审计视角下的权衡
| 维度 | 优点 | 缺点(审计关注点) |
|---|---|---|
| 灵活性 | 资源所有者快速授权,无需管理员介入 | 权限容易过度扩散,难以集中管控 |
| 实现成本 | 模型简单,系统实现和运维都很直接 | 缺少统一策略,审计日志难以聚合分析 |
| 用户体验 | 符合「我的东西我做主」的直觉 | 非技术用户容易误操作,造成数据泄露 |
| 可审计性 | 每个授权动作可记录在案 | 缺少「撤销传播」机制,历史授权难以回溯清理 |
| 扩展性 | 适用于小规模、低安全级别的场景 | 大型组织里权限碎片化严重,合规风险高 |
从审计角度看,最头疼的是「权限泄漏」和「权限蔓延」。我曾经帮一家金融公司做权限健康度检查,发现他们一个财务系统的共享报告文件夹用了 DAC——销售助理不小心把写权限给了外部顾问,那个顾问离职后账号没禁用……好在及时发现,不然季度财报数据就流出去了。
典型实现:从 Unix 到 Windows 再到关系数据库
讲完概念,咱们看看现实中 DAC 是怎么落地的。我整理了三种最常见的实现,也是我在项目中遇到的频率最高的场景。
1. Unix/Linux 传统文件权限
最基础的 DAC,也是很多人接触的第一个权限模型。三位权限位(Owner – Group – Other)加上 setuid/setgid/sticky bit。
举个实际例子:
# 查看文件权限
ls -l confidential_report.pdf
-rw-r----- 1 alice finance 20480 Feb 28 10:00 confidential_report.pdf
# 所有者 alice 可以读/写,组 finance 可以读,其他人无权限
# alice 可以随时调整:
chmod g+w confidential_report.pdf # 给同组的人加写权限
chmod o+r confidential_report.pdf # 给所有用户加读权限(危险操作!)
2. Windows NTFS 访问控制列表(ACL)
Windows 的 DAC 比 Unix 要细得多。它把权限细分成了「读取」「写入」「修改」「完全控制」等多个条目,每条 ACL 都由一个安全标识符(SID)和一个访问掩码组成。每个文件和文件夹都有一张 ACL 表,可以精确控制到单个用户或组。
我记得做 Windows 服务器审计时,发现一个共享文件夹的 ACL 里竟然同时包含「Everyone 完全控制」和「Domain Admins 拒绝写入」两条冲突条目——系统按优先级取拒绝,但审计人员一看就知道有问题。(为什么会这样?多半是管理员图省事直接给了 Everyone 完全控制,后来发现问题再补了个拒绝……这种方式很不规范。)
3. 关系型数据库中的 DAC
像 MySQL、PostgreSQL、Oracle 这些数据库,也用的是 DAC 模型——表的创建者(owner)默认拥有该表的所有权限,然后可以 GRANT 给其他用户。
-- PostgreSQL 示例
CREATE TABLE employee_salary (
emp_id INT PRIMARY KEY,
salary NUMERIC
);
-- 创建者(postgres)拥有所有权限
-- 然后把查询权限给审计员 bob
GRANT SELECT ON employee_salary TO bob;
-- 还可以带 WITH GRANT OPTION,让 bob 再转发给其他人
GRANT SELECT ON employee_salary TO alice WITH GRANT OPTION;
这里有个关键点——WITH GRANT OPTION 就是 DAC 里「权限可传递」的开关。你如果不想让权限扩散,记得不要用这个选项。我见过一个事故:DBA 给了一个初级运维 WITH GRANT OPTION,结果那个运维顺手就把表的 DELETE 权限给了整个项目组……
DAC 的典型审计关注点
- 权限蔓延检测:定期扫描哪些客体(文件/表/共享)的 ACL 包含超过 3 层以上的传递授权
- 孤儿权限清理:资源所有者离职或账号禁用后,其拥有的客体是否仍被其他用户访问?DAC 不会自动回收
- 默认权限检查:新创建的文件/目录是否继承了过于宽松的默认 ACL?比如 umask 设置为 000
- 授权一致性:同一个客体上的多个 ACL 条目是否存在冲突(允许 vs 拒绝)
- 可追溯性:每次 GRANT/REVOKE 操作都要记录操作人、时间、客体和权限变化
「谁拥有,谁授权;权限链,莫拖延;历史记录全保留,定期回收不手软。」
一张图看懂 DAC 核心逻辑
下面这张 SVG 把 DAC 的核心关系和典型流程串起来了。画布上从左到右依次是:资源所有者 → 授权动作 → 资源客体 → 被授权用户 → 权限传递链。右下角补充了审计关注点。
DAC 在复杂系统里的常见变体
除了上面三种纯 DAC 实现,现代系统经常把 DAC 和别的模型混着用。我列几个遇到过的情况:
- DAC + MAC 双层过滤:比如 SELinux,先做强制访问控制(MAC)的检查,再做 DAC 检查。你可以理解为「先看国家安全局批不批准,再看你家主人同不同意」。
- 基于 DAC 的委托授权:把 WITH GRANT OPTION 封装成「角色转移」功能,常见于文档协作系统(如 Google Drive 的「拥有者转移」)。
- DAC 的影子权限:有些系统表面上用 RBAC(基于角色的访问控制),但底层文件系统仍然用 DAC。这时候就会出现「角色能看到这个文档,但系统底层 DAC 拒绝读取」的诡异 bug。我曾在文件预览服务里排查过类似问题——页面一直报 403,但角色权限查了 N 遍都没问题,最后发现是服务器上文件所属组错了。
DAC 的灵活性和简洁性让它成为权限模型的基石。但作为审计专家,你得始终记住它的软肋——没有中心管控,没有强制策略。下一段我们可以接着聊强制访问控制(MAC)怎么解决这些问题的,不过那得放到第 3 章了。