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权限描述 |
read | r | 读取节点及显示子节点列表的权限 |
write | w | 设置节点数据的权限 |
create | c | 创建子节点的权限 |
delete | d | 删除子节点的权限 |
admin | a | 设置该节点ACL权限的权限 |
关于授权的命令:
命令 | 命令用法 | 命令作用描述 |
getAcl | getAcl /path | 读取节点的ACL |
setAcl | setAcl /path acl | 设置节点的ACL |
create | create /path data acl | 创建节点时设置acl |
addAuth | addAuth scheme auth | 添加认证用户,类似于登录操作 |
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
#这时我们看到我们可以正常操作节点的内容了,可以重新给该节点添加正确权限,让其他客户端能正常访问