zookeeper提供简单的ACL功能,用于对某个具体的node做基本的访问控制.比如限制某个用户对/a这个节点只有只读权限.zookeeper的ACL的粒度严格限制在node级别而且对父节点的ACL设置不会被子节点继承,比如设置某用户u1对节点/a有只读权限后并不意味着用户u1对/a/sub_a的节点也是只读.
Note also that an ACL pertains only to a specific znode. In particular it does not apply to children. For example, if /app is only readable by ip:172.16.16.1 and /app/status is world readable, anyone will be able to read /app/status; ACLs are not recursive.
zookeeper的ACL权限控制,可以控制节点的读写操作,保证数据的安全性,Zookeeper ACL权限设置分为3部分组成,分别是:权限模式(Scheme)、授权对象(ID)、权限信息(Permission).最终组成一条例如scheme:id:permission
格式的ACL请求信息。
下面我们具体看一下这 3 部分代表什么意思:
Scheme(权限模式): zookeeper提供下面5种权限模式
- world: 默认,任何人都有权限
- auth: 代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)
- digest: 使用username:password字符串生成MD5哈希,并将其用作ACL ID标识。身份验证是通过明文发送用户名:密码来完成的。当在ACL中使用时,表达式将是用户名:base64编码的SHA1密码摘要。
- ip: 使用客户端主机IP作为ACL ID标识。ACL表达式的形式是addr/bits,其中addr的最有效位与客户端主机IP的最有效位相匹配
- x509
- 授权对象(ID): 授权对象就是说我们要把权限赋予谁,不同的Scheme有相对应的ID类型,对应于 5种不同的权限模式来说,如果我们选择采用IP方式,使用的授权对象可以是一个IP地址或IP地址段;而如果使用Digest,则对应于一个用户名。如果是World模式,是授权系统中所有的用户
权限信息(Permission):权限就是指我们可以在数据节点上执行的操作种类,在 ZooKeeper 中已经定义好的权限有5种:
- 数据节点(c: create)创建权限,授予权限的对象可以在数据节点下创建子节点;
- 数据节点(w: wirte)更新权限,授予权限的对象可以更新该数据节点;
- 数据节点(r: read)读取权限,授予权限的对象可以读取该节点的内容以及子节点的列表信息;
- 数据节点(d: delete)删除权限,授予权限的对象可以删除该数据节点的子节点;
- 数据节点(a: admin)管理者权限,授予权限的对象可以对该数据节点体进行 ACL 权限设置。
代码验证
我们可以使用setAcl
设置ACL也可以使用getAcl
获取ACL信息
world模式
world模式就是任何连上zookeeper的人都有权限进行操作,但是权限是可以变更的,默认为cdrwa
,也就是create
,delete
,read
,write
,admin
.
# 创建一个node
[zk: localhost:2181(CONNECTED) 2] create /world_acl thinktik
Created /world_acl
# 获取ACL信息,也就是默认的ACL信息
[zk: localhost:2181(CONNECTED) 3] getAcl /world_acl
'world,'anyone # 任何人都可以访问
: cdrwa # create,delete,read,write,admin.
# 更新权限为admin,create,delete
[zk: localhost:2181(CONNECTED) 4] setAcl /world_acl world:anyone:acd
#
[zk: localhost:2181(CONNECTED) 5] getAcl /world_acl
'world,'anyone
: cda
# 由于没有read权限,所以尝试读取数据时会报错,提示没有权限
[zk: localhost:2181(CONNECTED) 6] get /world_acl
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /world_acl
IP模式
# 创建一个节点
[zk: localhost:2181(CONNECTED) 0] create /ip_acl thinktik
Created /ip_acl
# 设置权限为只能127.0.0.1可以访问,权限为crwda
[zk: localhost:2181(CONNECTED) 1] setAcl /ip_acl ip:127.0.0.1:crwda
# 查看权限
[zk: localhost:2181(CONNECTED) 2] getAcl /ip_acl
'ip,'127.0.0.1
: cdrwa
# 读取数据
[zk: localhost:2181(CONNECTED) 3] get /ip_acl
thinktik
# 修改权限,去掉read权限
[zk: localhost:2181(CONNECTED) 4] setAcl /ip_acl ip:127.0.0.1:cwda
# 这时无法读取了
[zk: localhost:2181(CONNECTED) 5] get /ip_acl
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /ip_acl
Auth模式
[zk: localhost:2181(CONNECTED) 6] create /auth_acl thinktik
Created /auth_acl
# 增加授权用户,明文用户名和密码
[zk: localhost:2181(CONNECTED) 7] addauth digest user1:password1
# 授予权限
[zk: localhost:2181(CONNECTED) 9] setAcl /auth_acl auth:user1:cdrwa
[zk: localhost:2181(CONNECTED) 10] getAcl /auth_acl
'digest,'user1:XDkd2dsEuhc9ImU3q8pa8UOdtpI=
: cdrwa
# 获取数据
[zk: localhost:2181(CONNECTED) 11] get /auth_acl
thinktik
如果重新连接之后获取会报没权限,需要添加授权用户
[zk: localhost:2181(CONNECTED) 1] get /auth_acl
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /auth_acl
# 需要添加授权用户
[zk: localhost:2181(CONNECTED) 2] addauth digest user1:password1
[zk: localhost:2181(CONNECTED) 3] get /auth_acl
thinktik
剩余的digest和X509我就不详细描述了.
本文原创链接:zookeeper ACL
参考: