Zookeeper 节点权限控制ACL详解

吴德辉
2023-12-01

一:zooKeeper ACL权限控制概述

Zookeeper类似于unix文件系统,节点类比文件,客户端可以删除节点,创建节点,修改节点。Zookeeper可以使用ACL(access control list)访问控制列表来对节点的权限进行控制。

acl权限控制使用:scheme id permission来标志,主要涵盖三个方面:

权限模式(scheme):授权的策略。
权限对象(id):授权的对象。
权限(permission):授予的权限。


Zookeeper acl的特性:
Zookeeper的权限控制是基于znode节点的,需要对每个节点设置权限。
每个znode支持设置多种权限控制方案和多个权限。
子节点不会继承父节点的权限。客户端无法访问某个节点,但是可以访问他的子节点。

权限模式种类:

权限模式种类
模式                                                             描述
world这种模式方法的授权对象只有一个anyone,代表登录到服务器的所有客户端都能对该节点执行某种权限
ip对连接的客户端使用IP地址认证方式进行认证
auth使用以添加认证的用户进行认证
digest使用 用户:密码方式验证


权限的类型:

权限类型
ACL权限类型ACL权限缩写ACL权限描述
readr读取节点及显示子节点列表的权限
writew设置节点数据的权限
createc创建子节点的权限
deleted删除子节点的权限
admina设置该节点ACL权限的权限

        
关于授权的命令:

权限相关命令
命令命令用法命令作用描述
getAclgetAcl /path读取节点的ACL
setAclsetAcl /path acl设置节点的ACL
createcreate /path data acl创建节点时设置acl
addAuthaddAuth scheme auth添加认证用户,类似于登录操作

二:zookeeper ACL权限控制实战

1.查看某个节点权限

getAcl path

[zk: localhost:2181(CONNECTED) 19] create /test_shao/test_node_xx
Created /test_shao/test_node_xx
[zk: localhost:2181(CONNECTED) 20] getAcl /test_shao/test_node_xx 
'world,'anyone
: cdrwa

##这是所有节点的默认acl,表示所有连接到zookeeper 的客户端都能对该节点进行cdrwa操作(即拥有所有权限)

2. 设置/修改 world 权限模式

1)设置或者修改 world 模式权限
[zk: localhost:2181(CONNECTED) 21] setAcl /test_shao/test_node_xx world:anyone:cdra
[zk: localhost:2181(CONNECTED) 22] getAcl /test_shao/test_node_xx 
'world,'anyone
: cdra
#当前设置会覆盖节点之前的权限(注意不要轻易去掉节点的a权限,否则所有人都无法对其进行权限设置)


2)取消 world 权限模式的所有权限
setAcl /test_shao/test_node_xx world:anyone:
#不要在生产环境轻易做该参数

3.设置/修改 ip 权限模式

1) 设置单个ip
[zk: localhost:2181(CONNECTED) 23] getAcl /test_shao/test_node_xx 
'world,'anyone
: cdra
[zk: localhost:2181(CONNECTED) 24] setAcl /test_shao/test_node_xx ip:127.0.0.1:cdrwa
[zk: localhost:2181(CONNECTED) 25] getAcl /test_shao/test_node_xx 
'ip,'127.0.0.1
: cdrwa
##这时只有通过 127.0.0.1 这个ip登录的客户端,才能访问 /test_shao/test_node_xx 节点。同时我们看到之前该节点的 world 模式权限被覆盖掉了。

2) 设置ip地址段
setAcl /test_shao/test_node_xx ip:192.168.1.0/16:cdrwa

4.设置/修改 auth 权限模式

1)设置 auth 权限模式
[zk: localhost:2181(CONNECTED) 26] addauth digest admin:root
[zk: localhost:2181(CONNECTED) 27] getAcl /test_shao/test_node_xx 
'ip,'127.0.0.1
: cdrwa
[zk: localhost:2181(CONNECTED) 29] setAcl /test_shao/test_node_xx auth:admin:cdra
[zk: localhost:2181(CONNECTED) 30] getAcl /test_shao/test_node_xx 
'digest,'admin:0sxEug2Dpm/NpzMPieOlFREd9Ao=
: cdra
##使用 auth 模式前,需要先通过 addauth 命令创建授权用户(admin:后面是密码加密后的字符串),auth权限模式又覆盖了之前的ip模式权限

这时退出重新登录zk后发现没有 /test_shao/test_node_xx 的操作权限,使用授权用户后可以正常操作
[zk: localhost:2181(CONNECTED) 0] get /test_shao/test_node_xx 
Insufficient permission : /test_shao/test_node_xx
[zk: localhost:2181(CONNECTED) 1] addauth digest admin:root
[zk: localhost:2181(CONNECTED) 2] get /test_shao/test_node_xx 
null



5.设置/修改 digest 权限模式

digest授权模式基于账号密码的授权模式,与Auth模式类似,只是他设置权限之前不用使用
addauth digest username:password进行权限用户添加。

直接使用命令 setAcl path digest:username:password:acl 进行授权就行。只是这里的密码要使用加密后的密码,不能使用铭文密码。

可以使用linux命令进行
echo -n username:password | openssl dgst -binary -sha1 | openssl base64 得到加密后的密码,这里的password是铭文密码

[root@ecs-38198 ~]# echo -n admin:root | openssl dgst -binary -sha1 | openssl base64
0sxEug2Dpm/NpzMPieOlFREd9Ao=

[zk: localhost:2181(CONNECTED) 3] delete /test_shao/test_node_xx
[zk: localhost:2181(CONNECTED) 4] create /test_shao/test_node_xx "测试节点内容"
Created /test_shao/test_node_xx
[zk: localhost:2181(CONNECTED) 5] getAcl /test_shao/test_node_xx 
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 6] 
[zk: localhost:2181(CONNECTED) 6] setAcl /test_shao/test_node_xx digest:admin:0sxEug2Dpm/NpzMPieOlFREd9Ao=:cdrwa
[zk: localhost:2181(CONNECTED) 7] getAcl /test_shao/test_node_xx
'digest,'admin:0sxEug2Dpm/NpzMPieOlFREd9Ao=
: cdrwa

##退出重新登录后,发现没有权限操作该节点,需要登录后才有权限操作
zk: localhost:2181(CONNECTED) 0] get /test_shao/test_node_xx 
Insufficient permission : /test_shao/test_node_xx
[zk: localhost:2181(CONNECTED) 1] addauth digest admin:root
[zk: localhost:2181(CONNECTED) 2] get /test_shao/test_node_xx
测试节点内容

6.同时设置多个权限模式

#上面我们发现老的权限模式会被新的权限模式覆盖,如果想设置多种权限模式,可以在 setAcl 时同时指定多种权限模式通过逗号分割
[zk: localhost:2181(CONNECTED) 7] setAcl /test_shao/test_node_xx ip:127.0.0.1:cdrwa,auth:admin:cdrwa,world:anyone:cdrwa,digest:admin:0sxEug2Dpm/NpzMPieOlFREd9Ao=:cdrwa
[zk: localhost:2181(CONNECTED) 8] getAcl /test_shao/test_node_xx 
'ip,'127.0.0.1
: cdrwa
'digest,'admin:0sxEug2Dpm/NpzMPieOlFREd9Ao=
: cdrwa
'world,'anyone
: cdrwa
'digest,'admin:0sxEug2Dpm/NpzMPieOlFREd9Ao=
: cdrwa

8.设置超级权限

Zookeeper管理员会因为某些客户端对某些节点设置了权限,而导致在紧急的情况下无法修改这些节点感到困扰。在这种情况下,管理员可以通过Zookeeper超级用户模式访问这些节点,一旦设置了超级权限访问节点,后续的操作就不需要check ACL了

[zk: localhost:2181(CONNECTED) 4] setAcl /test_shao/test_node_xx world:anyone:r
[zk: localhost:2181(CONNECTED) 5] getAcl /test_shao/test_node_xx 
'world,'anyone
: r
[zk: localhost:2181(CONNECTED) 6] set /test_shao/test_node_xx "新的测试内容"
Insufficient permission : /test_shao/test_node_xx
[zk: localhost:2181(CONNECTED) 7] setAcl /test_shao/test_node_xx world:anyone:cdrwa
Insufficient permission : /test_shao/test_node_xx
##通过上面一通操作后,我们发现我们没有权限写/test_shao/test_node_xx 节点了,这时候怎么办?(还有比如我们使用了auth或者digest 权限模式后,忘记了密码,怎么办?)

这时我们可以设置超级权限,重启zk
1) 在 zkEnv.sh 添加如下行
export SERVER_JVMFLAGS="-Dzookeeper.DigestAuthenticationProvider.superDigest=super:g9oN2HttPfn8MMWJZ2r45Np/LIA= $SERVER_JVMFLAGS"
#这里指定的用户名密码为 super:superpw ,可以通过如下命令生成加密后的密码
[root@ecs-38198 bin]# echo -n super:superpw | openssl dgst -binary -sha1 | openssl base64
g9oN2HttPfn8MMWJZ2r45Np/LIA=

2)执行 zkEnv.sh
sh zkEnv.sh

3)重启 zk
zkServer.sh stop
zkServer.sh start

4)使用超级用户登录zk
[zk: localhost:2181(CONNECTED) 0] getAcl /test_shao/test_node_xx 
'world,'anyone
: r
[zk: localhost:2181(CONNECTED) 1] set /test_shao/test_node_xx "新的测试内容"
Insufficient permission : /test_shao/test_node_xx
[zk: localhost:2181(CONNECTED) 2] addauth digest super:superpw
[zk: localhost:2181(CONNECTED) 3] set /test_shao/test_node_xx "新的测试内容"
[zk: localhost:2181(CONNECTED) 4] get /test_shao/test_node_xx
新的测试内容
[zk: localhost:2181(CONNECTED) 5] setAcl /test_shao/test_node_xx world:anyone:cdrwa
[zk: localhost:2181(CONNECTED) 6] getAcl /test_shao/test_node_xx
'world,'anyone
: cdrwa

#这时我们看到我们可以正常操作节点的内容了,可以重新给该节点添加正确权限,让其他客户端能正常访问

 类似资料: