在生产环境中设置 ZooKeeper 的访问控制列表(ACL)是确保数据安全和访问控制的关键步骤。ACL 允许你定义谁可以访问 ZooKeeper 节点以及他们可以执行的操作。以下是设置 ZooKeeper ACL 的详细步骤和代码示例。
ACL 基础知识
ZooKeeper 支持以下几种权限:
- CREATE:允许创建子节点。
- READ:允许读取节点数据和获取子节点列表。
- WRITE:允许设置节点数据。
- DELETE:允许删除子节点。
- ADMIN:允许设置权限。
ZooKeeper 支持以下几种认证模式:
- world:任何人都可以访问。
- auth:使用已经认证的用户。
- digest:使用用户名和密码认证。
- ip:基于 IP 地址的访问控制。
- super:超级用户模式,拥有所有权限。
设置 ACL 的步骤
1. 启用 ZooKeeper 认证
首先,需要在 zoo.cfg
配置文件中启用 ZooKeeper 认证。
properties
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
2. 使用 Digest 认证模式设置 ACL
Digest 认证模式通过用户名和密码进行身份验证。以下是详细的步骤和代码示例。
创建一个具有 Digest 认证模式的节点
- 连接到 ZooKeeper CLI:
bash
zkCli.sh -server localhost:2181
- 添加认证信息:
bash
addauth digest admin:admin_password
- 创建一个节点并设置 ACL:
bash
create /secure_node "secure_data" digest:admin:admin_password:cdrwa
在上述命令中,digest:admin:admin_password:cdrwa
表示使用 admin
用户名和 admin_password
密码进行认证,并赋予 cdrwa
(CREATE、DELETE、READ、WRITE、ADMIN)权限。
验证 ACL 设置
- 尝试在没有认证的情况下读取节点数据:
bash
get /secure_node
你应该会看到权限错误。
- 使用认证信息读取节点数据:
bash
addauth digest admin:admin_password
get /secure_node
你应该能够成功读取节点数据。
修改节点的 ACL
- 添加新的用户权限:
bash
setAcl /secure_node digest:admin:admin_password:cdrwa,digest:user:user_password:rw
在上述命令中,digest:user:user_password:rw
表示 user
用户名和 user_password
密码具有读写(READ、WRITE)权限。
- 验证新的用户权限:
bash
# 添加新用户的认证信息
addauth digest user:user_password
# 尝试读取节点数据
get /secure_node
# 尝试写入节点数据
set /secure_node "new_secure_data"
使用 Java API 设置 ACL
除了使用 CLI,也可以使用 Java API 来设置和管理 ACL。
1. 添加依赖
在你的 Maven 项目中添加 ZooKeeper 依赖:
xml
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactVersion>3.7.0</artifactVersion>
</dependency>
2. 使用 Java 代码设置 ACL
java
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import java.util.ArrayList;
import java.util.List;
public class ZooKeeperACLExample {
public static void main(String[] args) throws Exception {
String connectString = "localhost:2181";
int sessionTimeout = 3000;
ZooKeeper zk = new ZooKeeper(connectString, sessionTimeout, event -> {});
// 添加认证信息
zk.addAuthInfo("digest", "admin:admin_password".getBytes());
// 创建 ACL 列表
List<ACL> acls = new ArrayList<>();
Id adminId = new Id("digest", "admin:admin_password");
ACL adminAcl = new ACL(ZooDefs.Perms.ALL, adminId);
acls.add(adminAcl);
// 创建节点并设置 ACL
String path = "/secure_node_java";
String data = "secure_data";
zk.create(path, data.getBytes(), acls, CreateMode.PERSISTENT);
// 验证 ACL 设置
zk.addAuthInfo("digest", "user:user_password".getBytes());
byte[] retrievedData = zk.getData(path, false, null);
System.out.println("Data: " + new String(retrievedData));
zk.close();
}
}
总结
通过设置 ZooKeeper 的 ACL,可以有效地控制对 ZooKeeper 节点的访问权限,确保数据的安全性。可以使用 ZooKeeper CLI 或 Java API 来设置和管理 ACL。在生产环境中,合理设置 ACL 是确保 ZooKeeper 集群安全和数据保护的重要措施。