bigywater.tech
ZooKeeper · 71

ACL 权限控制

ZooKeeper 的 ACL 默认是完全开放的。这篇从默认值开始,用 digest 保护一个节点,再把五种权限逐一拆开测:谁能读、谁能写、谁能创建 / 删除子节点、谁能改 ACL。

默认完全开放
不指定时是 world:anyone:cdrwa(perms=31)
5 种权限
CREATE / READ / WRITE / DELETE / ADMIN(cdrwa)
CREATE / DELETE 看父节点
它们控制的是「在这个节点下」创建 / 删除子节点

默认 ACL

实测 · 本机执行输出
  /open 的 ACL: [('world', 'anyone', 31)] (perms=31 = ALL)
  匿名连接:读 /open                                               → 成功:b'hello'
  匿名连接:写 /open                                               → 成功:ZnodeStat(czxid=3, mzxid=4, ctime=179082
  匿名连接:删 /open                                               → 成功

用 digest 保护一个节点

实测 · 本机执行输出
  /secret 的 ACL: [('digest', 'admin:B05meOaFZGavGA/rJPCQlodOTYU=', 31)]
  匿名:读 /secret                                               → NoAuthError
  匿名:写 /secret                                               → NoAuthError
  匿名:读 ACL /secret                                           → NoAuthError
  匿名:改 ACL /secret                                           → NoAuthError
  匿名:列子节点 /secret                                            → NoAuthError
  匿名:创建子节点 /secret                                           → NoAuthError
  匿名:删子节点 /secret                                            → NoAuthError
  已认证 admin:读 /secret                                        → 成功:b'top'
  已认证 admin:写 /secret                                        → 成功:ZnodeStat(czxid=6, mzxid=11, ctime=17908
  已认证 admin:读 ACL /secret                                    → 成功
  已认证 admin:改 ACL /secret                                    → 成功
  已认证 admin:列子节点 /secret                                     → 成功:[]
  已认证 admin:创建子节点 /secret                                    → 成功:/secret/c
  已认证 admin:删子节点 /secret                                     → 成功

五种权限

实测 · 本机执行输出
  reader   {'get': '允许', 'set': '拒绝(NoAuth)', 'create_child': '拒绝(NoAuth)', 'delete_child': '拒绝(NoAuth)', 'set_acl': '拒绝(NoAuth)'}
  writer   {'get': '允许', 'set': '允许', 'create_child': '拒绝(NoAuth)', 'delete_child': '拒绝(NoAuth)', 'set_acl': '拒绝(NoAuth)'}
  maker    {'get': '允许', 'set': '拒绝(NoAuth)', 'create_child': '允许', 'delete_child': '拒绝(NoAuth)', 'set_acl': '拒绝(NoAuth)'}
  deleter  {'get': '允许', 'set': '拒绝(NoAuth)', 'create_child': '拒绝(NoAuth)', 'delete_child': '允许', 'set_acl': '拒绝(NoAuth)'}

表里每一行都是一个只有那一种(加 READ)权限的用户做的真实尝试。

分步演示

ACL
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。单机;客户端 kazoo 的 add_auth / make_digest_acl;ACL 的 digest 口令是实验用的假口令
    • 没有验证:超级用户(zookeeper.DigestAuthenticationProvider.superDigest)绕过 ACL、skipACL、enforceQuota、ACL 对 multi 的影响
    京ICP备2026067502号-1京公网安备11010502063487号