zookeeper ACL權限

原文連接:https://www.jianshu.com/p/392248ab27f4css

對zookeeper設置ACL屬性java

咱們以zkCli爲例,來講明zookeeper對ACL的設置。node

使用zkCli時,ACL的格式由<schema>:<id>:<acl>三段組成。shell

  • schema:能夠取下列值:world, auth, digest, host/ip
  • id: 標識身份,值依賴於schema作解析。
  • acl:就是權限:cdwra分別表示create, delete,write,read, admin

注意:zookeeper對權限的控制是znode級別的,不具備繼承性,即子節點不繼承父節點的權限。這種設計在使用上仍是有缺陷的,由於不少場景下,咱們仍是會把相關資源組織一下,放在同一個路徑下面,這樣就會有對一個路徑統一受權的需求。apache

  1. schema world

這是默認方式,表示沒有認證。當建立一個新的節點(znode),而又沒有設置任何權限時,就是這個值,例如:api

[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屬性,這樣任何人均可以訪問這個節點。ruby

若是要手工設置這個屬性,那麼此時的id域只容許一個值,即anyone,格式以下:bash

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

這種受權不針對任何特色ID,而是對全部已經添加認證的用戶,換句話說,就是對全部已經經過認證的用戶受權。session

用法以下:ide

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集羣裏面被配置成了超級用戶。

相關文章
相關標籤/搜索