自主访问控制(DAC):概念、优缺点与典型实现

讲权限模型,DAC 是个绕不开的起点。很多人把它叫作「随意的访问控制」,其实说白了——资源的所有者说了算。你创建了一个文件,你就可以决定谁能读、谁能写、谁能删。这种直觉式的模型,在早期 Unix 系统里就深深扎下了根。

我记得刚入行时接手过一个内部 OA 系统的权限模块,项目负责人说:「你就照着 Linux 文件权限做就行了」。那时候我还觉得挺简单的,结果后来……踩了不少坑。今天咱们就把 DAC 拆开揉碎了讲,你会看到它到底好在哪、坑在哪,以及企业系统里为什么经常拿它做底层。

什么才是真正的 DAC?

自主访问控制的核心只有一句话:拥有资源的用户,有权把该资源的访问权限授予给其他用户。这个「自主」两个字很关键——它不是系统管理员定的,也不是角色约束死的,而是资源持有者个人说了算。

我习惯把它类比成房子的钥匙。你买了房子,你可以给家人配钥匙,也可以给朋友一把临时钥匙,甚至哪天想换锁了就把之前的授权全部作废。这就是 DAC 的直觉感。

DAC 三要素:
主体(用户/进程)→ 客体(文件/数据/对象)→ 权限(读/写/执行/删除等)
权限传递路径由资源所有者控制。

但这种自由带来一个问题:权限容易扩散。你想想看,A 给了 B 权限,B 又给了 C,到最后连 A 自己都不清楚有多少人能访问那个文件了。我曾经在审计报表里发现一个共享目录,权限链长达 15 层,而且中间有 3 个人已经离职……这就是典型的 DAC 副作用。

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   # 给所有用户加读权限(危险操作!)
我的一点经验:很多开发同学误以为 chmod 777 很方便,但在生产环境里这就是等着被审计通报。我习惯强制团队用「最小权限」配置——先设置 750(所有者rwx,组r-x,其他人无),再单独用 ACL 扩展个别用户的权限。这样既保留了 DAC 的灵活,又控制了权限范围。

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) 核心逻辑框架 资源所有者 (如文件创建者) 授权操作 GRANT / chmod 资源客体 (文件/表/对象) 被授权用户 (拥有访问权限) 权限可传递 (WITH GRANT OPTION) 审计关注点 • 权限蔓延:传递链超过3层需预警 • 孤儿权限:所有者离职后资源访问未清理 • 默认宽松:umask 000 或 Everyone 完全控制 • ACL冲突:允许与拒绝条目同时存在 • 审计日志:授权、撤销、传递全量记录
看图解读:绿色节点表示资源客体,蓝色是所有者,红色是授权操作,青色是被授权用户。紫色节点和虚线箭头表示「权限可传递」这条关键路径。审计关注点集中在最下方的黄色说明框。你可以在实际审计中拿着这张图对照系统的权限模型——如果发现某个系统里所有者和授权操作混淆不清,或者没有记录传递关系,那基本就是 DAC 管理失控的前兆。

DAC 在复杂系统里的常见变体

除了上面三种纯 DAC 实现,现代系统经常把 DAC 和别的模型混着用。我列几个遇到过的情况:

  • DAC + MAC 双层过滤:比如 SELinux,先做强制访问控制(MAC)的检查,再做 DAC 检查。你可以理解为「先看国家安全局批不批准,再看你家主人同不同意」。
  • 基于 DAC 的委托授权:把 WITH GRANT OPTION 封装成「角色转移」功能,常见于文档协作系统(如 Google Drive 的「拥有者转移」)。
  • DAC 的影子权限:有些系统表面上用 RBAC(基于角色的访问控制),但底层文件系统仍然用 DAC。这时候就会出现「角色能看到这个文档,但系统底层 DAC 拒绝读取」的诡异 bug。我曾在文件预览服务里排查过类似问题——页面一直报 403,但角色权限查了 N 遍都没问题,最后发现是服务器上文件所属组错了。
再啰嗦一句:审计 DAC 时别只盯着应用层,一定要看底层文件系统或数据库的 ACL。我曾经锚定一个「越权漏洞」,业务层代码没查到任何问题,最后发现是 Docker 容器内的挂载目录给了 777 权限——容器里的应用能做任何事,直接绕开了业务层的控制。

DAC 的灵活性和简洁性让它成为权限模型的基石。但作为审计专家,你得始终记住它的软肋——没有中心管控,没有强制策略。下一段我们可以接着聊强制访问控制(MAC)怎么解决这些问题的,不过那得放到第 3 章了。