11.10.2 访问控制策略与ACL设计

在 ZooKeeper 的安全加固中,访问控制策略需要围绕“最小权限、分层授权、可审计”三原则设计。先明确使用主体与访问边界,将客户端划分为应用、运维、自动化任务与第三方系统等角色,并建立与业务域一致的命名空间与节点层级规划。

文章图片

访问控制模型与权限矩阵#

ACL 权限位含义:读(r)、写(w)、创建(c)、删除(d)、管理(a)。建议以业务目录为边界最小授权。

角色/路径 / /prod/order /prod/order/config /prod/order/lock
安全管理员 a,r,w,c,d a,r,w,c,d a,r,w,c,d a,r,w,c,d
应用账户(app_order) - r,w,c r w,c
运维账户(ops) r r,w,d,a r,w,d,a r,w,d,a
监控账户(monitor) r r r r

说明:锁与选主路径只授予必要写入权限,避免恶意创建导致选主、锁竞争与会话资源耗尽。

ACL 设计与示例(digest + sasl)#

  • digest:适合服务间基础认证
  • sasl:适合企业统一身份(Kerberos)

1) 创建账号并生成 digest#

# 生成 digest 口令(示例)
# 使用 zkCli 的 addauth 方式无需预先生成,但便于审计与脚本化
# 口令格式为 user:password

2) 使用 zkCli 设置 ACL(digest)#

# 连接 ZooKeeper
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181

# 以管理员身份添加认证
addauth digest admin:Admin@123

# 创建业务目录并设置 ACL
create /prod ""
create /prod/order ""
create /prod/order/config ""

# 为 /prod/order 设置多主体 ACL
# admin 拥有所有权限,app_order 拥有 r,w,c
setAcl /prod/order \
  digest:admin:$(echo -n "admin:Admin@123" | openssl dgst -sha1 | awk '{print $2}'):cdrwa,\
  digest:app_order:$(echo -n "app_order:App@123" | openssl dgst -sha1 | awk '{print $2}'):crw

# 验证 ACL
getAcl /prod/order

预期效果:
- /prod/order 仅 admin 与 app_order 可访问
- 其他匿名用户无权限

3) SASL(Kerberos)节点 ACL 示例#

# 假设已配置 JAAS 与 Kerberos(略)
# 在 zkCli 中以 SASL 方式连接
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181 -Djava.security.auth.login.config=/etc/zookeeper/jaas.conf

# 使用 SASL 主体设置 ACL
setAcl /prod/order \
  sasl:zkadmin@EXAMPLE.COM:cdrwa,\
  sasl:app_order@EXAMPLE.COM:crw

安装与落地前置(最小化示例)#

确保启用 ACL 认证支持(示例配置路径):

# /opt/zookeeper/conf/zoo.cfg
# Digest 认证
authProvider.1=org.apache.zookeeper.server.auth.DigestAuthenticationProvider

# SASL 认证
authProvider.2=org.apache.zookeeper.server.auth.SASLAuthenticationProvider

重启服务:

systemctl restart zookeeper

批量审计与整改示例#

清理默认 world:anyone 权限并输出审计报告:

#!/usr/bin/env bash
# /opt/zookeeper/scripts/acl_audit.sh
ZK=127.0.0.1:2181
BASE=/prod

/opt/zookeeper/bin/zkCli.sh -server $ZK <<EOF | awk '/^\/|acl/ {print}'
ls $BASE
getAcl $BASE
# 递归需要脚本扩展,这里演示固定路径
getAcl $BASE/order
getAcl $BASE/order/config
EOF

整改示例(变更窗口执行):

/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181 <<EOF
addauth digest admin:Admin@123
setAcl /prod/order digest:admin:$(echo -n "admin:Admin@123" | openssl dgst -sha1 | awk '{print $2}'):cdrwa
EOF

常见错误与排错#

1) 权限不足

KeeperErrorCode = NoAuth

排查与修复:

# 未添加认证或权限不匹配
addauth digest admin:Admin@123
getAcl /prod/order

2) 节点继承误解
ZooKeeper 节点 ACL 不继承,必须在每个节点上显式设置。

# 需要对子节点逐一设置 ACL
setAcl /prod/order/config ...

3) 误用 world:anyone

# 发现任何 world:anyone:crdwa 立即整改
getAcl /prod/order

练习#

1) 设计并实现 /prod/pay 的 ACL,要求 app_pay 仅能读写本业务目录,监控账户只读。
2) 写一个脚本递归检查 /prod 下是否存在 world:anyone 可写权限并输出问题路径。
3) 用 SASL 身份为 /prod/order/leader 设置仅运维与应用账户可写的 ACL。