Zookeeper節點ACL許可權設定(四)
概述
ACL全稱為Access Control List(訪問控制列表),用於控制資源的訪問許可權。ZooKeeper使用ACL來控制對其znode(ZooKeeper資料樹的資料節點)的訪問。ACL實現與UNIX檔案訪問許可權非常相似:它使用許可權位來允許/禁止針對節點的各種操作以及位應用的範圍。與標準UNIX許可權不同,ZooKeeper節點不受使用者(檔案所有者),組和world(其他)的三個標準範圍的限制。
zk利用ACL策略控制節點的訪問許可權,如節點資料讀寫、節點建立、節點刪除、讀取子節點列表、設定節點許可權等。
在傳統的檔案系統中,一個檔案擁有某個組的許可權即擁有了組裡的所有許可權,檔案或子目錄預設會繼承自父目錄的ACL。而在Zookeeper中,znode的ACL是沒有繼承關係的,每個znode的許可權都是獨立控制的,只有客戶端滿足znode設定的許可權要求時,才能完成相應的操作。Zookeeper的ACL,分為三個維度:scheme、id、permission,通常表示為:scheme:id:permission
一、scheme
scheme即採取的授權策略,每種授權策略對應不同的許可權校驗方式。下面是zk常用的幾種scheme:
- world:預設方式,相當於全世界都能訪問
- auth:不使用任何id,表示任何經過身份驗證的使用者。
- digest:即使用者名稱:密碼這種方式認證,這也是業務系統中最常用的,使用username:password字串生成MD5雜湊,然後將其用作ACL的ID標識。通過以明文形式傳送 例如:wangsaichao:123456 來完成身份驗證。在ACL中使用時,表示式將是wangsaichao:G2RdrM8e0u0f1vNCj/TI99ebRMw=。
- ip:使用Ip地址認證
1> world
語法:world:anyone:cdrwa
建立節點預設的scheme,所有人都可以訪問。如下所示:
## 建立新的節點 /node01
[zk: localhost:2181(CONNECTED) 10] create /node01 234
Created /node01
# 檢視ACL
[zk: localhost:2181(CONNECTED) 11] getAcl /node01
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 12]
2> digest
語法:digest:username:BASE64(SHA1(password)):cdrwa
java -Djava.ext.dirs=/Users/wangsaichao/Desktop/zookeeper-3.4.6/lib -cp /Users/wangsaichao/Desktop/zookeeper-3.4.6/zookeeper-3.4.6.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider wangsaichao:123456
wangsaichao:123456->wangsaichao:G2RdrM8e0u0f1vNCj/TI99ebRMw=
本文的Zookeeper安裝在:/Users/wangsaichao/Desktop/zookeeper-3.4.6
下面是演示建立節點,並新增授權資訊操作節點的示例:
## 檢視/根節點
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper]
## 建立節點/node
[zk: localhost:2181(CONNECTED) 2] create /node 123
Created /node
## 設定許可權
[zk: localhost:2181(CONNECTED) 3] setAcl /node digest:wangsaichao:G2RdrM8e0u0f1vNCj/TI99ebRMw=:cdrwa
cZxid = 0x2
ctime = Sun Sep 09 16:25:51 CST 2018
mZxid = 0x2
mtime = Sun Sep 09 16:25:51 CST 2018
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
## 獲取節點剛剛設定的許可權
[zk: localhost:2181(CONNECTED) 4] getAcl /node
'digest,'wangsaichao:G2RdrM8e0u0f1vNCj/TI99ebRMw=
: cdrwa
## 沒有授權,建立子節點失敗
[zk: localhost:2181(CONNECTED) 5] create /node/child_01 234
Authentication is not valid : /node/child_01
## 為當前session新增授權資訊
[zk: localhost:2181(CONNECTED) 6] addauth digest wangsaichao:123456
## 新增授權資訊後,建立子節點成功
[zk: localhost:2181(CONNECTED) 7] create /node/child_01 234
Created /node/child_01
[zk: localhost:2181(CONNECTED) 8]
3> auth
scheme為auth時,不需要id。說的不需要id,但是還需要使用一個username:password
的expression來表示這個許可權,你也可以理解其實就是id,哈哈.
## 建立一個新的節點 /test_node1
[zk: localhost:2181(CONNECTED) 23] create /test_node1 121
Created /test_node1
## 新增授權賬號
[zk: localhost:2181(CONNECTED) 24] addauth digest zookeeper:zookeeper
## 然後設定節點的ACL
[zk: localhost:2181(CONNECTED) 25] setAcl /test_node1 auth:zookeeper:zookeeper:cdrwa
cZxid = 0x13
ctime = Sun Sep 09 17:46:26 CST 2018
mZxid = 0x13
mtime = Sun Sep 09 17:46:26 CST 2018
pZxid = 0x13
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
## 檢視剛才設定的ACL
[zk: localhost:2181(CONNECTED) 26] getAcl /test_node1
'digest,'zookeeper:4lvlzsipXVaEhXMd+2qMrLc0at8=
: cdrwa
[zk: localhost:2181(CONNECTED) 27]
這裡有一個坑,在使用auth授權時,一定要先執行addauth digest zookeeper:zookeeper然後再授權,否則將使用上一次的授權expression。下面舉個例子。執行多次addauth digest 使用者名稱:密碼 操作,在新的節點設定auth時,將都會生效。具體例子如下:
## 建立一個新的節點 /test_node2
[zk: localhost:2181(CONNECTED) 27] create /test_node2 234
Created /test_node2
## 設定auth授權, 使用一個並不存在的 hello使用者,依然成功了
[zk: localhost:2181(CONNECTED) 28] setAcl /test_node2 auth:hello:hello:cdrwa
cZxid = 0x15
ctime = Sun Sep 09 17:50:10 CST 2018
mZxid = 0x15
mtime = Sun Sep 09 17:50:10 CST 2018
pZxid = 0x15
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
## 檢視ACL 竟然是之前的zookeeper使用者
[zk: localhost:2181(CONNECTED) 29] getAcl /test_node2
'digest,'zookeeper:4lvlzsipXVaEhXMd+2qMrLc0at8=
: cdrwa
## 這個時候新增 hello 使用者
[zk: localhost:2181(CONNECTED) 30] addauth digest hello:hello
## 建立新的節點 /test_node3
[zk: localhost:2181(CONNECTED) 31] create /test_node3 456
Created /test_node3
## 檢視ACL 這個時候還是world
[zk: localhost:2181(CONNECTED) 32] getAcl /test_node3
'world,'anyone
: cdrwa
## 設定auth ACL
[zk: localhost:2181(CONNECTED) 33] setAcl /test_node3 auth:hello:hello:cdrwa
cZxid = 0x17
ctime = Sun Sep 09 17:53:14 CST 2018
mZxid = 0x17
mtime = Sun Sep 09 17:53:14 CST 2018
pZxid = 0x17
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
## 檢視ACL 發現之前的zookeeper使用者也存在
[zk: localhost:2181(CONNECTED) 34] getAcl /test_node3
'digest,'zookeeper:4lvlzsipXVaEhXMd+2qMrLc0at8=
: cdrwa
'digest,'hello:uXpRvPoy9gsHHSCo8uMtZmaXPIA=
: cdrwa
[zk: localhost:2181(CONNECTED) 35]
4> ip
基於客戶端IP地址校驗,限制只允許指定的客戶端能操作znode。 比如,設定某個節點只允許IP為127.0.0.1的客戶端能讀寫該寫節點的資料:ip:127.0.0.1:rw
## 給node節點新增新的ACL許可權
[zk: localhost:2181(CONNECTED) 8] setAcl /node ip:127.0.0.1:cdrwa
cZxid = 0x2
ctime = Sun Sep 09 16:25:51 CST 2018
mZxid = 0x2
mtime = Sun Sep 09 16:25:51 CST 2018
pZxid = 0x5
cversion = 1
dataVersion = 0
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1
## 檢視ACL
[zk: localhost:2181(CONNECTED) 9] getAcl /node
'ip,'127.0.0.1
: cdrwa
[zk: localhost:2181(CONNECTED) 10]
上面主要介紹了平時常用的三種scheme,除此之外,還有host、super、auth授權策略。
二、id
id是驗證模式,不同的scheme,id的值也不一樣。scheme為digest時,id的值為:username:BASE64(SHA1(password)),scheme為ip時,id的值為客戶端的ip地址。scheme為world時,id的值為anyone。scheme為auth時,id為 username:password。
三、permission
znode可以擁有的許可權還記得之前的授權語句,如: digest:username:BASE64(SHA1(password)):cdrwa中的cdrwa即是permission。
CREATE(r)
:建立子節點的許可權DELETE(d)
:刪除節點的許可權READ(r)
:讀取節點資料的許可權WRITE(w)
:修改節點資料的許可權ADMIN(a)
:設定子節點許可權的許可權
示例
## 先在當前session中新增 wangsaichao:123456 使用者
[zk: localhost:2181(CONNECTED) 35] addauth digest wangsaichao:123456
## 建立一個新的節點,並新增digest ACL(只能建立和刪除) 因為是digest 所以密碼為加密之後的
[zk: localhost:2181(CONNECTED) 36] create /test_node5 123 digest:wangsaichao:G2RdrM8e0u0f1vNCj/TI99ebRMw=:cd
Created /test_node5
## 沒有WRITE許可權, 設定節點資料 失敗
[zk: localhost:2181(CONNECTED) 37] set /test_node5 234
Authentication is not valid : /test_node5
## 沒有ADMIN許可權,設定ACL失敗
[zk: localhost:2181(CONNECTED) 38] setAcl /test_node5 auth:wangsaichao:123456:cdrwa
Authentication is not valid : /test_node5
## 沒有READ許可權, 讀取節點 失敗
[zk: localhost:2181(CONNECTED) 39] get /test_node5
Authentication is not valid : /test_node5
## 具備CREATE許可權,建立子節點成功
[[zk: localhost:2181(CONNECTED) 40] create /test_node5/child_01 123
Created /test_node5/child_01
## 具備DELETE許可權,可以刪除子節點
[zk: localhost:2181(CONNECTED) 41] delete /test_node5/child_01
[zk: localhost:2181(CONNECTED) 42]