ZooKeeper zkclient ACL 访问控制列表

存在的必要性

zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机制来解决访问权限问题,详见官网文档:http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#sc_ZooKeeperAccessControl

设计架构

acl 通过 [scheme:id:permissions] 构成

 

ZK的节点有5种操作权限:

权限组合字符串

缩写 crdwa 
CREATE:创建子节点 
READ:获取节点、子节点 
WRITE:设置节点数据 
DELETE:删除子节点 
ADMIN:设置权限

注:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限

 

4种身份的认证方式:

  • world: world下只有一个 id,即只有一个用户,也就是 anyone,组合写法为:world:anyone:[permissions]
  • auth: 代表认证登录,需要注册用户有权限,形式为:auth:user:password:[permissions],(作用: 1: 通过addauth digest user:pwd 来认证用户,2 :可以在1之后,设置节点acl权限使用。)
  • digest: 需要对密码加密才能访问,digest:username:BASE64(SHA1(password)):[permissions] 
    QQ截图20180713085219.png

  • ip: 设置为指定的 ip,此时对 ip 访问进行限制,ip:192.168.1.1:[permissions]

  • super: 代表超级管理员,拥有所有的权限

id: 认证对象

对象: 根据schema 的不同而不同。

IP对象 :ip:192.168.1.1

auth 对象: auth:user1:pass1

digest 对象  digest:user1 :base64(sha1("pass1"))

 

测试示例:

测试功能点:1默认所有的节点都是world:anyone 的访问控制权限。

Cli命令行下可以这样测试:

通过getAcl命令可以发现,刚创建的节点,默认是 world,anyone的认证方式,具有cdrwa所有权限

测试功能点:2 可以通过setAcl 设置权限 ,getAcl 获取权限,获取权限得到的秘钥都是加密过的。设置权限之后,get 方法获取某个path 下的数据,就需要 先认证再获取了,认证是通过addauth 命令实现的。

先给/test增加了user1:+owfoSBn/am19roBPzR1/MfCblE的只读(r)权限控制,

说明:setAcl /test digest:用户名:密码:权限 给节点设置ACL访问权限时,密码必须是加密后的内容,这里的+owfoSBn/am19roBPzR1/MfCblE=,对应的原文是12345 (至于这个密文怎么得来的,后面会讲到,这里先不管这个),设置完Acl后,可以通过

getAcl /节点路径 查看Acl设置

然后get /test时,提示认证无效,说明访问控制起作用了,接下来:

addauth digest user1:12345 给"上下文"增加了一个认证用户,即对应刚才setAcl的设置

然后再 get /test 就能取到数据了

最后 delete /test 成功了!原因是:根节点/默认是world:anyone:crdwa(即:全世界都能随便折腾),所以也就是说任何人,都能对根节点/进行读、写、创建子节点、管理acl、以及删除子节点(再次映证了ACL中的delete权限应该理解为对子节点的delete权限)

测试功能点:3  setAcl /path digest这种方式,必须输入密码加密后的值,这在cli控制台上很不方便,所以可以先认证上下文,然后使用 setacl path 明文权限   做权限设置。

注意加框的部分,先用addauth digest user1:12345 增加一个认证用户,然后用 setAcl /test auth:user1:12345:r 设置权限,跟刚才的效果一样,但是密码这里输入的是明文,控制台模式下手动输入更方便。

 

加密规则

 

好了,揭开加密规则:

1

2

3

4

5

6

7

static public String generateDigest(String idPassword)

        throws NoSuchAlgorithmException {

    String parts[] = idPassword.split(":"2);

    byte digest[] = MessageDigest.getInstance("SHA1").digest(

            idPassword.getBytes());

    return parts[0] + ":" + base64Encode(digest);

}

就是SHA1加密,然后base64编码  

 

权限控制和目录的关系

最后:关于多级节点之间的ACL,并非继承关系,但是也有些一联系,这是初次接触ACL中比较难理解的地方:

从这张图上可以发现,子节点/a/b的控制权限范围(全世界都能做任何事)可以超出父节点的范围(仅限:user-a:pwd:a具有read/admin权限)

继续,看上面的这4条红线标注的地方,从上向下一个个解释:

红线1:因为/a只有user-a:pwd-a有ra权限,即:没用户具有c(create)权限,所以不能创建子节点

红线2:因为/a/b为world:anyone:cdrwa权限,即无限制,所以在/a/b下创建子节点b1,地球人已经无法阻止,创建成功

红线3:给/a/b/b1指定了user-b1:pwd-b1的da权限(即:delete+admin)

(注:重温下前面提到的setAcl 二种模式,

一种是setAcl /path digest:username:encrypedpwd:crwda 用这种方式时,encrypedpwd用户必须是密文,

另一种方式是先addauth digest:usrname:password 先把授权信息加入上下文,这里password用的是明文,然后再setAcl /pathauth:username:password:crdwa

所以如果在cli控制台测试,强烈建议用第二种方式,否则象上图中的方式用错了方式,pwd-b1在zk中被认为是密文,要解密出来几乎不可能,所以设置后,相当于这个节点就废了,因为你不知道密码,要操作该节点时,提供不了正确的认证信息)

红线4:还是刚才的理由,因为/a/b为world:anyone:cdrwa,没有限制,所以删除其下的子节点不受阻挡。

从上图可以看出,无法get父节点的内容,但是可以get子节点的内容,再次说明父、子节点的权限没直接关系,但是做delete时,上面的例子却遇到了麻烦:

想删除/a/b时,由于父节点/a的ACL列表里,只有ra权限,没有d权限,所以无法删除子节点。想删除/a时,发现下面还有子节点b,节点非空无法删除,所以这个示例就无解了(因为根据前面的操作,密码也还原不出来,也就无法修改ACL属性),而根节点/也无法删除,解决办法,只能到data目录里清空所有数据,再重启zk,但是这样就相当于所有数据全扔了,所以在设计ACL时,对于delete权限,要谨慎规划,在测试zk集群上做好测试,再转到生产环境操作。

最后给一些权限组合的测试结果:

要修改某个节点的ACL属性,必须具有read、admin二种权限

要删除某个节点下的子节点,必须具有对父节点的read权限,以及父节点的delete权限

 

ACL 使用场景

  1. 开发、测试环境分离,开发者无权操作测试库节点
  2. 生产环境控制指定 ip 的服务可以访问相关节点,防止混乱

java 实现:

注意zk 连接之后,做了一个权限认证,这个认证可以保证后续所有操作都是OK的

 

java权限扩展

尽管ZooKeeper已经为我们提供了上述的四种权限模式,同时也提供给我们能够自定义自己权限的方式——实现接口 
org.apache.zookeeper.server.auth.AuthenticationProvider 
- 启动参数配置 
在ZooKeeper启动参数中配置类似于如下的系统属性 
-Dzookeeper.authProvider.1=com.zkbook.CustomAuthenticationProvider 
- 配置文件配置 
在zoo.cfg配置文件中配置类似于如下的配置项 
authProvider.1=com.zkbook.CustomAuthenticationProvider

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值