目录
什么是 ZooKeeper ACL
ACL(访问控制列表)是 ZooKeeper 用于保护 ZNode 的机制,通过定义谁(认证身份)可以对节点执行哪些操作(权限)来实现访问控制。默认情况下,ZooKeeper 的节点是开放的(world:anyone
),但可以通过 ACL 设置限制访问,适用于需要安全管理的分布式系统。
ACL 的基本组成
ZooKeeper 的 ACL 由三部分组成,格式为 [scheme:id:permissions]
:
- Scheme(认证模式)
- 定义认证的方式,例如
world
、digest
、ip
。
- ID(身份标识)
- 与 Scheme 对应,表示具体的身份,例如用户名、IP 地址。
- Permissions(权限)
- 指定允许的操作,例如读、写、创建等。
示例
world:anyone:cdrwa
:所有人拥有所有权限。digest:user1:password:cr
:用户user1
(经过密码加密)拥有创建和读权限。ip:192.168.1.101:r
:IP 为192.168.1.101
的客户端只有读权限。
权限类型
ZooKeeper 定义了五种基本权限,可以通过组合使用:
- READ (r)
- 允许读取节点数据(
get
)和子节点列表(ls
)。
- WRITE (w)
- 允许修改节点数据(
set
)。
- CREATE (c)
- 允许创建子节点。
- DELETE (d)
- 允许删除节点。
- ADMIN (a)
- 允许设置 ACL(
setAcl
)和管理权限。
权限表示
- 用字母
cdrwa
表示,组合时按需拼接。 - 例如:
rw
表示读写权限,cdrwa
表示所有权限。
认证模式
ZooKeeper 支持多种认证模式(Scheme),用于识别客户端身份:
- world
- ID:固定为
anyone
。 - 含义:表示所有客户端,无需认证。
- 示例:
world:anyone:cdrwa
(默认开放权限)。
- auth
- ID:当前会话中已认证的用户名。
- 含义:基于会话的认证用户,不需显式指定 ID。
- 示例:
auth::rw
(当前认证用户有读写权限)。
- digest
- ID:
username:password
的 Base64 编码 SHA-1 哈希值。 - 含义:基于用户名和密码的认证。
- 示例:
digest:user1:BASE64(SHA1(password)):rw
。
- ip
- ID:客户端的 IP 地址或 CIDR 格式。
- 含义:基于 IP 的访问控制。
- 示例:
ip:192.168.1.101:r
。
- sasl
- ID:SASL 认证的用户名。
- 含义:基于 Kerberos 或其他 SASL 机制。
- 示例:
sasl:user@domain.com:rw
。
ACL 操作示例
以下通过 ZooKeeper 命令行客户端(zkCli.sh
)和 Java API 展示 ACL 的使用。
命令行示例
- 启动客户端
zkCli.sh -server localhost:2181
- 创建节点并设置 ACL(默认开放)
create /openNode "open data"
getAcl /openNode
输出:
'world,'anyone
: cdrwa
- 添加认证用户
addauth digest user1:password123
- 创建受限节点
create /secureNode "secure data" digest:user1:password123:rw
getAcl /secureNode
输出:
'digest,'user1:BASE64(SHA1(password123))
: rw
- 测试权限
- 未认证客户端尝试访问:
bash get /secureNode
输出:Authentication is not valid
- 认证后访问:
bash addauth digest user1:password123 get /secureNode
输出:secure data
- 修改 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 说明。
- ZooKeeper Admin Guide – 认证和权限配置。
- Baeldung – ZooKeeper ACL – ACL 使用教程。
- Apache ZooKeeper FAQ – 安全相关问题解答。
这是 ZooKeeper ACL 的完整解析,涵盖权限类型、认证模式和操作示例。如果您需要更复杂的 ACL 配置(如多用户权限组合),请告诉我!
发表回复