Zookeeper中的Access Control(ACL)

Access Control在分佈式系統中重要性是毋庸置疑的,今天這篇文章來介紹一下Zookeeper中的Access Control(ACL)。

  • 1. 概述
    傳統的文件系統中,ACL分爲兩個維度,一個是屬組,一個是權限,子目錄/文件默認繼承父目錄的ACL。而在Zookeeper中,node的ACL是沒有繼承關係的,是獨立控制的。Zookeeper的ACL,可以從三個維度來理解:一是scheme; 二是user; 三是permission,通常表示爲scheme:id:permissions, 下面從這三個方面分別來介紹:

    (1)scheme: scheme對應於採用哪種方案來進行權限管理,zookeeper實現了一個pluggable的ACL方案,可以通過擴展scheme,來擴展ACL的機制。zookeeper-3.4.4缺省支持下面幾種scheme:

    • world: 它下面只有一個id, 叫anyone, world:anyone代表任何人,zookeeper中對所有人有權限的結點就是屬於world:anyone的
    • auth: 它不需要id, 只要是通過authentication的user都有權限(zookeeper支持通過kerberos來進行authencation, 也支持username/password形式的authentication)
    • digest: 它對應的id爲username:BASE64(SHA1(password)),它需要先通過username:password形式的authentication
    • ip: 它對應的id爲客戶機的IP地址,設置的時候可以設置一個ip段,比如ip:192.168.1.0/16, 表示匹配前16個bit的IP段
    • super: 在這種scheme情況下,對應的id擁有超級權限,可以做任何事情(cdrwa)

另外,zookeeper-3.4.4的代碼中還提供了對sasl的支持,不過缺省是沒有開啓的,需要配置才能啓用,具體怎麼配置在下文中介紹。

  • sasl: sasl的對應的id,是一個通過sasl authentication用戶的id,zookeeper-3.4.4中的sasl authentication是通過kerberos來實現的,也就是說用戶只有通過了kerberos認證,才能訪問它有權限的node.

(2)id: id與scheme是緊密相關的,具體的情況在上面介紹scheme的過程都已介紹,這裏不再贅述。

(3)permission: zookeeper目前支持下面一些權限:

  • CREATE(c): 創建權限,可以在在當前node下創建child node
  • DELETE(d): 刪除權限,可以刪除當前的node
  • READ(r): 讀權限,可以獲取當前node的數據,可以list當前node所有的child nodes
  • WRITE(w): 寫權限,可以向當前node寫數據
  • ADMIN(a): 管理權限,可以設置當前node的permission
2. 實現
如前所述,在zookeeper中提供了一種pluggable的ACL機制。具體來說就是每種scheme對應於一種ACL機制,可以通過擴展scheme來擴展ACL的機制。在具體的實現中,每種scheme對應一種AuthenticationProvider。每種AuthenticationProvider實現了當前機制下authentication的檢查,通過了authentication的檢查,然後再進行統一的permission檢查,如此便實現了ACL。所有的AuthenticationProvider都註冊在ProviderRegistry中,新擴展的AuthenticationProvider可以通過配置註冊到ProviderRegistry中去。下面是實施檢查的具體實現:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void checkACL(ZooKeeperServer zks, List<acl> acl, int perm,
    List<id> ids) throws KeeperException.NoAuthException {
  if (skipACL) {
    return;
  }
  if (acl == null || acl.size() == 0) {
    return;
  }
  for (Id authId : ids) {
    if (authId.getScheme().equals("super")) {
      return;
    }
  }
  for (ACL a : acl) {
    Id id = a.getId();
    if ((a.getPerms() & perm) != 0) {
      if (id.getScheme().equals("world")
          && id.getId().equals("anyone")) {
        return;
      }   
      AuthenticationProvider ap = ProviderRegistry.getProvider(id
          .getScheme());
      if (ap != null) {
        for (Id authId : ids) {
          if (authId.getScheme().equals(id.getScheme())
              && ap.matches(authId.getId(), id.getId())) {
            return;
          }   
        }   
      }   
    }   
  }
  throw new KeeperException.NoAuthException();
}
</id></acl>
3. server配置
可以通過下面兩種方式把新擴展的AuthenticationProvider註冊到ProviderRegistry:
配置文件:在zookeeper的配置文件中,加入authProvider.$n=$classname即可
JVM參數:啓動Zookeeper的時候,通過-Dzookeeper.authProvider.$n=$classname的方式,把AuthenticaitonProvider傳入
在上面的配置中, $n是爲了區分不同的provider的一個序號,只要保證不重複即可,沒有實際的意義,通常用數字1,2,3等 4. 管理ACL
可以通過zookeeper client來管理ACL, zookeeper的發行包中提供了一個cli工具zkcli.sh,可以通過它來進行acl管理,下面通過一些例子來說明acl管理的基本方法:
zkcli
轉自:小武哥的博客  http://www.wuzesheng.com/?p=2438
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章