原文連接:https://www.jianshu.com/p/392248ab27f4css
對zookeeper設置ACL屬性java
咱們以zkCli爲例,來講明zookeeper對ACL的設置。node
使用zkCli時,ACL的格式由<schema>:<id>:<acl>三段組成。shell
注意:zookeeper對權限的控制是znode級別的,不具備繼承性,即子節點不繼承父節點的權限。這種設計在使用上仍是有缺陷的,由於不少場景下,咱們仍是會把相關資源組織一下,放在同一個路徑下面,這樣就會有對一個路徑統一受權的需求。apache
- 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
- schema auth
這種受權不針對任何特色ID,而是對全部已經添加認證的用戶,換句話說,就是對全部已經經過認證的用戶受權。session
用法以下:ide
addauth digest <user>:<password> setAcl <path> auth:<id>:<acl>
注意:
[zk: localhost:2181(CONNECTED) 0] create /test 'test' [zk: localhost:2181(CONNECTED) 1] setAcl /test auth::crdwa Acl is not valid : /test
舉例:
[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)裏能夠添加多個認證用戶嗎,那驗證的時候按哪個算呢;若是不一樣的用戶有不一樣的受權會致使受權衝突嗎?以誰爲準?
幾點總結:
[zk: localhost:2181(CONNECTED) 1] setAcl /test auth::crdwa Acl is not valid : /test
因此這種受權方式更傾向於用做測試開發環境,而不是產品環境中。
- schema digest
這就是最普通的用戶名:密碼的驗證方式,在通常業務系統中最經常使用。
格式以下:
setAcl <path> digest:<user>:<password(密文)>:<acl>
和schema auth相比,有兩點不一樣:
密碼能夠經過以下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有以下特性:
- schema host/ip
就是客戶機地址,或者是主機名、或者是IP地址。
主機名能夠是單個主機名,也能夠是域名。IP能夠是單個IP地址,也能夠是IP地址段,好比ip:192.168.1.0/16。
這個不細說了,比較簡單,也沒有驗證過。
- 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集羣裏面被配置成了超級用戶。