1. 程式人生 > >Zookeeper節點ACL許可權設定(四)

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

,schema代表授權策略,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

digest:是授權方式 username:BASE64(SHA1(password)):是id部分 cdrwa:許可權部份 使用者名稱+密碼授權訪問方式,也是常用的一種授權策略。id部份是使用者名稱和密碼做sha1加密再做BASE64加密後的組合,比如設定一個節點的使用者名稱為wangsaichao,密碼為123456,則表示方式為: 原:wangsaicaho:BASE64(SHA1(123456)) 正確:wangsaichao:G2RdrM8e0u0f1vNCj/TI99ebRMw=。 密碼加密需要用到zk的一個工具類來生成,如下所示:

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。

  1. CREATE(r):建立子節點的許可權
  2. DELETE(d):刪除節點的許可權
  3. READ(r):讀取節點資料的許可權
  4. WRITE(w):修改節點資料的許可權
  5. 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]