欢迎光临
我们一直在努力

ZooKeeper ACL 权限控制机制深度解析:从原理到实战

ZooKeeper ACL 权限控制机制深度解析:从原理到实战

    • 一、ACL 权限控制概述
      • 1.1 什么是 ACL?
      • 1.2 为什么需要 ACL?
    • 二、ACL 的组成要素
      • 2.1 权限类型(Permissions)
      • 2.2 认证方案(Scheme)
    • 三、ACL 的工作流程
      • 3.1 完整的 ACL 验证流程
      • 3.2 权限验证的核心逻辑
    • 四、内置 ACL 常量
    • 五、ACL 的操作命令
      • 5.1 命令行操作
        • 添加认证信息
        • 查看 ACL
        • 设置 ACL
        • 创建时直接设置 ACL
      • 5.2 Java API 操作
        • 客户端添加认证信息
    • 六、五种认证方案详解
      • 6.1 world 方案:最简单但最不安全
      • 6.2 auth 方案:当前认证用户
      • 6.3 digest 方案:最常用
        • 密码哈希生成工具
        • 使用示例
      • 6.4 ip 方案:基于网络位置
      • 6.5 sasl 方案:企业级认证
    • 七、ACL 的继承规则与注意事项
      • 7.1 ACL 的继承规则
      • 7.2 重要注意事项
    • 八、最佳实践与安全建议
      • 8.1 生产环境 ACL 配置清单
      • 8.2 常见场景配置
      • 8.3 安全审计脚本
    • 九、总结
      • 9.1 ACL 核心要点
      • 9.2 实现原理回顾
      • 9.3 一句话总结

🌺The Begin🌺点点关注,收藏不迷路🌺

摘要:在分布式系统中,数据安全是至关重要的。ZooKeeper 作为分布式协调服务,存储着大量敏感配置和元数据,必须提供完善的访问控制机制。ACL(Access Control List,访问控制列表)就是 ZooKeeper 实现精细化权限管理的核心机制。本文将深入剖析 ZooKeeper ACL 的工作原理、权限类型、认证方案以及完整的实现流程,通过源码分析和实战示例,帮助读者全面掌握 ACL 权限控制机制。

一、ACL 权限控制概述

1.1 什么是 ACL?

ACL(Access Control List)是 ZooKeeper 提供的访问控制列表机制,用于定义谁可以对 ZNode 执行什么操作 。它与传统的 UNIX 文件权限类似,但更加灵活和精细化,主要体现在:

  • 没有文件所有者概念:不同于 UNIX 权限中的用户(owner)、组(group)、其他人(other)三范围,ZooKeeper 的节点没有所有者的概念
  • 支持多种认证方案:通过可插拔的认证机制,支持 world、auth、digest、ip、sasl 等多种认证方式
  • 节点级控制:ACL 仅针对特定节点,不会递归应用到子节点

#mermaid-svg-S5RtMackONuFdRjP{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-S5RtMackONuFdRjP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-S5RtMackONuFdRjP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-S5RtMackONuFdRjP .error-icon{fill:#552222;}#mermaid-svg-S5RtMackONuFdRjP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-S5RtMackONuFdRjP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-S5RtMackONuFdRjP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-S5RtMackONuFdRjP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-S5RtMackONuFdRjP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-S5RtMackONuFdRjP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-S5RtMackONuFdRjP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-S5RtMackONuFdRjP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-S5RtMackONuFdRjP .marker.cross{stroke:#333333;}#mermaid-svg-S5RtMackONuFdRjP svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-S5RtMackONuFdRjP p{margin:0;}#mermaid-svg-S5RtMackONuFdRjP .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-S5RtMackONuFdRjP .cluster-label text{fill:#333;}#mermaid-svg-S5RtMackONuFdRjP .cluster-label span{color:#333;}#mermaid-svg-S5RtMackONuFdRjP .cluster-label span p{background-color:transparent;}#mermaid-svg-S5RtMackONuFdRjP .label text,#mermaid-svg-S5RtMackONuFdRjP span{fill:#333;color:#333;}#mermaid-svg-S5RtMackONuFdRjP .node rect,#mermaid-svg-S5RtMackONuFdRjP .node circle,#mermaid-svg-S5RtMackONuFdRjP .node ellipse,#mermaid-svg-S5RtMackONuFdRjP .node polygon,#mermaid-svg-S5RtMackONuFdRjP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-S5RtMackONuFdRjP .rough-node .label text,#mermaid-svg-S5RtMackONuFdRjP .node .label text,#mermaid-svg-S5RtMackONuFdRjP .image-shape .label,#mermaid-svg-S5RtMackONuFdRjP .icon-shape .label{text-anchor:middle;}#mermaid-svg-S5RtMackONuFdRjP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-S5RtMackONuFdRjP .rough-node .label,#mermaid-svg-S5RtMackONuFdRjP .node .label,#mermaid-svg-S5RtMackONuFdRjP .image-shape .label,#mermaid-svg-S5RtMackONuFdRjP .icon-shape .label{text-align:center;}#mermaid-svg-S5RtMackONuFdRjP .node.clickable{cursor:pointer;}#mermaid-svg-S5RtMackONuFdRjP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-S5RtMackONuFdRjP .arrowheadPath{fill:#333333;}#mermaid-svg-S5RtMackONuFdRjP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-S5RtMackONuFdRjP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-S5RtMackONuFdRjP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-S5RtMackONuFdRjP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-S5RtMackONuFdRjP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-S5RtMackONuFdRjP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-S5RtMackONuFdRjP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-S5RtMackONuFdRjP .cluster text{fill:#333;}#mermaid-svg-S5RtMackONuFdRjP .cluster span{color:#333;}#mermaid-svg-S5RtMackONuFdRjP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-S5RtMackONuFdRjP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-S5RtMackONuFdRjP rect.text{fill:none;stroke-width:0;}#mermaid-svg-S5RtMackONuFdRjP .icon-shape,#mermaid-svg-S5RtMackONuFdRjP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-S5RtMackONuFdRjP .icon-shape p,#mermaid-svg-S5RtMackONuFdRjP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-S5RtMackONuFdRjP .icon-shape rect,#mermaid-svg-S5RtMackONuFdRjP .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-S5RtMackONuFdRjP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-S5RtMackONuFdRjP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-S5RtMackONuFdRjP :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

ACL 的核心组成

ACL

Scheme授权方案

ID授权ID

Permissions权限位

1.2 为什么需要 ACL?

ZooKeeper 中存储着大量敏感信息 :

数据类别示例安全风险
配置信息 数据库连接串、密码、密钥 泄露导致数据被篡改
服务元数据 服务注册信息、路由规则 恶意服务注册导致流量劫持
分布式锁 锁节点状态 误释放或抢占锁导致数据竞争
集群状态 节点存活信息 暴露内部拓扑结构

没有 ACL,任何客户端都可以随意读取、修改这些数据,造成严重的安全隐患。

二、ACL 的组成要素

每个 ACL 由三部分组成:权限(permissions)、认证方案(scheme)和授权ID(id) 。

2.1 权限类型(Permissions)

ZooKeeper 定义了 5 种基本权限,使用字母表示,可以组合使用 :

权限缩写数字表示说明
CREATE c 1 允许创建子节点
DELETE d 2 允许删除子节点
READ r 4 允许读取节点数据及子节点列表
WRITE w 8 允许修改节点数据
ADMIN a 16 允许设置 ACL 权限

权限设计背后的考量:

  • CREATE 和 DELETE 从 WRITE 权限中分离出来,是为了更精细的控制 。例如:
    • 你可以允许用户设置节点数据,但不允许创建或删除子节点
    • 有 CREATE 但无 DELETE 权限:客户端可以创建节点,但只有特定进程能删除(类似于文件的 APPEND 权限)

权限组合示例:

// 权限组合计算
int READ_WRITE = 4 | 8 = 12; // rw
int ALL = 1 | 2 | 4 | 8 | 16 = 31; // cdwra
int READ_ONLY = 4; // r

#mermaid-svg-hli577Pr4CFba3xz{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hli577Pr4CFba3xz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hli577Pr4CFba3xz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hli577Pr4CFba3xz .error-icon{fill:#552222;}#mermaid-svg-hli577Pr4CFba3xz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hli577Pr4CFba3xz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hli577Pr4CFba3xz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hli577Pr4CFba3xz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hli577Pr4CFba3xz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hli577Pr4CFba3xz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hli577Pr4CFba3xz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hli577Pr4CFba3xz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hli577Pr4CFba3xz .marker.cross{stroke:#333333;}#mermaid-svg-hli577Pr4CFba3xz svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hli577Pr4CFba3xz p{margin:0;}#mermaid-svg-hli577Pr4CFba3xz .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-hli577Pr4CFba3xz .cluster-label text{fill:#333;}#mermaid-svg-hli577Pr4CFba3xz .cluster-label span{color:#333;}#mermaid-svg-hli577Pr4CFba3xz .cluster-label span p{background-color:transparent;}#mermaid-svg-hli577Pr4CFba3xz .label text,#mermaid-svg-hli577Pr4CFba3xz span{fill:#333;color:#333;}#mermaid-svg-hli577Pr4CFba3xz .node rect,#mermaid-svg-hli577Pr4CFba3xz .node circle,#mermaid-svg-hli577Pr4CFba3xz .node ellipse,#mermaid-svg-hli577Pr4CFba3xz .node polygon,#mermaid-svg-hli577Pr4CFba3xz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hli577Pr4CFba3xz .rough-node .label text,#mermaid-svg-hli577Pr4CFba3xz .node .label text,#mermaid-svg-hli577Pr4CFba3xz .image-shape .label,#mermaid-svg-hli577Pr4CFba3xz .icon-shape .label{text-anchor:middle;}#mermaid-svg-hli577Pr4CFba3xz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hli577Pr4CFba3xz .rough-node .label,#mermaid-svg-hli577Pr4CFba3xz .node .label,#mermaid-svg-hli577Pr4CFba3xz .image-shape .label,#mermaid-svg-hli577Pr4CFba3xz .icon-shape .label{text-align:center;}#mermaid-svg-hli577Pr4CFba3xz .node.clickable{cursor:pointer;}#mermaid-svg-hli577Pr4CFba3xz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hli577Pr4CFba3xz .arrowheadPath{fill:#333333;}#mermaid-svg-hli577Pr4CFba3xz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hli577Pr4CFba3xz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hli577Pr4CFba3xz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hli577Pr4CFba3xz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hli577Pr4CFba3xz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hli577Pr4CFba3xz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hli577Pr4CFba3xz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hli577Pr4CFba3xz .cluster text{fill:#333;}#mermaid-svg-hli577Pr4CFba3xz .cluster span{color:#333;}#mermaid-svg-hli577Pr4CFba3xz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hli577Pr4CFba3xz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hli577Pr4CFba3xz rect.text{fill:none;stroke-width:0;}#mermaid-svg-hli577Pr4CFba3xz .icon-shape,#mermaid-svg-hli577Pr4CFba3xz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hli577Pr4CFba3xz .icon-shape p,#mermaid-svg-hli577Pr4CFba3xz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hli577Pr4CFba3xz .icon-shape rect,#mermaid-svg-hli577Pr4CFba3xz .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hli577Pr4CFba3xz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hli577Pr4CFba3xz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hli577Pr4CFba3xz :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

常见权限组合

权限组合 (按位或运算)

ZooKeeper ACL 权限位定义

CREATE (C)位值: 1 (2^0)

DELETE (D)位值: 2 (2^1)

READ (R)位值: 4 (2^2)

WRITE (W)位值: 8 (2^3)

ADMIN (A)位值: 16 (2^4)

权限组合

cdwr (15)CREATE|DELETE|READ|WRITE1|2|4|8 = 15

rwa (28)READ|WRITE|ADMIN4|8|16 = 28

all (31)所有权限1|2|4|8|16 = 31

read (4)只读权限READ = 4

write (8)只写权限WRITE = 8

2.2 认证方案(Scheme)

Scheme 定义了 ACL 的验证方式,ZooKeeper 支持多种方案 :

Scheme说明ID 格式使用场景
world 全世界,所有客户端都有权限 anyone 公开数据、默认配置
auth 任何已认证的用户 空(使用当前认证信息) 多用户协作
digest 用户名:密码认证 用户名:密码哈希 最常见的认证方式
ip IP 地址限制 IP 地址或网段 内网服务、固定IP环境
sasl Kerberos 认证 认证主体 企业级安全环境

特别说明 :

  • 由于普通模式启动客户端不需要认证,sasl 认证类型的 ACL 在普通模式下将不能使用
  • 在 3.5.6 及以后版本,用户对于 getAcl 操作需要有读权限

三、ACL 的工作流程

3.1 完整的 ACL 验证流程

Client2

ACL验证模块

认证模块

ZooKeeper服务器

客户端

Client2

ACL验证模块

认证模块

ZooKeeper服务器

客户端

#mermaid-svg-q1Y3B9USA5KmIRF1{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-q1Y3B9USA5KmIRF1 .error-icon{fill:#552222;}#mermaid-svg-q1Y3B9USA5KmIRF1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-q1Y3B9USA5KmIRF1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-q1Y3B9USA5KmIRF1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-q1Y3B9USA5KmIRF1 .marker.cross{stroke:#333333;}#mermaid-svg-q1Y3B9USA5KmIRF1 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-q1Y3B9USA5KmIRF1 p{margin:0;}#mermaid-svg-q1Y3B9USA5KmIRF1 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-q1Y3B9USA5KmIRF1 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-q1Y3B9USA5KmIRF1 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-q1Y3B9USA5KmIRF1 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-q1Y3B9USA5KmIRF1 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-q1Y3B9USA5KmIRF1 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-q1Y3B9USA5KmIRF1 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-q1Y3B9USA5KmIRF1 .sequenceNumber{fill:white;}#mermaid-svg-q1Y3B9USA5KmIRF1 #sequencenumber{fill:#333;}#mermaid-svg-q1Y3B9USA5KmIRF1 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-q1Y3B9USA5KmIRF1 .messageText{fill:#333;stroke:none;}#mermaid-svg-q1Y3B9USA5KmIRF1 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-q1Y3B9USA5KmIRF1 .labelText,#mermaid-svg-q1Y3B9USA5KmIRF1 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-q1Y3B9USA5KmIRF1 .loopText,#mermaid-svg-q1Y3B9USA5KmIRF1 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-q1Y3B9USA5KmIRF1 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-q1Y3B9USA5KmIRF1 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-q1Y3B9USA5KmIRF1 .noteText,#mermaid-svg-q1Y3B9USA5KmIRF1 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-q1Y3B9USA5KmIRF1 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-q1Y3B9USA5KmIRF1 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-q1Y3B9USA5KmIRF1 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-q1Y3B9USA5KmIRF1 .actorPopupMenu{position:absolute;}#mermaid-svg-q1Y3B9USA5KmIRF1 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-q1Y3B9USA5KmIRF1 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-q1Y3B9USA5KmIRF1 .actor-man circle,#mermaid-svg-q1Y3B9USA5KmIRF1 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-q1Y3B9USA5KmIRF1 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

阶段1:添加认证信息

阶段2:创建受保护节点

阶段3:未认证的访问

阶段4:已认证的访问

addauth digest user:pass

验证用户名密码

认证通过,存储认证信息

create /secure secret

设置 ACL: digest:user:pass:cdwra

创建成功

get /secure

检查客户端认证信息

无匹配认证信息

NoAuth异常

get /secure

检查客户端认证信息

认证匹配,权限通过

返回数据

3.2 权限验证的核心逻辑

当客户端请求访问 ZNode 时,ZooKeeper 按照以下规则进行权限验证 :

  • 获取客户端认证信息:从客户端连接中获取所有关联的 ID(通过 addAuthInfo 添加)
  • 获取节点的 ACL 列表:从目标 ZNode 读取 ACL 配置
  • 遍历匹配:对每个 ACL 条目,检查 scheme 和 id 是否与客户端的认证信息匹配
  • 权限检查:如果找到匹配的条目,检查其权限位是否包含请求的操作所需权限
  • 授权决策:任何匹配的 ACL 满足所需权限即可通过;如果没有匹配项,则拒绝访问
  • // 权限验证的核心逻辑(简化版)
    public boolean checkPermission(ClientInfo client, ZNode node, int requiredPerm) {
    // 1. 获取节点的 ACL 列表
    List<ACL> acls = node.getAcl();

    // 2. 遍历 ACL,查找匹配项
    for (ACL acl : acls) {
    // 检查 scheme 是否匹配
    if (!matchesScheme(client, acl)) continue;

    // 检查 ID 是否匹配
    if (!matchesId(client, acl)) continue;

    // 检查权限是否包含所需权限
    if ((acl.getPerms() & requiredPerm) == requiredPerm) {
    return true; // 权限验证通过
    }
    }

    // 3. 没有匹配的 ACL,拒绝访问
    return false;
    }

    四、内置 ACL 常量

    ZooKeeper 在 ZooDefs.Ids 中提供了一些常用的 ACL 常量,方便开发者使用 :

    常量等效 ACL说明
    OPEN_ACL_UNSAFE world:anyone:cdrwa 完全开放,任何应用可在节点上执行任何操作,能创建、列出和删除其子节点
    CREATOR_ALL_ACL auth::cdrwa 创建者有所有权限,创建者必须已被服务器认证
    READ_ACL_UNSAFE world:anyone:r 任何人只读

    public class BuiltInAclExample {

    public void useBuiltInAcl() throws Exception {
    ZooKeeper zk = new ZooKeeper("localhost:2181", 5000, null);

    // 1. 完全开放的节点(不安全)
    zk.create("/public", "data".getBytes(),
    ZooDefs.Ids.OPEN_ACL_UNSAFE,
    CreateMode.PERSISTENT);

    // 2. 仅创建者可访问
    zk.addAuthInfo("digest", "admin:admin123".getBytes());
    zk.create("/private", "secret".getBytes(),
    ZooDefs.Ids.CREATOR_ALL_ACL,
    CreateMode.PERSISTENT);

    // 3. 全局只读
    zk.create("/readonly", "readme".getBytes(),
    ZooDefs.Ids.READ_ACL_UNSAFE,
    CreateMode.PERSISTENT);
    }
    }

    五、ACL 的操作命令

    5.1 命令行操作

    添加认证信息

    # 添加 digest 认证信息
    [zk: localhost:2181(CONNECTED) 0] addauth digest admin:admin123

    查看 ACL

    # 查看节点的 ACL
    [zk: localhost:2181(CONNECTED) 1] getAcl /config

    # 输出示例
    'world,'anyone
    : cdrwa

    设置 ACL

    # 1. world 方案(任何人可读)
    [zk: localhost:2181(CONNECTED) 0] create /public "public-data"
    [zk: localhost:2181(CONNECTED) 1] setAcl /public world:anyone:r

    # 2. digest 方案(用户名密码认证)
    [zk: localhost:2181(CONNECTED) 2] addauth digest admin:admin123
    [zk: localhost:2181(CONNECTED) 3] create /secure "secret"
    [zk: localhost:2181(CONNECTED) 4] setAcl /secure digest:admin:admin123:cdwra

    # 3. ip 方案(IP 限制)
    [zk: localhost:2181(CONNECTED) 5] create /ip-limited "internal"
    [zk: localhost:2181(CONNECTED) 6] setAcl /ip-limited ip:192.168.1.0/24:cdrwa

    # 4. 组合多个 ACL
    [zk: localhost:2181(CONNECTED) 7] setAcl /multi world:anyone:r,digest:admin:admin123:cdwra

    创建时直接设置 ACL

    # 创建节点时指定 ACL
    [zk: localhost:2181(CONNECTED) 0] create /secure-node "data" digest:admin:admin123:cdwra

    5.2 Java API 操作

    客户端添加认证信息

    import org.apache.zookeeper.*;
    import org.apache.zookeeper.data.ACL;
    import org.apache.zookeeper.data.Id;
    import org.apache.zookeeper.data.Stat;

    import java.util.ArrayList;
    import java.util.List;

    public class ACLExample {
    private ZooKeeper zk;

    /**
    * 添加认证信息
    */

    public void addAuth() throws Exception {
    // 添加 digest 认证
    zk.addAuthInfo("digest", "admin:admin123".getBytes());
    System.out.println("认证信息已添加");
    }

    /**
    * 创建带 ACL 的节点
    */

    public void createNodeWithAcl() throws Exception {
    // 1. 添加认证信息(必须先认证)
    zk.addAuthInfo("digest", "admin:admin123".getBytes());

    // 2. 创建 ACL 列表
    List<ACL> acls = new ArrayList<>();

    // 添加 digest 认证 ACL
    Id id1 = new Id("digest", "admin:W5R8ZqN7nYqY9YqY"); // 密码哈希
    acls.add(new ACL(ZooDefs.Perms.ALL, id1)); // 所有权限

    // 添加 IP 限制 ACL
    Id id2 = new Id("ip", "192.168.1.100");
    acls.add(new ACL(ZooDefs.Perms.READ, id2)); // 只读权限

    // 3. 创建节点
    String path = zk.create("/secure-node",
    "sensitive-data".getBytes(),
    acls,
    CreateMode.PERSISTENT);
    System.out.println("节点创建成功: " + path);
    }

    /**
    * 获取节点的 ACL
    */

    public void getNodeAcl(String path) throws Exception {
    Stat stat = new Stat();
    List<ACL> acls = zk.getACL(path, stat);

    System.out.println("节点 " + path + " 的 ACL:");
    for (ACL acl : acls) {
    System.out.println(" Scheme: " + acl.getId().getScheme() +
    ", ID: " + acl.getId().getId() +
    ", Perms: " + acl.getPerms());
    }
    }

    /**
    * 设置节点的 ACL
    */

    public void setNodeAcl(String path) throws Exception {
    // 创建新的 ACL
    List<ACL> acls = ZooDefs.Ids.CREATOR_ALL_ACL; // 仅创建者有所有权限

    Stat stat = new Stat();
    zk.getData(path, false, stat);

    // 使用版本号更新 ACL(aversion 版本控制)
    zk.setACL(path, acls, stat.getAversion());
    System.out.println("ACL 更新成功");
    }
    }

    六、五种认证方案详解

    6.1 world 方案:最简单但最不安全

    # world 方案
    [zk: localhost:2181(CONNECTED) 0] create /public "open"
    [zk: localhost:2181(CONNECTED) 1] setAcl /public world:anyone:r

    # 任何人都可以读
    [zk: localhost:2181(CONNECTED) 2] get /public
    open

    特点 :

    • 不进行任何认证
    • ID 固定为 anyone
    • 适合公开的配置信息

    6.2 auth 方案:当前认证用户

    # 1. 先添加认证
    [zk: localhost:2181(CONNECTED) 0] addauth digest user1:pass1
    [zk: localhost:2181(CONNECTED) 1] addauth digest user2:pass2

    # 2. 创建节点,使用 auth 方案
    [zk: localhost:2181(CONNECTED) 2] create /shared "shared-data"
    [zk: localhost:2181(CONNECTED) 3] setAcl /shared auth::cdrwa

    # 3. 查看 ACL(自动添加了两个用户)
    [zk: localhost:2181(CONNECTED) 4] getAcl /shared
    'digest,'user1:rX8ZpK6mXpX8XpX
    : cdrwa
    'digest,'user2:pY7QoJ5nYoY7YoY
    : cdrwa

    特点 :

    • 自动将当前所有已认证用户添加到 ACL
    • ID 为空字符串,表示"创建者的身份"
    • 适合多用户协作场景

    6.3 digest 方案:最常用

    digest 认证通过用户名和密码进行身份验证,是生产环境中最常用的认证方式。密码不以明文存储,而是经过 SHA-1 加密后再进行 Base64 编码 。

    #mermaid-svg-bPXEq6cfToDFe02r{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bPXEq6cfToDFe02r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bPXEq6cfToDFe02r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bPXEq6cfToDFe02r .error-icon{fill:#552222;}#mermaid-svg-bPXEq6cfToDFe02r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bPXEq6cfToDFe02r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bPXEq6cfToDFe02r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bPXEq6cfToDFe02r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bPXEq6cfToDFe02r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bPXEq6cfToDFe02r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bPXEq6cfToDFe02r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bPXEq6cfToDFe02r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bPXEq6cfToDFe02r .marker.cross{stroke:#333333;}#mermaid-svg-bPXEq6cfToDFe02r svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bPXEq6cfToDFe02r p{margin:0;}#mermaid-svg-bPXEq6cfToDFe02r .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-bPXEq6cfToDFe02r .cluster-label text{fill:#333;}#mermaid-svg-bPXEq6cfToDFe02r .cluster-label span{color:#333;}#mermaid-svg-bPXEq6cfToDFe02r .cluster-label span p{background-color:transparent;}#mermaid-svg-bPXEq6cfToDFe02r .label text,#mermaid-svg-bPXEq6cfToDFe02r span{fill:#333;color:#333;}#mermaid-svg-bPXEq6cfToDFe02r .node rect,#mermaid-svg-bPXEq6cfToDFe02r .node circle,#mermaid-svg-bPXEq6cfToDFe02r .node ellipse,#mermaid-svg-bPXEq6cfToDFe02r .node polygon,#mermaid-svg-bPXEq6cfToDFe02r .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bPXEq6cfToDFe02r .rough-node .label text,#mermaid-svg-bPXEq6cfToDFe02r .node .label text,#mermaid-svg-bPXEq6cfToDFe02r .image-shape .label,#mermaid-svg-bPXEq6cfToDFe02r .icon-shape .label{text-anchor:middle;}#mermaid-svg-bPXEq6cfToDFe02r .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bPXEq6cfToDFe02r .rough-node .label,#mermaid-svg-bPXEq6cfToDFe02r .node .label,#mermaid-svg-bPXEq6cfToDFe02r .image-shape .label,#mermaid-svg-bPXEq6cfToDFe02r .icon-shape .label{text-align:center;}#mermaid-svg-bPXEq6cfToDFe02r .node.clickable{cursor:pointer;}#mermaid-svg-bPXEq6cfToDFe02r .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bPXEq6cfToDFe02r .arrowheadPath{fill:#333333;}#mermaid-svg-bPXEq6cfToDFe02r .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bPXEq6cfToDFe02r .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bPXEq6cfToDFe02r .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bPXEq6cfToDFe02r .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bPXEq6cfToDFe02r .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bPXEq6cfToDFe02r .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bPXEq6cfToDFe02r .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bPXEq6cfToDFe02r .cluster text{fill:#333;}#mermaid-svg-bPXEq6cfToDFe02r .cluster span{color:#333;}#mermaid-svg-bPXEq6cfToDFe02r div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bPXEq6cfToDFe02r .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bPXEq6cfToDFe02r rect.text{fill:none;stroke-width:0;}#mermaid-svg-bPXEq6cfToDFe02r .icon-shape,#mermaid-svg-bPXEq6cfToDFe02r .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bPXEq6cfToDFe02r .icon-shape p,#mermaid-svg-bPXEq6cfToDFe02r .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bPXEq6cfToDFe02r .icon-shape rect,#mermaid-svg-bPXEq6cfToDFe02r .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bPXEq6cfToDFe02r .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bPXEq6cfToDFe02r .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bPXEq6cfToDFe02r :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    digest 认证流程

    匹配

    不匹配

    客户端输入用户名:密码

    addauth digest user:pass

    客户端发送明文密码

    服务端计算 SHA-1 哈希

    与存储的哈希比较

    认证通过

    认证失败

    密码哈希生成工具

    import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;

    public class PasswordGenerator {
    public static void main(String[] args) throws Exception {
    String userPass = "admin:admin123";
    String hash = DigestAuthenticationProvider.generateDigest(userPass);
    System.out.println("密码哈希: " + hash);
    // 输出: admin:W5R8ZqN7nYqY9YqY
    }
    }

    使用示例

    # 1. 添加认证
    [zk: localhost:2181(CONNECTED) 0] addauth digest admin:admin123

    # 2. 创建受保护节点
    [zk: localhost:2181(CONNECTED) 1] create /secret "top-secret"
    [zk: localhost:2181(CONNECTED) 2] setAcl /secret digest:admin:admin123:cdwra

    # 3. 查看 ACL(密码已哈希)
    [zk: localhost:2181(CONNECTED) 3] getAcl /secret
    'digest,'admin:W5R8ZqN7nYqY9YqY
    : cdrwa

    # 4. 另一个客户端尝试访问
    [zk: localhost:2181(CONNECTED) 0] get /secret
    KeeperErrorCode = NoAuth for /secret

    # 5. 添加正确认证后可以访问
    [zk: localhost:2181(CONNECTED) 1] addauth digest admin:admin123
    [zk: localhost:2181(CONNECTED) 2] get /secret
    top-secret

    6.4 ip 方案:基于网络位置

    # 允许特定 IP 访问
    [zk: localhost:2181(CONNECTED) 0] create /internal "internal-data"
    [zk: localhost:2181(CONNECTED) 1] setAcl /internal ip:192.168.1.100:cdrwa

    # 允许整个网段
    [zk: localhost:2181(CONNECTED) 2] setAcl /internal ip:192.168.1.0/24:cdrwa

    特点 :

    • 基于客户端 IP 地址认证
    • 可以指定单个 IP 或 CIDR 网段(如 ip:19.22.0.0/16)
    • 适合内部网络服务

    6.5 sasl 方案:企业级认证

    sasl(Simple Authentication and Security Layer)认证是 ZooKeeper 提供的最高安全级别的认证方式,基于 JAAS(Java Authentication and Authorization Service)框架,支持 Kerberos 等企业级认证协议 。

    # zoo.cfg 中启用 SASL 认证
    authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
    requireClientAuthScheme=sasl
    jaasLoginRenew=3600000

    # 使用 sasl 认证的 ACL
    setAcl /secure sasl:userA@HADOOP.COM:cdrwa

    七、ACL 的继承规则与注意事项

    7.1 ACL 的继承规则

    ZooKeeper 中,子节点不会自动继承父节点的 ACL。每个节点独立设置自己的 ACL 。

    #mermaid-svg-DMpOz7LQtKkneIGq{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DMpOz7LQtKkneIGq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DMpOz7LQtKkneIGq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DMpOz7LQtKkneIGq .error-icon{fill:#552222;}#mermaid-svg-DMpOz7LQtKkneIGq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DMpOz7LQtKkneIGq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DMpOz7LQtKkneIGq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DMpOz7LQtKkneIGq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DMpOz7LQtKkneIGq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DMpOz7LQtKkneIGq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DMpOz7LQtKkneIGq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DMpOz7LQtKkneIGq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DMpOz7LQtKkneIGq .marker.cross{stroke:#333333;}#mermaid-svg-DMpOz7LQtKkneIGq svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DMpOz7LQtKkneIGq p{margin:0;}#mermaid-svg-DMpOz7LQtKkneIGq .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-DMpOz7LQtKkneIGq .cluster-label text{fill:#333;}#mermaid-svg-DMpOz7LQtKkneIGq .cluster-label span{color:#333;}#mermaid-svg-DMpOz7LQtKkneIGq .cluster-label span p{background-color:transparent;}#mermaid-svg-DMpOz7LQtKkneIGq .label text,#mermaid-svg-DMpOz7LQtKkneIGq span{fill:#333;color:#333;}#mermaid-svg-DMpOz7LQtKkneIGq .node rect,#mermaid-svg-DMpOz7LQtKkneIGq .node circle,#mermaid-svg-DMpOz7LQtKkneIGq .node ellipse,#mermaid-svg-DMpOz7LQtKkneIGq .node polygon,#mermaid-svg-DMpOz7LQtKkneIGq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DMpOz7LQtKkneIGq .rough-node .label text,#mermaid-svg-DMpOz7LQtKkneIGq .node .label text,#mermaid-svg-DMpOz7LQtKkneIGq .image-shape .label,#mermaid-svg-DMpOz7LQtKkneIGq .icon-shape .label{text-anchor:middle;}#mermaid-svg-DMpOz7LQtKkneIGq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DMpOz7LQtKkneIGq .rough-node .label,#mermaid-svg-DMpOz7LQtKkneIGq .node .label,#mermaid-svg-DMpOz7LQtKkneIGq .image-shape .label,#mermaid-svg-DMpOz7LQtKkneIGq .icon-shape .label{text-align:center;}#mermaid-svg-DMpOz7LQtKkneIGq .node.clickable{cursor:pointer;}#mermaid-svg-DMpOz7LQtKkneIGq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DMpOz7LQtKkneIGq .arrowheadPath{fill:#333333;}#mermaid-svg-DMpOz7LQtKkneIGq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DMpOz7LQtKkneIGq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DMpOz7LQtKkneIGq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DMpOz7LQtKkneIGq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DMpOz7LQtKkneIGq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DMpOz7LQtKkneIGq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DMpOz7LQtKkneIGq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DMpOz7LQtKkneIGq .cluster text{fill:#333;}#mermaid-svg-DMpOz7LQtKkneIGq .cluster span{color:#333;}#mermaid-svg-DMpOz7LQtKkneIGq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DMpOz7LQtKkneIGq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DMpOz7LQtKkneIGq rect.text{fill:none;stroke-width:0;}#mermaid-svg-DMpOz7LQtKkneIGq .icon-shape,#mermaid-svg-DMpOz7LQtKkneIGq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DMpOz7LQtKkneIGq .icon-shape p,#mermaid-svg-DMpOz7LQtKkneIGq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DMpOz7LQtKkneIGq .icon-shape rect,#mermaid-svg-DMpOz7LQtKkneIGq .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DMpOz7LQtKkneIGq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DMpOz7LQtKkneIGq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DMpOz7LQtKkneIGq :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    /parentACL: admin:cdrwa

    /parent/child1ACL: world:r

    /parent/child2ACL: auth::cdw

    # 验证继承规则
    [zk: localhost:2181(CONNECTED) 0] create /parent "parent"
    [zk: localhost:2181(CONNECTED) 1] setAcl /parent digest:admin:admin123:cdrwa

    [zk: localhost:2181(CONNECTED) 2] create /parent/child "child"
    [zk: localhost:2181(CONNECTED) 3] getAcl /parent/child
    'world,'anyone
    : cdrwa # 子节点使用默认 ACL,没有继承父节点

    7.2 重要注意事项

    注意事项说明示例
    ACL 不是递归的 父节点的 ACL 不适用于子节点 /app 可被 IP 访问,/app/status 可能对所有人开放
    ADMIN 权限的特殊性 由于没有文件所有者概念,ADMIN 权限在某种意义上指定了"所有者" 只有具有 ADMIN 权限的客户端才能修改 ACL
    隐含的 LOOKUP 权限 所有用户隐式具有 LOOKUP 权限,可以 stat 节点,但不能做其他操作 即使没有 READ 权限,也可以检查节点是否存在
    版本控制 修改 ACL 时需注意 aversion 版本号 使用版本号防止并发修改冲突

    八、最佳实践与安全建议

    8.1 生产环境 ACL 配置清单

    ✅ 禁用 world 认证,除非必要
    ✅ 使用 digest 认证作为默认方案
    ✅ 密码遵循复杂度要求
    ✅ 结合 IP 限制增强安全
    ✅ 开启 SASL 用于高安全场景
    ✅ 审计认证失败日志
    ✅ 定期检查 ACL 配置

    8.2 常见场景配置

    场景推荐 ACL说明
    公共配置 world:anyone:r 所有人可读,不可写
    服务注册 auth::cd 已认证服务可创建删除
    敏感配置 digest:admin:cdrwa 只有管理员可访问
    内部服务 ip:10.0.0.0/8:r 仅内网可读

    8.3 安全审计脚本

    #!/bin/bash
    # audit_zk_acl.sh – 审计 ZooKeeper ACL 配置

    ZK_CLIENT="./zkCli.sh -server localhost:2181"

    echo "===== ZooKeeper ACL 审计报告 ====="
    echo "时间: $(date)"
    echo ""

    # 获取所有节点
    nodes=$(echo "ls /" | $ZK_CLIENT 2>/dev/null | grep -v "WATCHER" | grep -v "Connecting" | tr -d '[],')

    for node in $nodes; do
    echo "节点: $node"

    # 获取 ACL
    acl=$(echo "getAcl $node" | $ZK_CLIENT 2>/dev/null | grep -v "WATCHER" | grep -v "Connecting")

    # 检查是否存在开放权限
    if echo "$acl" | grep -q "world:anyone:cdrwa"; then
    echo "⚠️ 警告: 节点 $node 完全开放 (world:anyone:cdrwa)"
    fi

    # 检查是否有 ADMIN 权限滥用
    if echo "$acl" | grep -q "a"; then
    echo "ℹ️ 节点 $node 包含 ADMIN 权限"
    fi

    echo "ACL: $acl"
    echo "—"
    done

    九、总结

    9.1 ACL 核心要点

    要素说明常用值
    权限 5 种基本操作 c,d,r,w,a
    Scheme 认证方式 world,auth,digest,ip,sasl
    ID 具体标识 anyone,用户名,IP地址,密码哈希

    9.2 实现原理回顾

    #mermaid-svg-gOgyR9BMQkpioQk7{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gOgyR9BMQkpioQk7 .error-icon{fill:#552222;}#mermaid-svg-gOgyR9BMQkpioQk7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gOgyR9BMQkpioQk7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gOgyR9BMQkpioQk7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gOgyR9BMQkpioQk7 .marker.cross{stroke:#333333;}#mermaid-svg-gOgyR9BMQkpioQk7 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gOgyR9BMQkpioQk7 p{margin:0;}#mermaid-svg-gOgyR9BMQkpioQk7 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-gOgyR9BMQkpioQk7 .cluster-label text{fill:#333;}#mermaid-svg-gOgyR9BMQkpioQk7 .cluster-label span{color:#333;}#mermaid-svg-gOgyR9BMQkpioQk7 .cluster-label span p{background-color:transparent;}#mermaid-svg-gOgyR9BMQkpioQk7 .label text,#mermaid-svg-gOgyR9BMQkpioQk7 span{fill:#333;color:#333;}#mermaid-svg-gOgyR9BMQkpioQk7 .node rect,#mermaid-svg-gOgyR9BMQkpioQk7 .node circle,#mermaid-svg-gOgyR9BMQkpioQk7 .node ellipse,#mermaid-svg-gOgyR9BMQkpioQk7 .node polygon,#mermaid-svg-gOgyR9BMQkpioQk7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gOgyR9BMQkpioQk7 .rough-node .label text,#mermaid-svg-gOgyR9BMQkpioQk7 .node .label text,#mermaid-svg-gOgyR9BMQkpioQk7 .image-shape .label,#mermaid-svg-gOgyR9BMQkpioQk7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-gOgyR9BMQkpioQk7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gOgyR9BMQkpioQk7 .rough-node .label,#mermaid-svg-gOgyR9BMQkpioQk7 .node .label,#mermaid-svg-gOgyR9BMQkpioQk7 .image-shape .label,#mermaid-svg-gOgyR9BMQkpioQk7 .icon-shape .label{text-align:center;}#mermaid-svg-gOgyR9BMQkpioQk7 .node.clickable{cursor:pointer;}#mermaid-svg-gOgyR9BMQkpioQk7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gOgyR9BMQkpioQk7 .arrowheadPath{fill:#333333;}#mermaid-svg-gOgyR9BMQkpioQk7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gOgyR9BMQkpioQk7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gOgyR9BMQkpioQk7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gOgyR9BMQkpioQk7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gOgyR9BMQkpioQk7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gOgyR9BMQkpioQk7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gOgyR9BMQkpioQk7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gOgyR9BMQkpioQk7 .cluster text{fill:#333;}#mermaid-svg-gOgyR9BMQkpioQk7 .cluster span{color:#333;}#mermaid-svg-gOgyR9BMQkpioQk7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gOgyR9BMQkpioQk7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gOgyR9BMQkpioQk7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-gOgyR9BMQkpioQk7 .icon-shape,#mermaid-svg-gOgyR9BMQkpioQk7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gOgyR9BMQkpioQk7 .icon-shape p,#mermaid-svg-gOgyR9BMQkpioQk7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gOgyR9BMQkpioQk7 .icon-shape rect,#mermaid-svg-gOgyR9BMQkpioQk7 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gOgyR9BMQkpioQk7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gOgyR9BMQkpioQk7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gOgyR9BMQkpioQk7 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    客户端连接

    添加认证信息 addAuthInfo

    客户端请求操作

    服务端获取节点 ACL

    遍历 ACL 匹配客户端认证

    有匹配项?

    拒绝访问 NoAuth

    权限足够?

    允许操作

    9.3 一句话总结

    ZooKeeper 的 ACL 机制通过 Scheme + ID + Permissions 的三元组结构,结合可插拔的认证方案和节点级的权限控制,提供了灵活精细的访问控制能力,是保障分布式协调服务数据安全的基石。正确理解和应用 ACL,能够有效防止未授权访问,构建安全可靠的分布式系统。

    在这里插入图片描述

    🌺The End🌺点点关注,收藏不迷路🌺

    赞(0)
    未经允许不得转载:171主机测评 » ZooKeeper ACL 权限控制机制深度解析:从原理到实战
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址