zookeeper权限控制详解


本文为 zookeeper客户端shell命令详解中的一部分,由于内容较多,网上一些文章对该部分讨论讲解比较模糊,尤其是auth与digest两种授权模式的介绍部分,所以在此处独立出来讲解。

1、预备知识

zookeeper通过ACL权限控制列表来控制其对znode节点的访问权限。ACL权限与Unix文件系统中的权限控制类似,使用权限位限制指定角色对znode节点的各种操作,本节来详细介绍zookeeper中ACL权限控制。

1.1 权限列表

zookeeper中对znode节点的操作权限主要有以下五种,我们可以通过其简写的任意组合来实现对znode节点的不同权限控制。

名称 简写 权限说明
CREATE c 允许创建当前节点下的字节点
DELETE d 允许删除当前节点下的子节点,仅限下一级
READ r 允许读取节点数据以及显示子节点的列表
WRITE w 允许设置当前节点的数据
ADMIN a 管理员权限,允许设置或读取当前节点的权限列表

1.2 ACL权限特点

Zookeeper权限控制有以下几个特点:

  • 1、zookeeper的权限是基于znode节点的,需要对每个节点设置权限。
  • 2、znode节点支持同时设置多种权限方案和多个权限。当znode有多种权限的时候,只有有一个权限允许当前操作,即可执行当前操作,即多个权限之间为或的关系
  • 3、子节点不会继承父节点的权限,客户端没有权限访问当前节点,但是可以访问当前节点的子节点。
  • 4、使用setAcl命令对节点进行权限设置会覆盖掉原来的权限。

1.3 权限相关命令

zookeeper中权限控制包括以下三个命令。下面我们详细对ACL进行操作的控制进行讲解。

addauth scheme auth 	// 添加认证用户
getAcl [-s] path			// 获取指定节点的权限列表
setAcl [-s] [-v version] [-R] path acl	// 对指定节点设置权限。

2、添加认证用户:addauth

添加认证用户命令

# 通常情况下,schame固定为digest,auth为user:passwd。(目前只接触这种用法)
addauth scheme auth

添加认证用户实例

# 添加第一个认证用户
addauth digest abc:123456
# 添加第二个认证用户,注意:第一个添加的认证用户依然有效。
addauth digest ab:123
# 添加第三个认证用户,注意,单个用户可以有不同的密码,此时三个认证的用户全部同时有效
addauth digest abc:abcdefg

注意问题:

  • 1、认证用户添加完之后,认证将对该回话中添加认证之后的所有操作都有效,一旦回话结束,认证失效。
  • 2、添加认证时不同认证用户可以有不同的密码,多个user:passwd都有效。

待确认问题:addauth处理schame为digest外,可以有其他模式吗?

3、 设置znode节点操作权限命令:SetAcl

设置znode节点操作权限命令:

setAcl [-v version] [-R] path acl	// 对指定节点设置权限。 

设置znode节点选项说明

  • -v : 指定权限版本,即aclVersion,若指定版本与当前节点的ACL版本不一致,修改znode节点权限将失败。
  • -R : 递归设置权限,设置当前节点下的递归子节点的权限为acl,特别注意:权限只有当前拥有的权限有效,而新创建的子节点不会继承该权限
[zk: localhost:2181(CONNECTED) 0] addauth digest 12:12
[zk: localhost:2181(CONNECTED) 1] setAcl -R /test auth::cdrwa
[zk: localhost:2181(CONNECTED) 2] getAcl /test
'digest,'12:xMu76vwz/rplGmbBm31F1J8x7/c=
: cdrwa
[zk: localhost:2181(CONNECTED) 3] getAcl /test/1
'digest,'12:xMu76vwz/rplGmbBm31F1J8x7/c=
: cdrwa
[zk: localhost:2181(CONNECTED) 4] getAcl /test/1/1
'digest,'12:xMu76vwz/rplGmbBm31F1J8x7/c=
: cdrwa
# 特别注意:新创建的节点不会继承父节点的权限。
[zk: localhost:2181(CONNECTED) 5] create /test/2
Created /test/2
[zk: localhost:2181(CONNECTED) 6] getAcl /test/2 
'world,'anyone
: cdrwa

4、 设置节点权限命令中节点权限详解

上述命令set path acl中,acl权限的格式为:schema:id:permission。其中每个角色代表的含义如下:

  • scheme:采用的授权策略,即zk以什么方式进行权限校验。一般常见的授权策略包括:ip、world、auth、digest四种。
  • id:指定在指定模式下授权哪些用户可以对znode有指定权限。对于不同的授权策略,该id的含义也随之而变。
  • Permission:权限,即为指定当前用户可以拥有哪些权限,即为1.4.1.1中5中权限的组合。

下面分别对不同策略下的权限设置进行详细说明:

4.1 world ACL授权策略

world授权策略从字面意义上讲就是世界,即为对于所有人进行赋予权限。在world授权模式下,id的取值只有一种,即为anyone,所以该模式下,其设置权限的命令就固定为:

setAcl /test world:anyone:${permission}

使用实例,该例子中,对节点/test_aworld进行赋予所有人都可以对该节点进行读读取和权限操作:

[zk: localhost:2181(CONNECTED) 11] create /test_aworld
Created /test_aworld
[zk: localhost:2181(CONNECTED) 12] setAcl /test_world world:anyone:ra
Node does not exist: /test_world
[zk: localhost:2181(CONNECTED) 13] setAcl /test_aworld world:anyone:ra
[zk: localhost:2181(CONNECTED) 15] getAcl /test_aworld
'world,'anyone
: ra

注意:创建节点之后,节点的默认权限为所有人都可以对节点进行所有操作,即为world:anyone:cdrwa权限,可创建节点之后进行权限查看:

[zk: localhost:2181(CONNECTED) 16] create /test
Created /test
[zk: localhost:2181(CONNECTED) 17] getAcl /test
'world,'anyone
: cdrwa

4.2 ip ACL授权策略

ip授权策略即为限制指定ip可以对当前节点进行指定操作。在ip授权策略下,id的取值为被赋予权限的IP,我们也可以对节点进行多个ip赋予权限,不同ip权限使用逗号隔开。

[zk: localhost:2181(CONNECTED) 18] create /test_ip
Created /test_ip
# 赋予单个ip节点权限
[zk: localhost:2181(CONNECTED) 19] setAcl /test_ip ip:127.0.0.1:cdrwa
[zk: localhost:2181(CONNECTED) 20] getAcl /test_ip
'ip,'127.0.0.1
: cdrwa
# 赋予多个ip节点权限,权限之间使用逗号隔开
[zk: localhost:2181(CONNECTED) 21] setAcl /test_ip ip:127.0.0.1:cdrwa,ip:127.0.0.2:cdr
[zk: localhost:2181(CONNECTED) 22] getAcl /test_ip
'ip,'127.0.0.1
: cdrwa
'ip,'127.0.0.2
: cdr

4.3 auth ACL授权策略

auth授权策略为给**(1)当前会话中 (2)设置权限之前 (3)所有授权过的所有用户**赋予权限。在当前模式下,权限设置中的id字段为空,如果填写也会被zk忽略。从上面对auth授权策略的解释可以看出,设置auth ACL权限必须要有个前提,即为在设置权限之前需要添加授权认证用户,若没有添加,则设置权限会报错。

[zk: localhost:2181(CONNECTED) 1] create /test_auth auth
Created /test_auth
# 在设置权限之前没有添加认证用户,直接设置权限报错。
[zk: localhost:2181(CONNECTED) 2] setAcl /test_auth auth::cdrwa
Acl is not valid : /test_auth

# 首先添加三个认证用户,注意认证用户可以有不同的密码,相当于有两种身份
[zk: localhost:2181(CONNECTED) 3] addauth digest user1:123
[zk: localhost:2181(CONNECTED) 4] addauth digest user2:123
[zk: localhost:2181(CONNECTED) 5] addauth digest user1:12
[zk: localhost:2181(CONNECTED) 6] setAcl /test_auth auth::cdrwa
[zk: localhost:2181(CONNECTED) 7] getAcl /test_auth 
'digest,'user1:Nv3cjIteQ1W3F6fZb+mYaNSs5rc=
: cdrwa
'digest,'user2:gZ5Cvtv1mYP7pvsOM/1dcB8DgR0=
: cdrwa
'digest,'user1:5JrZvgh2b8BZ0ZjBlnn0pK9h0Ww=
: cdrwa

# 断开当前链接
[zk: localhost:2181(CONNECTED) 8] close
WATCHER::
WatchedEvent state:Closed type:None path:null
[zk: localhost:2181(CLOSED) 9] connect 127.0.0.1:2181
[zk: 127.0.0.1:2181(CONNECTING) 10] 
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
# 访问当前节点,会报错没有权限
[zk: 127.0.0.1:2181(CONNECTED) 10] get /test_auth
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /test_auth

# 添加认证用户之后进行访问,即可有权限操作当前节点。
[zk: 127.0.0.1:2181(CONNECTED) 11] addauth digest user1:123
[zk: 127.0.0.1:2181(CONNECTED) 12] get /test_auth
auth

4.4 digest Acl授权策略

digest 授权策略即为用户名密码的授权策略,也是生产中最常用的一种方式。与auth授权策略不同的是,digest授权策略在设置权限之前不需要添加认证用户,digest中的id为指定可以访问的用户名:密码健值对,其中密码为对(user:明文密码)进行SHA1之后再进行BASE64的到的编码。 同样的,我们也可以对同一个节点设置不同的用户名密码,对不同的用户名密码设置不同的权限,这个有很大的作用,我们可以创建一个管理员用户以及一个guest用户,使用同一个znode节点对外提供服务

要设置digest权限控制,首先需要通过用户和明文密码进行生成密文。生成密文有很多中方式,最简单的就是使用Linux提供的工具进行生成,计算密文方式如下:

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

使用实例

1、首先我们选取w1:test1234作为用户名密码,然后生成密码对应的密文:

[root@VM_centos ~]# echo  -n w1:test1234  | openssl dgst -binary -sha1 | openssl base64
gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=

2、然后我们创建znode节点并对节点进行设置权限。

[zk: localhost:2181(CONNECTED) 1] create /test_digest
Created /test_digest
# 首先对节点设置digest ACL权限
[zk: localhost:2181(CONNECTED) 2] setAcl /test_digest digest:w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=:cdrwa

# 查询当前节点权限,由于当前没有添加回话信息,所以返回认证失败
[zk: localhost:2181(CONNECTED) 3] getAcl /test_digest
Authentication is not valid : /test_digest
# 添加用户认证,再进行权限访问,访问成功。
[zk: localhost:2181(CONNECTED) 4] addauth digest w1:test1234
[zk: localhost:2181(CONNECTED) 5] getAcl /test_digest
'digest,'w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=
: cdrwa

# 同样的 我们可以进行设置多个digest权限,针对不同的用户有不同的权限
[zk: localhost:2181(CONNECTED) 7] setAcl /test_digest digest:w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=:cdrwa,digest:w2:gQXogR4k0JPSqlvthbuiYOnAhAM=:cdra
[zk: localhost:2181(CONNECTED) 8] getAcl /test_digest
'digest,'w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=
: cdrwa
'digest,'w2:gQXogR4k0JPSqlvthbuiYOnAhAM=
: cdra

[zk: localhost:2181(CONNECTED) 9] setAcl /test_digest digest:w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=:cdrwa,digest:w1:gQXogR4k0JPSqlvthbuiYOnAhAM=:cdra
[zk: localhost:2181(CONNECTED) 10] getAcl /test_digest
'digest,'w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=
: cdrwa
'digest,'w1:gQXogR4k0JPSqlvthbuiYOnAhAM=
: cdra

4.5 auth与digest权限控制区别

上面四种授权策略中,ip和world授权方式比较容易理解,但是auth与digest比较容易混淆,网上很多文章也说的不太清楚,所以这里总结一下这两种授权方式的区别。

  • auth授权之前必须在当前会话中添加授权用户,若不添加,设置权限报错;而digest授权方式无需在授权之前添加认证用户
  • auth授权中id为空,如果填写也会被忽略;digest授权id为(用户名:密文)的格式。
  • auth只能针对多个授权用户进行相同权限的赋予;而digest可以自定义不同用户对该节点有不同的权限,在该节点的管理员、普通用户权限设置比较友好。
发布了130 篇原创文章 · 获赞 40 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/u014630623/article/details/103749103