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。