乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • ZooKeeper 学习路径
  • 第1章 分布式协调与ZooKeeper概述

    • ZooKeeper 概述
  • 第2章 单机与集群搭建

    • 配置参数详解
    • 集群搭建
  • 第3章 数据模型与ZNode

    • ZNode 详解
    • 节点类型对比
    • 顺序节点
    • ACL 权限控制
  • 第4章 会话与Watcher机制

    • 会话机制
    • Watcher 机制
  • 第5章 ZAB协议与一致性保证

    • ZAB 协议
    • 一致性保证
    • 数据同步
  • 第6章 Leader选举

    • Leader 选举
  • 第7章 典型应用:分布式锁

    • 分布式锁
  • 第8章 典型应用:配置中心与命名服务

    • 配置中心
    • 命名服务
  • 第9章 客户端编程基础(Java原生API)

    • Java 原生 API 编程
  • 第10章 运维与监控

    • 四字命令
    • 监控体系
  • 第11章 面试考点与设计思想

    • 设计思想
    • 面试考点汇编

本章定位:ACL(Access Control List)是 ZooKeeper 保障 ZNode 数据安全的核心机制。掌握 ACL 才能在分布式环境中安全地共享协调数据。

定义与作用

ACL 控制谁可以对 ZNode 执行什么操作。每个 ZNode 都有自己的 ACL 列表,由一组 (scheme:expression, permissions) 对组成。

ACL 解决的核心痛点:

  • 多租户共享 ZooKeeper 集群时的数据隔离
  • 生产环境误操作防护(如测试客户端误删生产配置)
  • 敏感配置数据(数据库密码、API Key)的访问控制

核心原理

五种权限

权限字母含义影响的操作
CREATEc可创建子节点create()
READr可读取数据和子节点列表getData(), getChildren(), exists()
WRITEw可修改节点数据setData()
DELETEd可删除子节点delete()
ADMINa可修改 ACLsetACL()

四种内置 Scheme

world 是默认方案(world:anyone),任何人拥有全部权限。digest 是最常用的认证方案,通过用户名密码认证。ip 适合内网白名单场景。

ACL 不递归

ACL 仅作用于当前 ZNode,不继承到子节点。父节点 ACL 与子节点 ACL 完全独立。

/app           ACL: world:anyone:cdrwa(所有人)
  /app/config  ACL: digest:admin:xxxxx:cdrwa(仅 admin 可用)
  /app/public  ACL: world:anyone:r(所有人只读)

完整示例

示例一:digest 认证的完整流程

场景说明:对 /app/config 节点设置 digest 认证,仅 admin 用户可读写。

操作前状态:节点 /app/config 使用默认 ACL(world:anyone:cdrwa)。

zkCli.sh -server 127.0.0.1:2181

# 1. 查看当前 ACL
[zkshell: 0] getAcl /app/config
'world,'anyone
: cdrwa

# 2. 添加认证身份
[zkshell: 1] addauth digest admin:admin123

# 3. 设置 ACL —— 仅 admin 拥有全部权限
[zkshell: 2] setAcl /app/config auth:admin:cdrwa

# 4. 验证 —— 当前会话 (admin) 可读
[zkshell: 3] get /app/config
port=8080

# 5. 验证 —— 新会话(未认证)被拒绝
# 在另一个终端:
zkCli.sh -server 127.0.0.1:2181
[zkshell: 0] get /app/config
Authentication is not valid : /app/config

Java API 实现:

ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 3000, event -> {});

// 认证
zk.addAuthInfo("digest", "admin:admin123".getBytes());

// 创建 ACL
ACL acl = new ACL(ZooDefs.Perms.ALL,
        new Id("auth", "admin"));
List<ACL> acls = Collections.singletonList(acl);

// 设置 ACL
zk.setACL("/app/config", acls, -1);

操作后状态:

会话认证身份操作 /app/config结果
当前会话adminget / setData成功
新会话无getNoAuthException

示例二:IP 白名单场景

场景说明:生产配置节点仅允许内网指定 IP 的服务器读取。

# 设置 ACL —— 仅 192.168.1.0/24 网段可读
[zkshell: 0] setAcl /app/config ip:192.168.1.0/24:r

# 192.168.1.10 机器上的客户端
[zkshell: 0] get /app/config
port=8080

# 外网 10.0.0.1 机器上的客户端
[zkshell: 0] get /app/config
Authentication is not valid : /app/config

操作前后对比:

来源 IPACL 设置前ACL 设置后
192.168.1.x(内网)可读写可读(不可写)
10.0.0.x(外网)可读写无权限

示例三:多权限混合 ACL

场景说明:一个节点允许 admin 用户全权限,其他用户只读。

[zkshell: 0] create /app/mixed "mixed-data"
Created /app/mixed

# 添加认证
[zkshell: 1] addauth digest admin:admin123

# 设置混合 ACL
[zkshell: 2] setAcl /app/mixed \
  auth:admin:cdrwa,\
  world:anyone:r

[zkshell: 3] getAcl /app/mixed
'digest,'admin:QIbUSW6wR4RcBU...
: cdrwa
'world,'anyone
: r

操作前后对比:

角色读写创建子节点删除修改 ACL
admin(已认证)✅✅✅✅✅
匿名用户✅❌❌❌❌

易错场景与面试考点

易错场景

1. 忘记 addauth 就设置 auth ACL

# 没有先 addauth
[zkshell: 0] setAcl /node auth:user:cdrwa
# Acl is not valid : /node

# 原因:auth scheme 需要当前会话已有认证身份

必须先执行 addauth,才能用 auth scheme 设置 ACL。

2. 设置 ACL 后把自己锁在外面

# 设置 digest ACL 但未先 addauth
[zkshell: 0] setAcl /node digest:admin:hashedPwd:cdrwa
[zkshell: 1] get /node
# Authentication is not valid
# 自己也无法读取!

正确流程:先 addauth 建立身份 → 再 setAcl。

3. ACL 不递归带来的安全隐患

# /app 是所有人可读
# /app/secrets 可能被疏忽设置为继承父节点
create /app/secrets "password=secret"
# 默认 ACL 是 world:anyone:cdrwa !任何人可读写

每次创建节点都应显式考虑 ACL。可使用 Curator 的 withACL() 统一管理。

面试高频题

Q:ZooKeeper ACL 与 Unix 文件权限有何不同?

A:

  • ZooKeeper 不区分 owner/group/other,而是使用 scheme:expression 的身份模型
  • ZooKeeper 有 ADMIN 权限(修改 ACL)和 CREATE/DELETE 的细粒度拆分
  • ZooKeeper ACL 不递归,Unix 默认也不递归但可通过 setfacl -R 实现
  • ZooKeeper 无 LOOKUP 权限(可遍历目录但不可列出),因为不需要

Q:auth 和 digest scheme 的区别?

A:

  • digest:ACL 中存储的是 username:base64(sha1(password)) 的静态哈希值,任何知道密码的用户都可以匹配
  • auth:不存储具体身份信息,而是动态引用当前会话的认证身份。设置后,只有该会话创建者可以访问

Q:如何实现"节点创建者才有全部权限"?

A:使用 auth scheme 配合 ZOO_CREATOR_ALL_ACL:

zk.addAuthInfo("digest", "user:password".getBytes());
zk.create("/node", data,
    ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);

这样 /node 的 ACL 为 auth::cdrwa,只有该用户能操作。

小结

要点说明
5 种权限CREATE、READ、WRITE、DELETE、ADMIN
4+1 种 Schemeworld、auth、digest、ip、x509
ACL 不递归子节点需独立设置
默认 ACLworld:anyone:cdrwa(全员全权限)
auth vs digestauth 动态、digest 静态哈希
IP 白名单通过 ip scheme + 子网掩码实现

ACL 是安全的第一道防线。下一节将深入顺序节点的机制,理解它在分布式锁和队列中的核心作用。

上一页
顺序节点