• zookeeper ACL权限


    原文链接:https://www.jianshu.com/p/392248ab27f4

    对zookeeper设置ACL属性

    我们以zkCli为例,来说明zookeeper对ACL的设置。

    使用zkCli时,ACL的格式由<schema>:<id>:<acl>三段组成。

    • schema:可以取下列值:world, auth, digest, host/ip
    • id: 标识身份,值依赖于schema做解析。
    • acl:就是权限:cdwra分别表示create, delete,write,read, admin

    注意:zookeeper对权限的控制是znode级别的,不具有继承性,即子节点不继承父节点的权限。这种设计在使用上还是有缺陷的,因为很多场景下,我们还是会把相关资源组织一下,放在同一个路径下面,这样就会有对一个路径统一授权的需求。

    1. schema world

    这是默认方式,表示没有认证。当创建一个新的节点(znode),而又没有设置任何权限时,就是这个值,例如:

    [zk: localhost:2181(CONNECTED) 18] create /noacl 'noacl'
    Created /noacl
    [zk: localhost:2181(CONNECTED) 19] getAcl /noacl
    'world,'anyone
    : cdrwa
    

    看到/noacl的ACL属于就是world schema的,因为它没有设置ACL属性,这样任何人都可以访问这个节点。

    如果要手工设置这个属性,那么此时的id域只允许一个值,即anyone,格式如下:

    setAcl /newznode world:anyone:crdwa
    
    1. schema auth

    这种授权不针对任何特点ID,而是对所有已经添加认证的用户,换句话说,就是对所有已经通过认证的用户授权。

    用法如下:

    addauth digest <user>:<password> 
    setAcl <path> auth:<id>:<acl>
    

    注意:

      1. 比须要先添加认证用户,否则会失败呢。如下所示:
    [zk: localhost:2181(CONNECTED) 0] create /test 'test'
    [zk: localhost:2181(CONNECTED) 1] setAcl /test auth::crdwa
    Acl is not valid : /test
    
      1. setAcl命令中的id域是被忽略的,可以填任意值,或者空串,例如:`setAcl <path> auth::crdwa。因为这个域是忽略的,会把所有已经添加的认证用户都加进来。

    举例:

    [zk: localhost:2181(CONNECTED) 2] addauth digest tom1:tom1
    [zk: localhost:2181(CONNECTED) 3] addauth digest tom2:tom2
    [zk: localhost:2181(CONNECTED) 4] addauth digest tom3:tom3
    [zk: localhost:2181(CONNECTED) 5] setAcl /test auth:tom2:crdwa
    [zk: localhost:2181(CONNECTED) 6] getAcl /test
    'digest,'tom1:ben+k/3JomjGj4mfd4fYsfM6p0A=
    : cdrwa
    'digest,'tom2:2iJM00A7+qkeKdEXt8Bhgq+IACw=
    : cdrwa
    'digest,'tom3:TAZPWLs6IaYRS8mlvcfyCOwyBJ8=
    : cdrwa
    

    这个例子中,我们先添加了三个认证用户tom1,tom2,tom3,然后通过setAcl设置ACL,命令中指定了id为tom2,根据前面的说法,这个id值是被忽略的,写任何值,甚至空值也得到一样的结果。我们看到最后getAcl查询出来的结果包含所有前面添加的三个认证用户。

    补充说明:zkCli的命令addauth digest user:pwd是用来添加当前上下文中的认证用户的:

    addauth digest user1:password1(明文)
    

    其实我不是很理解这个功能,难道在一个会话(session)里可以添加多个认证用户吗,那验证的时候按哪一个算呢;如果不同的用户有不同的授权会导致授权冲突吗?以谁为准?

    几点总结:

    1. auth的id值是无效的,表示给所有认证用户设置acl权限。
      1.1. 认证用户的添加,通过addauth命令(addauth digest <username>:<password>),只在当前会话(session)有效。
    2. 当使用addauth命令添加多个认证用户后,再用auth setAcl来设置acl时,那么所有之前addauth的用户都被会加入到acl中。
    3. 如果在当前会话中还没有认证过的用户就使用auth setAcl来设置acl权限时会失败,前面已经讨论过。
    [zk: localhost:2181(CONNECTED) 1] setAcl /test auth::crdwa
    Acl is not valid : /test
    
    1. 在auth setAcl之后再使用addauth添加的认证用户是没有acl权限的,必须重新执行auth setAcl来设置权限。
    2. 使用addauth添加的认证用户只在当前会话(session)有效,如果此时在另外一个会话中,不添加对应的认证用户,那么就没有相应访问权限的,而且如果再使用auth setAcl来设置acl权限,则会覆盖之前的acl权限信息,而且只会针对当前会话中的认证用户来设置acl权限。

    所以这种授权方式更倾向于用作测试开发环境,而不是产品环境中。

    1. schema digest

    这就是最普通的用户名:密码的验证方式,在一般业务系统中最常用。
    格式如下:

    setAcl <path> digest:<user>:<password(密文)>:<acl>
    

    和schema auth相比,有两点不同:

    1. 第一不需要预先添加认证用户(但是在zkCli访问的时候,肯定还是要添加认证用户的)。
    2. 第二密码是经过sha1及base64处理的密文。

    密码可以通过如下shell的方式生成:

    echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
    

    例如:

    echo -n root:root | openssl dgst -binary -sha1 | openssl base64
    qiTlqPLK7XM2ht3HMn02qRpkKIE=
    

    或者可以使用zookeeper的库文件生成:

    java -cp /zookeeper-3.4.13/zookeeper-3.4.13.jar:/zookeeper-3.4.13/lib/slf4j-api-1.7.25.jar 
      org.apache.zookeeper.server.auth.DigestAuthenticationProvider 
      root:root
    root:root->root:qiTlqPLK7XM2ht3HMn02qRpkKIE=
    

    输出的root:jalRr+knv/6L2uXdenC93dEDNuE=就是传递给setAcl使用的id串。

    setAcl /test2 digest:root:jalRr+knv/6L2uXdenC93dEDNuE=:rwdca
    

    注意,只有通过zkCli.sh设置digest的ACL时id才需要密文,而通过zookeeper的客户端设置digest的ACL时对应的auth数据是明文。这个属于编码实现的问题了。

    和auth比较,digest有如下特性:

    1. setAcl不需要事先添加认证用户。
    2. 授权是针对单个特定用户。
    3. setAcl使用的密码不是明文,是sha1摘要值,无法反推出用户密码内容。
    1. schema host/ip

    就是客户机地址,或者是主机名、或者是IP地址。
    主机名可以是单个主机名,也可以是域名。IP可以是单个IP地址,也可以是IP地址段,比如ip:192.168.1.0/16。
    这个不细说了,比较简单,也没有验证过。

    1. super用户

    设置一个超级用户,这个超级用户的设置必须在zookeeper内部,zookeeper启动之前设置好。在这种scheme情况下,超级用户具有超级权限,可以做任何事情(cdrwa),不需要授权。

    5.1 设置zookeeper环境变量SERVER_JVMFLAGS:

    export SERVER_JVMFLAGS="-Dzookeeper.DigestAuthenticationProvider.superDigest=root:qiTlqPLK7XM2ht3HMn02qRpkKIE="
    

    5.2 重启zookeeper

    创建/test节点,并且设置acl为jerry1用户。

    [zk: localhost:2181(CONNECTED) 0] create /test 'test'
    Created /test
    [zk: localhost:2181(CONNECTED) 1] setAcl /test digest:jerry1:dJJW56m9FIOfUDDHVC5wVWNsFEo=:rwdca
    [zk: localhost:2181(CONNECTED) 2] getAcl /test
    'digest,'jerry1:dJJW56m9FIOfUDDHVC5wVWNsFEo=
    : cdrwa
    

    5.3 添加认证用户tom

    [zk: localhost:2181(CONNECTED) 3] addauth digest tom:tom  
    

    5.4 访问节点/test

    [zk: localhost:2181(CONNECTED) 4] get /test
    Authentication is not valid : /test
    

    这时失败,因为tom用户没有权限。

    5.3 添加认证用户root

    [zk: localhost:2181(CONNECTED) 6] addauth digest root:root
    

    5.4 再次访问节点/test

    [zk: localhost:2181(CONNECTED) 6] get /test
    test
    ...
    

    成功,虽然root也没有在/test的acl列表里面(是有jerry1),但是也能访问,因为root在zookeeper集群里面被配置成了超级用户。

  • 相关阅读:
    Java NIO使用及原理分析(二)(转)
    Java NIO使用及原理分析 (一)(转)
    虚拟机字节码执行引擎
    虚拟机类加载机制
    浅析Java中的final关键字
    java内存模型7-处理器内存模型
    java内存模型6-final
    最小生成树
    有向图的基本算法
    并查集(Union-Find)算法介绍
  • 原文地址:https://www.cnblogs.com/fswhq/p/11959291.html
Copyright © 2020-2023  润新知