bigywater.tech
ZooKeeper · 73

ACL 继承与递归授权

给一个目录设了 ACL,它下面的东西就安全了吗?不一定。这篇验证 ZooKeeper 的 ACL 完全不继承,以及要保护整棵子树的代价。

不继承
受保护的父节点下新建的子节点默认是 world:anyone
完整路径能绕过
匿名读不了父节点的子节点列表,但知道路径就能读子节点
3906 个节点 / 13.2 s
递归给子树设置 ACL 的节点数与用时(逐个同步请求)

ACL 不继承

实测 · 本机执行输出
  /p/c 的 ACL: [('world', 'anyone', 31)]
  匿名按完整路径读 /p/c → 允许 (父节点受保护,但子节点自己的 ACL 是 world)
  匿名列出 /p 的子节点 → 拒绝(NoAuth)

谁的 ACL 管什么

实测 · 本机执行输出
  匿名在 /p 下创建子节点 → 拒绝(NoAuth)
  匿名删除 /p/c(子节点是 world,但父节点 /p 只允许 admin)→ 拒绝(NoAuth)
  匿名修改 /p/c 的数据(子节点 world:cdrwa)→ 允许

递归授权的代价

实测 · 本机执行输出
  建树 3906 个节点用时 12.8 s;全是 world,匿名读两个深层节点:2/2 成功
  递归 set_acls 3906 个节点用时 13.2 s(逐个同步请求);之后匿名读深层节点: 拒绝(NoAuth)

用异步请求或 multi 可以更快,本文只测了逐个同步的写法。

新建节点

实测 · 本机执行输出
  /tree/n0/new 的 ACL: [('world', 'anyone')]
  创建时就带上 ACL(create 的 acl 参数)或者在创建后立刻 set_acls,否则会有一小段「裸奔」的时间窗。

分步演示

ACL 继承
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。单机;kazoo 同步请求;树是 5 层 × 5 个子节点
    • 没有验证:用 multi / 异步加速递归授权、客户端库的「创建节点时继承父 ACL」选项(有的库有)、Curator 的 ACLProvider
    京ICP备2026067502号-1京公网安备11010502063487号