zookeeper权限控制 ACL

zookeeper权限控制 ACL

zookeeper类似于文件系统,client可以创建、更新、删除节点。但是如何做到节点的权限控制呢,zookeeper提供了access control list访问控制列表。ACL 权限可以针对节点设置相关读写等权限,保障数据安全性。permissions 可以指定不同的权限范围及角色。

ACL权限控制,通过 [scheme:id:permissions] 来构成权限列表。

  • 权限模式(schema):授权的策略,采用的某种权限机制,包括 world、auth、digest、ip、super 几种。
  • 授权对象(id):授权的对象,代表允许访问的用户
  • 权限(permission):授予的权限,由 cdrwa 组成,其中每个字母代表支持不同权限, 创建权限 create(c)、删除权限 delete(d)、读权限 read(r)、写权限 write(w)、管理权限admin(a)。

ACL特性

  • zookeeper的权限控制是基于每个znode节点的,需要对每个节点设置权限
  • 每个znode支持多种权限控制方案和多个权限
  • 子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点

权限模式

方案 描述
world 只有一个用户:anyone,代表登录zookeeper的所有人(默认)
ip 对客户端使用ip地址认证
auth 使用已添加的用户认证
digest 使用"用户名:密码"方式认证

授权对象 

给谁授予权限,授权对象ID是指权限赋予的实体,例如:IP地址或用户

授予的权限

create、delete、read、writer、admin也就是增、删、改、查、管理权限,这5种权限简写为cdrwa。这5种权限中,delete是指对子节点的删除权限,其他4种权限是指对自身节点的操作权限。

权限 ACL简写 描述
create c 可以创建子节点
delete d 可以删除子节点(仅下一级节点)
read r 可以读取节点数据及显示子节点列表
write w 可以设置节点数据
admin a 可以设置节点访问控制列表权限

授权的相关命令

命令 使用方式 描述
 getAcl  getAcl [-s] path  读取ACL权限
 setAcl  setAcl [-s] [-v version] [-R] path acl  设置ACL权限
 addauth  addauth schema auth  添加认证用户

案例演示

world授权模式

world代表开放式权限,即创建节点的默认权限。

[zk: localhost:2181(CONNECTED) 10] getAcl /node1 
'world,'anyone
: cdrwa
# 删除c权限,创建子节点失败
[zk: localhost:2181(CONNECTED) 12] setAcl /node1 world:anyone:drwa
[zk: localhost:2181(CONNECTED) 14] create /node1/node13 "node13"
Insufficient permission : /node1/node13
# 删除d权限,删除子节点失败
[zk: localhost:2181(CONNECTED) 15] setAcl /node1 world:anyone:rwa
[zk: localhost:2181(CONNECTED) 16] delete /node1/node12
Insufficient permission : /node1/node12
# 删除r权限,获取节点数据失败,且读取子节点列表失败
[zk: localhost:2181(CONNECTED) 17] setAcl /node1 world:anyone:wa
[zk: localhost:2181(CONNECTED) 18] get /node1 
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /node1
[zk: localhost:2181(CONNECTED) 40] ls /node1 
Insufficient permission : /node1
# 删除w权限,修改节点数据失败
[zk: localhost:2181(CONNECTED) 20] setAcl /node1 world:anyone:a
[zk: localhost:2181(CONNECTED) 21] set /node1 "node1234"
Insufficient permission : /node1
# 删除a权限,查看设置权限管理失败
[zk: localhost:2181(CONNECTED) 22] setAcl /node1 world:anyone:
[zk: localhost:2181(CONNECTED) 23] getAcl /node1 
Insufficient permission : /node1

ip授权模式

限制 IP 地址的访问权限

[zk: localhost:2181(CONNECTED) 2] create /node2 "node2"
Created /node2
[zk: localhost:2181(CONNECTED) 3] setAcl /node2 ip:127.0.0.1:crdwa
[zk: localhost:2181(CONNECTED) 4] getAcl /node2 
'ip,'127.0.0.1
: cdrwa
[zk: localhost:2181(CONNECTED) 5] get /node2
node2
[zk: localhost:2181(CONNECTED) 6] setAcl /node2 ip:192.168.126.3:crdwa
[zk: localhost:2181(CONNECTED) 7] getAcl /node2 
Insufficient permission : /node2
# 同时给多个ip地址赋权
[zk: localhost:2181(CONNECTED) 10] setAcl /node3 ip:192.168.126.3:crdwa,ip:127.0.0.1:crdwa
[zk: localhost:2181(CONNECTED) 11] getAcl /node3
'ip,'192.168.126.3
: cdrwa
'ip,'127.0.0.1
: cdrwa

auth授权模式

auth 用于授予权限,注意需要先创建用户。

[zk: localhost:2181(CONNECTED) 16] create /node3
Created /node3
[zk: localhost:2181(CONNECTED) 17] addauth digest user:123456
[zk: localhost:2181(CONNECTED) 18] setAcl /node3 auth:user:123456:cdrwa
[zk: localhost:2181(CONNECTED) 20] getAcl /node3
'digest,'user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=
: cdrwa
[zk: localhost:2181(CONNECTED) 21] get /node3
null
# 退出客户端重新登录
[zk: localhost:2181(CONNECTED) 0] whoami
Auth scheme: User
ip: 127.0.0.1
[zk: localhost:2181(CONNECTED) 1] get /node3
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /node3
[zk: localhost:2181(CONNECTED) 2] addauth digest user:123456
[zk: localhost:2181(CONNECTED) 3] get /node3
null
[zk: localhost:2181(CONNECTED) 4] whoami
Auth scheme: User
digest: user
ip: 127.0.0.1

digest授权模式

digest 可用于账号密码登录和验证,digest和auth有两点区别。一是digest不用进行授权用户的添加,二是digest在授权过程中需要提供加密之后的密码。这里的密码是经过SHA1及BASE64处理的密文,在shell中用以下命令计算:

echo -n wfj:123456 | openssl dgst -binary -sha1 | openssl base64

案例:

# 在shell计算密文
[root@d477dbe7959e ~]# echo -n wfj:123456 | openssl dgst -binary -sha1 | openssl base64
rljj942QO396u5a6EO/22EozxsI=
# 创建节点并赋予digest权限
[zk: localhost:2181(CONNECTED) 1] create /node4 "node4"
Created /node4
[zk: localhost:2181(CONNECTED) 2] setAcl /node4 digest:wfj:rljj942QO396u5a6EO/22EozxsI=:cdrwa
[zk: localhost:2181(CONNECTED) 3] get /node4
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /node4
[zk: localhost:2181(CONNECTED) 4] getAcl /node4
Insufficient permission : /node4
[zk: localhost:2181(CONNECTED) 5] addauth digest wfj:123456
[zk: localhost:2181(CONNECTED) 6] getAcl /node4
'digest,'wfj:rljj942QO396u5a6EO/22EozxsI=
: cdrwa

多种授权模式

同一个节点同时使用多种授权模式

[zk: localhost:2181(CONNECTED) 1] addauth digest wfj:123456
[zk: localhost:2181(CONNECTED) 2] setAcl /node5 ip:127.0.0.1:cdwa,auth:itcast:cdrwa
[zk: localhost:2181(CONNECTED) 3] getAcl /node5
'ip,'127.0.0.1
: cdwa
'digest,'wfj:rljj942QO396u5a6EO/22EozxsI=
: cdrwa

ACL超级管理员

zookeeper的权限管理模式有一种叫做super,该模式提供一个超管可以方便的访问任何权限的节点。例如在忘记密码时,可以通过超管来对节点进行操作。

假设这个超管是: super:admin,需要先为超管生成密码的密文

[root@d477dbe7959e ~]# echo -n super:admin |openssl dgst -binary -sha1 |openssl base64
xQJmxLMiHGwaqBvst5y6rkB6HQs=

找到zookeeper目录下的 bin/zkServer.sh服务器脚本文件,找到如下一行:

root@667afe193621:/apache-zookeeper-3.7.0-bin/bin# cat zkServer.sh | grep -nA3 nohup
164:    nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" 
165-    "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" 
166-    -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p' 
167-    -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &

这就是脚本中启动zookeeper的命令,默认只有以上两个配置项,我们需要加一个超管的配置项

"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs=" 

修改之后这条命令就变成了如下所示:

root@667afe193621:/apache-zookeeper-3.7.0-bin/bin# sed -i '165a    "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs=" \' zkServer.sh
root@667afe193621:/apache-zookeeper-3.7.0-bin/bin# cat zkServer.sh | grep -nA4 nohup
164:    nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" 
165-    "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" 
166-    "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs=" 
167-    -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p' 
168-    -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &

然后重启zookeeper。

create /node6 "node6"
[zk: localhost:2181(CONNECTED) 6] setAcl /node6 ip:192.168.126.1:
[zk: localhost:2181(CONNECTED) 7] ls /node6
Insufficient permission : /node6
[zk: localhost:2181(CONNECTED) 8] addauth digest super:admin
[zk: localhost:2181(CONNECTED) 9] delete /node6
原文地址:https://www.cnblogs.com/jkin/p/14778342.html