目录

  1. 什么是 ZooKeeper ACL
  2. ACL 的基本组成
  3. 权限类型
  4. 认证模式
  5. ACL 操作示例
  6. 参考资料

什么是 ZooKeeper ACL

ACL(访问控制列表)是 ZooKeeper 用于保护 ZNode 的机制,通过定义谁(认证身份)可以对节点执行哪些操作(权限)来实现访问控制。默认情况下,ZooKeeper 的节点是开放的(world:anyone),但可以通过 ACL 设置限制访问,适用于需要安全管理的分布式系统。


ACL 的基本组成

ZooKeeper 的 ACL 由三部分组成,格式为 [scheme:id:permissions]

  1. Scheme(认证模式)
  • 定义认证的方式,例如 worlddigestip
  1. ID(身份标识)
  • 与 Scheme 对应,表示具体的身份,例如用户名、IP 地址。
  1. Permissions(权限)
  • 指定允许的操作,例如读、写、创建等。

示例

  • world:anyone:cdrwa:所有人拥有所有权限。
  • digest:user1:password:cr:用户 user1(经过密码加密)拥有创建和读权限。
  • ip:192.168.1.101:r:IP 为 192.168.1.101 的客户端只有读权限。

权限类型

ZooKeeper 定义了五种基本权限,可以通过组合使用:

  1. READ (r)
  • 允许读取节点数据(get)和子节点列表(ls)。
  1. WRITE (w)
  • 允许修改节点数据(set)。
  1. CREATE (c)
  • 允许创建子节点。
  1. DELETE (d)
  • 允许删除节点。
  1. ADMIN (a)
  • 允许设置 ACL(setAcl)和管理权限。

权限表示

  • 用字母 cdrwa 表示,组合时按需拼接。
  • 例如:rw 表示读写权限,cdrwa 表示所有权限。

认证模式

ZooKeeper 支持多种认证模式(Scheme),用于识别客户端身份:

  1. world
  • ID:固定为 anyone
  • 含义:表示所有客户端,无需认证。
  • 示例world:anyone:cdrwa(默认开放权限)。
  1. auth
  • ID:当前会话中已认证的用户名。
  • 含义:基于会话的认证用户,不需显式指定 ID。
  • 示例auth::rw(当前认证用户有读写权限)。
  1. digest
  • IDusername:password 的 Base64 编码 SHA-1 哈希值。
  • 含义:基于用户名和密码的认证。
  • 示例digest:user1:BASE64(SHA1(password)):rw
  1. ip
  • ID:客户端的 IP 地址或 CIDR 格式。
  • 含义:基于 IP 的访问控制。
  • 示例ip:192.168.1.101:r
  1. sasl
  • ID:SASL 认证的用户名。
  • 含义:基于 Kerberos 或其他 SASL 机制。
  • 示例sasl:user@domain.com:rw

ACL 操作示例

以下通过 ZooKeeper 命令行客户端(zkCli.sh)和 Java API 展示 ACL 的使用。

命令行示例

  1. 启动客户端
   zkCli.sh -server localhost:2181
  1. 创建节点并设置 ACL(默认开放)
   create /openNode "open data"
   getAcl /openNode

输出:

   'world,'anyone
   : cdrwa
  1. 添加认证用户
   addauth digest user1:password123
  1. 创建受限节点
   create /secureNode "secure data" digest:user1:password123:rw
   getAcl /secureNode

输出:

   'digest,'user1:BASE64(SHA1(password123))
   : rw
  1. 测试权限
  • 未认证客户端尝试访问:
    bash get /secureNode
    输出:Authentication is not valid
  • 认证后访问:
    bash addauth digest user1:password123 get /secureNode
    输出:secure data
  1. 修改 ACL
   setAcl /secureNode digest:user1:password123:cdrwa
   getAcl /secureNode

Java API 示例

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import java.util.Collections;

public class ZooKeeperACL {
    private static final String CONNECT_STRING = "localhost:2181";
    private static final int SESSION_TIMEOUT = 30000;

    public static void main(String[] args) throws Exception {
        ZooKeeper zk = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, null);

        // 创建开放节点
        zk.create("/open", "open data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        // 创建受限节点(仅 IP 192.168.1.101 可读)
        ACL acl = new ACL(ZooDefs.Perms.READ, new Id("ip", "192.168.1.101"));
        zk.create("/ipNode", "ip data".getBytes(), Collections.singletonList(acl), CreateMode.PERSISTENT);

        // 添加认证并创建受限节点
        zk.addAuthInfo("digest", "user1:password123".getBytes());
        zk.create("/authNode", "auth data".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);

        // 读取数据
        System.out.println(new String(zk.getData("/authNode", false, null)));

        zk.close();
    }
}
  • 解释
  • OPEN_ACL_UNSAFE:默认开放权限。
  • ACL 对象:自定义权限规则。
  • addAuthInfo:添加客户端认证。

参考资料


这是 ZooKeeper ACL 的完整解析,涵盖权限类型、认证模式和操作示例。如果您需要更复杂的 ACL 配置(如多用户权限组合),请告诉我!