ZooKeeper ACL (Access Control List) access control list

As an important middleware in a distributed architecture, zk usually stores some key information in the form of nodes. By default, all applications can read and write any node. In complex applications, this is not very secure. ZK Use the ACL mechanism to solve access rights problems, see the official website documentation for details: http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#sc_ZooKeeperAccessControl

In general, ZK nodes have 5 operating permissions :

CREATE, READ, WRITE, DELETE, ADMIN are the permissions to add, delete, modify, check, and manage. These five permissions are abbreviated as crwda (ie: the acronym of each word)

Note: Among these 5 kinds of permissions, delete refers to the permission to delete the child node, and the other 4 kinds of permissions refer to the permission to operate the own node.

 

There are 4 ways to authenticate your identity :

world: the default method, which is equivalent to the world's access to
auth: represents an authenticated user (the authorized user in the current context can be added by addauth digest user:pwd in the cli)
digest: that is, user name: password authentication , which is also the most commonly used ip in business systems
: use IP address authentication

 

The Cli command line can be tested like this:

Through the getAcl command, it can be found that the node just created is the authentication method of world and anyone by default, and has all the permissions of cdrwa

 

Keep fiddling:

First add the read-only (r) permission control of user1:+owfoSBn/am19roBPzR1/MfCblE to /test ,

Description: setAcl /test digest:username:password:authority  When setting ACL access rights for a node, the password must be encrypted content, where +owfoSBn/am19roBPzR1/MfCblE=, the corresponding original text is 12345 (as for this ciphertext how It is obtained, which will be mentioned later, and this is ignored here.) After setting Acl, you can pass

getAcl/node path  to view Acl settings

Then when get /test, it prompts that the authentication is invalid, indicating that the access control works. Next:

addauth digest user1:12345  adds an authentication user to the "context", which corresponds to the setting of setAcl just now

Then get /test to get the data

Finally delete /test succeeded! The reason is: the root node/default is world:anyone:crdwa (ie: the world can toss freely), so that is to say, anyone can read, write, create child nodes, manage acl, and Delete the child node (again, the delete permission in the ACL should be understood as the delete permission for the child node)

 

As mentioned just now, in the method of setAcl /path digest, the encrypted value of the password must be entered, which is very inconvenient on the cli console, so the following method is more commonly used:

Pay attention to the boxed part, first add an authentication user with addauth digest user1:12345, and then use setAcl /test  auth :user1: 12345 :r to set permissions, the same effect as before, but the password is entered in plain text here , console mode It is more convenient to enter manually.

 

Alright, unraveling the encryption rules:

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);
}

It is SHA1 encryption, then base64 encoding  

 

Code use:

zookeeper has a very useful client open source project zkclient, the official website address is: http://github.com/zkclient, its latest 0.7-dev already supports ACL (the old version 0.1 does not have this function, so it is recommended to use the latest version ),Instructions:

git clone https://github.com/sgroschupf/zkclient  (pull the code to the local)

Revise

build.gradle found 92 lines

Kill this section, otherwise you will get an error when compiling

Then (windows environment, replace ./gradew with gradlew)

./gradlew test  (test)

./gradlew jars  (compile and generate jar package)

./gradlew install  (install to the local maven repository)  

 

Create a new maven project and refer to the following settings for pom.xml:

  View Code

 

Then write a piece of code to test it:

 

Output result:

复制代码
test-data
Node created successfully!
---------------------
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /test
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /test
test-data
---------------------
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /test
new-data
---------------------
[31,s{'digest,'admin-user:mAlW21Phn07yOvWnKJYq2sCMoZw=}
]
---------------------
Node deleted successfully!
复制代码

From the results of using zkclient, it has the same effect as the cli operation.  

 

最后:关于多级节点之间的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 /path auth: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权限

 

参考文章:
https://ihong5.wordpress.com/2014/07/10/apache-zookeeper-acl-access-control-list-getting-permission-sets/

https://ihong5.wordpress.com/2014/07/24/apache-zookeeper-setting-acl-in-zookeeper-client/

https://ihong5.wordpress.com/2014/06/24/znode-types-and-how-to-create-read-delete-and-write-in-zookeeper-via-zkclient/

http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#sc_ZooKeeperAccessControl

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326981401&siteId=291194637