對(duì)zookeeper設(shè)置ACL屬性

對(duì)zookeeper設(shè)置ACL屬性

我們以zkCli為例,來說明zookeeper對(duì)ACL的設(shè)置。

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

  • schema:可以取下列值:world, auth, digest, host/ip
  • id: 標(biāo)識(shí)身份,值依賴于schema做解析。
  • acl:就是權(quán)限:cdwra分別表示create, delete,write,read, admin

注意:zookeeper對(duì)權(quán)限的控制是znode級(jí)別的,不具有繼承性,即子節(jié)點(diǎn)不繼承父節(jié)點(diǎn)的權(quán)限。這種設(shè)計(jì)在使用上還是有缺陷的,因?yàn)楹芏鄨?chǎng)景下,我們還是會(huì)把相關(guān)資源組織一下,放在同一個(gè)路徑下面,這樣就會(huì)有對(duì)一個(gè)路徑統(tǒng)一授權(quán)的需求。

  1. schema world

這是默認(rèn)方式,表示沒有認(rèn)證。當(dāng)創(chuàng)建一個(gè)新的節(jié)點(diǎn)(znode),而又沒有設(shè)置任何權(quán)限時(shí),就是這個(gè)值,例如:

[zk: localhost:2181(CONNECTED) 18] create /noacl 'noacl'
Created /noacl
[zk: localhost:2181(CONNECTED) 19] getAcl /noacl
'world,'anyone
: cdrwa

看到/noacl的ACL屬于就是world schema的,因?yàn)樗鼪]有設(shè)置ACL屬性,這樣任何人都可以訪問這個(gè)節(jié)點(diǎn)。

如果要手工設(shè)置這個(gè)屬性,那么此時(shí)的id域只允許一個(gè)值,即anyone,格式如下:

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

這種授權(quán)不針對(duì)任何特點(diǎn)ID,而是對(duì)所有已經(jīng)添加認(rèn)證的用戶,換句話說,就是對(duì)所有已經(jīng)通過認(rèn)證的用戶授權(quán)。

用法如下:

addauth digest <user>:<password> 
setAcl <path> auth:<id>:<acl>

注意:

    1. 比須要先添加認(rèn)證用戶,否則會(huì)失敗呢。如下所示:
[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。因?yàn)檫@個(gè)域是忽略的,會(huì)把所有已經(jīng)添加的認(rèn)證用戶都加進(jìn)來。

舉例:

[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

這個(gè)例子中,我們先添加了三個(gè)認(rèn)證用戶tom1,tom2,tom3,然后通過setAcl設(shè)置ACL,命令中指定了id為tom2,根據(jù)前面的說法,這個(gè)id值是被忽略的,寫任何值,甚至空值也得到一樣的結(jié)果。我們看到最后getAcl查詢出來的結(jié)果包含所有前面添加的三個(gè)認(rèn)證用戶。

補(bǔ)充說明:zkCli的命令addauth digest user:pwd是用來添加當(dāng)前上下文中的認(rèn)證用戶的:

addauth digest user1:password1(明文)

其實(shí)我不是很理解這個(gè)功能,難道在一個(gè)會(huì)話(session)里可以添加多個(gè)認(rèn)證用戶嗎,那驗(yàn)證的時(shí)候按哪一個(gè)算呢;如果不同的用戶有不同的授權(quán)會(huì)導(dǎo)致授權(quán)沖突嗎?以誰為準(zhǔn)?

幾點(diǎn)總結(jié):

  1. auth的id值是無效的,表示給所有認(rèn)證用戶設(shè)置acl權(quán)限。
    1.1. 認(rèn)證用戶的添加,通過addauth命令(addauth digest <username>:<password>),只在當(dāng)前會(huì)話(session)有效。
  2. 當(dāng)使用addauth命令添加多個(gè)認(rèn)證用戶后,再用auth setAcl來設(shè)置acl時(shí),那么所有之前addauth的用戶都被會(huì)加入到acl中。
  3. 如果在當(dāng)前會(huì)話中還沒有認(rèn)證過的用戶就使用auth setAcl來設(shè)置acl權(quán)限時(shí)會(huì)失敗,前面已經(jīng)討論過。
[zk: localhost:2181(CONNECTED) 1] setAcl /test auth::crdwa
Acl is not valid : /test
  1. 在auth setAcl之后再使用addauth添加的認(rèn)證用戶是沒有acl權(quán)限的,必須重新執(zhí)行auth setAcl來設(shè)置權(quán)限。
  2. 使用addauth添加的認(rèn)證用戶只在當(dāng)前會(huì)話(session)有效,如果此時(shí)在另外一個(gè)會(huì)話中,不添加對(duì)應(yīng)的認(rèn)證用戶,那么就沒有相應(yīng)訪問權(quán)限的,而且如果再使用auth setAcl來設(shè)置acl權(quán)限,則會(huì)覆蓋之前的acl權(quán)限信息,而且只會(huì)針對(duì)當(dāng)前會(huì)話中的認(rèn)證用戶來設(shè)置acl權(quán)限。

所以這種授權(quán)方式更傾向于用作測(cè)試開發(fā)環(huán)境,而不是產(chǎn)品環(huán)境中。

  1. schema digest

這就是最普通的用戶名:密碼的驗(yàn)證方式,在一般業(yè)務(wù)系統(tǒng)中最常用。
格式如下:

setAcl <path> digest:<user>:<password(密文)>:<acl>

和schema auth相比,有兩點(diǎn)不同:

  1. 第一不需要預(yù)先添加認(rèn)證用戶(但是在zkCli訪問的時(shí)候,肯定還是要添加認(rèn)證用戶的)。
  2. 第二密碼是經(jīng)過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的庫(kù)文件生成:

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設(shè)置digest的ACL時(shí)id才需要密文,而通過zookeeper的客戶端設(shè)置digest的ACL時(shí)對(duì)應(yīng)的auth數(shù)據(jù)是明文。這個(gè)屬于編碼實(shí)現(xiàn)的問題了。

和auth比較,digest有如下特性:

  1. setAcl不需要事先添加認(rèn)證用戶。
  2. 授權(quán)是針對(duì)單個(gè)特定用戶。
  3. setAcl使用的密碼不是明文,是sha1摘要值,無法反推出用戶密碼內(nèi)容。
  1. schema host/ip

就是客戶機(jī)地址,或者是主機(jī)名、或者是IP地址。
主機(jī)名可以是單個(gè)主機(jī)名,也可以是域名。IP可以是單個(gè)IP地址,也可以是IP地址段,比如ip:192.168.1.0/16。
這個(gè)不細(xì)說了,比較簡(jiǎn)單,也沒有驗(yàn)證過。

  1. super用戶

設(shè)置一個(gè)超級(jí)用戶,這個(gè)超級(jí)用戶的設(shè)置必須在zookeeper內(nèi)部,zookeeper啟動(dòng)之前設(shè)置好。在這種scheme情況下,超級(jí)用戶具有超級(jí)權(quán)限,可以做任何事情(cdrwa),不需要授權(quán)。

5.1 設(shè)置zookeeper環(huán)境變量SERVER_JVMFLAGS:

export SERVER_JVMFLAGS="-Dzookeeper.DigestAuthenticationProvider.superDigest=root:qiTlqPLK7XM2ht3HMn02qRpkKIE="

5.2 重啟zookeeper

創(chuàng)建/test節(jié)點(diǎn),并且設(shè)置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 添加認(rèn)證用戶tom

[zk: localhost:2181(CONNECTED) 3] addauth digest tom:tom  

5.4 訪問節(jié)點(diǎn)/test

[zk: localhost:2181(CONNECTED) 4] get /test
Authentication is not valid : /test

這時(shí)失敗,因?yàn)閠om用戶沒有權(quán)限。

5.3 添加認(rèn)證用戶root

[zk: localhost:2181(CONNECTED) 6] addauth digest root:root

5.4 再次訪問節(jié)點(diǎn)/test

[zk: localhost:2181(CONNECTED) 6] get /test
test
...

成功,雖然root也沒有在/test的acl列表里面(是有jerry1),但是也能訪問,因?yàn)閞oot在zookeeper集群里面被配置成了超級(jí)用戶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容