1. 程式人生 > >Zookeeper的API操作以及ACL許可權

Zookeeper的API操作以及ACL許可權

Zookeeper的ACL許可權

1. ACL的簡介

首先說明一下為什麼需要ACL

  簡單來說 :在通常情況下,zookeeper允許未經授權的訪問,因此在安全漏洞掃描中暴漏未授權訪問漏洞。這在一些監控很嚴的系統中是不被允許的,所以需要ACL來控制權限.

接下來貼出來的截圖是:實際環境中網路檢測出來需要整改的zookeeper漏洞
下圖是一個實際遇到的需求

既然需要ACL來控制權限,那麼Zookeeper的許可權有哪些呢?

許可權包括以下幾種:

CREATE: 能建立子節點
READ:能獲取節點資料和列出其子節點
WRITE: 能設定節點資料
DELETE: 能刪除子節點
ADMIN:
能設定許可權

說到許可權,就要介紹一下zookeeper的認證方式:

包括以下四種:

world:預設方式,相當於全世界都能訪問
auth:代表已經認證通過的使用者(cli中可以通過addauth digest user:pwd 來添加當前上下文中的授權使用者)
digest:即使用者名稱:密碼這種方式認證,這也是業務系統中最常用的
ip:使用Ip地址認證

ACL基本介紹就到這裡

2. 沒有ACL認證時zookeeper的操作

直接上程式碼 : 更改一下伺服器地址和埠號即可!

import java.io.IOException;

import org.apache.zookeeper.CreateMode;
import
org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper; public class ZkConn { public static void main(String[] args) throws IOException, KeeperException, InterruptedException { /** * 建立一個與伺服器的連線 * 引數一:伺服器地址和埠號(該埠號值伺服器允許客戶端連線的埠號) * 引數二:連線會話超時時間 * 引數三:觀察者,連線成功會觸發該觀察者。不過只會觸發一次。 * 該Watcher會獲取各種事件的通知 */
ZooKeeper zk = new ZooKeeper("node005:4180", 60000, new Watcher() { // 監控所有被觸發的事件 public void process(WatchedEvent event) { System.out.println("監控所有被觸發的事件:EVENT:" + event.getType()); } }); System.out.println("*******************************************************"); // 檢視根節點的子節點 System.out.println("檢視根節點的子節點:ls / => " + zk.getChildren("/", true)); System.out.println("*******************************************************"); // 建立一個目錄節點 if (zk.exists("/node", true) == null) { /** * 引數一:路徑地址 * 引數二:想要儲存的資料,需要轉換成位元組陣列 * 引數三:ACL訪問控制列表(Access control list), * 引數型別為ArrayList<ACL>,Ids介面提供了一些預設的值可以呼叫。 * OPEN_ACL_UNSAFE This is a completely open ACL * 這是一個完全開放的ACL,不安全 * CREATOR_ALL_ACL This ACL gives the * creators authentication id's all permissions. * 這個ACL賦予那些授權了的使用者具備許可權 * READ_ACL_UNSAFE This ACL gives the world the ability to read. * 這個ACL賦予使用者讀的許可權,也就是獲取資料之類的許可權。 * 引數四:建立的節點型別。列舉值CreateMode * PERSISTENT (0, false, false) * PERSISTENT_SEQUENTIAL (2, false, true) * 這兩個型別建立的都是持久型型別節點,回話結束之後不會自動刪除。 * 區別在於,第二個型別所建立的節點名後會有一個單調遞增的數值 * EPHEMERAL (1, true, false) * EPHEMERAL_SEQUENTIAL (3, true, true) * 這兩個型別所建立的是臨時型型別節點,在回話結束之後,自動刪除。 * 區別在於,第二個型別所建立的臨時型節點名後面會有一個單調遞增的數值。 * 最後create()方法的返回值是建立的節點的實際路徑 */ zk.create("/node", "conan".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println("建立一個目錄節點:create /node conan"); /** * 檢視/node節點資料,這裡應該輸出"conan" * 引數一:獲取節點的路徑 * 引數二:說明是否需要觀察該節點,設定為true,則設定共享預設的觀察器 * 引數三:stat類,儲存節點的資訊。例如資料版本資訊,建立時間,修改時間等資訊 */ System.out.println("檢視/node節點資料:get /node => " + new String(zk.getData("/node", false, null))); /** * 檢視根節點 * 在此檢視根節點的值,這裡應該輸出上面所建立的/node節點 */ System.out.println("檢視根節點:ls / => " + zk.getChildren("/", true)); } System.out.println("*******************************************************"); // 建立一個子目錄節點 if (zk.exists("/node/sub1", true) == null) { zk.create("/node/sub1", "sub1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println("建立一個子目錄節點:create /node/sub1 sub1"); // 檢視node節點 System.out.println("檢視node節點:ls /node => " + zk.getChildren("/node", true)); } System.out.println("*******************************************************"); /** * 修改節點資料 * 修改的資料會覆蓋上次所設定的資料 * setData()方法引數一、引數二不多說,與上面類似。 * 引數三:數值型。需要傳入該介面的數值型別版本號!!! * 該資訊可以通過Stat類獲取,也可以通過命令列獲取。 * 如果該值設定為-1,就是忽視版本匹配,直接設定節點儲存的值。 */ if (zk.exists("/node", true) != null) { zk.setData("/node", "changed".getBytes(), -1); // 檢視/node節點資料 System.out.println("修改節點資料:get /node => " + new String(zk.getData("/node", false, null))); } System.out.println("*******************************************************"); // 刪除節點 if (zk.exists("/node/sub1", true) != null) { zk.delete("/node/sub1", -1); zk.delete("/node", -1); // 檢視根節點 System.out.println("刪除節點:ls / => " + zk.getChildren("/", true)); } // 關閉連線 zk.close(); } }

以下是程式碼的執行結果 :
(程式執行開始控制檯打印出來的很多日誌資訊就不一一截取了)

2018-05-22 08:41:14,942 INFO  [main-SendThread(node005:4180)] zookeeper.ClientCnxn (ClientCnxn.java:logStartConnect(975)) - Opening socket connection to server node005/192.168.1.54:4180. Will not attempt to authenticate using SASL (unknown error)
2018-05-22 08:41:14,944 INFO  [main-SendThread(node005:4180)] zookeeper.ClientCnxn (ClientCnxn.java:primeConnection(852)) - Socket connection established to node005/192.168.1.54:4180, initiating session
2018-05-22 08:41:15,007 INFO  [main-SendThread(node005:4180)] zookeeper.ClientCnxn (ClientCnxn.java:onConnected(1235)) - Session establishment complete on server node005/192.168.1.54:4180, sessionid = 0x36010c48e1200017, negotiated timeout = 40000
監控所有被觸發的事件:EVENT:None
檢視根節點的子節點:ls / => [super, kaishuntest1, testWatch, zookeeper, kaishuntest, zks10000000041, demo, hbase, kaishun]
*******************************************************
監控所有被觸發的事件:EVENT:NodeCreated
監控所有被觸發的事件:EVENT:NodeChildrenChanged
建立一個目錄節點:create /node conan
檢視/node節點資料:get /node => conan
檢視根節點:ls / => [super, kaishuntest1, node, testWatch, zookeeper, kaishuntest, zks10000000041, demo, hbase, kaishun]
*******************************************************
監控所有被觸發的事件:EVENT:NodeCreated
建立一個子目錄節點:create /node/sub1 sub1
檢視node節點:ls /node => [sub1]
*******************************************************
監控所有被觸發的事件:EVENT:NodeDataChanged
修改節點資料:get /node => changed
*******************************************************
監控所有被觸發的事件:EVENT:NodeDeleted
監控所有被觸發的事件:EVENT:NodeChildrenChanged
監控所有被觸發的事件:EVENT:NodeChildrenChanged
刪除節點:ls / => [super, kaishuntest1, testWatch, zookeeper, kaishuntest, zks10000000041, demo, hbase, kaishun]
2018-05-22 08:41:15,178 INFO  [main] zookeeper.ZooKeeper (ZooKeeper.java:close(684)) - Session: 0x36010c48e1200017 closed
2018-05-22 08:41:15,178 INFO  [main-EventThread] zookeeper.ClientCnxn (ClientCnxn.java:run(512)) - EventThread shut down

從這裡面可以看到,在沒有進行任何設定的前提下,所有的操作都時被允許的!

3.接下來開始新增ACL認證

a. 首先進入到zookeeper
在zookeeper安裝目錄下的bin目錄執行 : 
zkCli.sh -server 192.168.1.54:4180 // 伺服器地址 : zookeeper埠號(預設2181)
b. 沒有新增ACL認證的節點資訊
create /test // 建立一個進行ACL認證測試的節點
getAcl /test // 獲取該節點資訊
控制檯輸出 :
'world,'anyone
: cdrwa
// 從結果來看,結合之前的介紹來看,新建立的節點預設是全世界都可以訪問,並且具有全部的5種許可權的.
c. 新增ACL認證
create /test 'test-data' //建立節點 
addauth digest xmr:123456 //增加一個認證使用者  格式 addauth digest 使用者名稱:密碼
 setAcl /test auth:xmr:123456:r //對新增加的使用者設定許可權,r代表只讀許可權
 getAcl /test //獲取節點資訊

這裡寫圖片描述
從控制檯的輸出可以看到,密碼已經被加密,加密規則如下:

static public String generateDigest(String idPassword)
        throws NoSuchAlgorithmException {
    String parts[] = idPassword.split(":", 2);
    byte digest[] = MessageDigest.getInstance("SHA1").digest(
            idPassword.getBytes());
    return parts[0] + ":" + base64Encode(digest);
}

SHA1加密,然後base64編碼

這個時候我們來試驗一下對剛剛的節點進行非讀取操作

set /test nihao // 向該節點裡面寫入資料(如果該節點存在資料,此操作為修改資料)
控制檯返回如下 :
Authentication is not valid : /test // 說明我們配置的ACL認證已經生效

* 剛剛介紹的API操作再走一發,這次只列出部分程式碼*

   if (zk.exists("/test", true) != null) {
         zk.setData("/test", "ACL認證".getBytes(), -1);
         // 檢視/node節點資料
         System.out.println("修改節點資料:get /test => "
                 + new String(zk.getData("/test", false, null)));
     }
     System.out.println("*******************************************************");

嘗試修改,test節點的資料, 之前怎麼做都是沒問題的,現在呢?

控制檯輸出結果如下:
Exception in thread "main" org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /test
    at org.apache.zookeeper.KeeperException.create(KeeperException.java:113)
    at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
    at org.apache.zookeeper.ZooKeeper.setData(ZooKeeper.java:1270)
    at mastercom.cn.zookeeper.ZkConn.main(ZkConn.java:94)

可見,ACL許可權設定的作用就在這兒了!

注意事項:
要修改某個節點的ACL屬性,必須具有read、admin二種許可權。
要刪除某個節點下的子節點,必須具有對父節點的read許可權,以及父節點的delete許可權。

遇到的問題 :

在本地叢集,以及程式碼測試 : 設定的ACL認證確實有效,成功的避免了一些使用者對於zookeeper的任意操作!
但是在實際中,遇到了巨大的問題!
由於現場的叢集配置的是高可用的,zookeeper下面有如下節點 :

zookeeper,hadoop-ha,spark等等

對叢集下面所有節點 都設定了ACL許可權認證之後,叢集的啟動直接報錯!叢集徹底爆炸!

嘗試了各種各樣的辦法都宣告失敗之後,使用通過zookeeper超級使用者模式訪問這些節點,我們修改了zookeeper的zookeeper.DigestAuthenticationProvider.superDigest引數。

在zkServer.sh配置啟動引數:

nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:g9oN2HttPfn8MMWJZ2r45Np/LIA=" \

提示 : /nohup 找到該位置, 然後新增進去即可
重要的是新增下圖中的這一行!!!這裡的super: 後面跟的是:superpw的密文
新增後的結果如下所示:
重啟zookeeper之後,執行:

addauth digest super:superpw //新增超級使用者,設定密碼superpw(對應於: g9oN2HttPfn8MMWJZ2r45Np/LIA=")

將zookeeper下面的所有節點: 設定為

'world,'anyone
: cdrwa
命令如下 : 
setAcl /testAcl world:anyone:cdrwa //將該節點設定為最高許可權!

然後重啟叢集, 問題得到解決!!!
ACL認證的正確使用方式 還需要繼續研究!
參考的部落格連結

相關推薦

Zookeeper的API操作以及ACL許可權

Zookeeper的ACL許可權 1. ACL的簡介 首先說明一下為什麼需要ACL 簡單來說 :在通常情況下,zookeeper允許未經授權的訪問,因此在安全漏洞掃描中暴漏未授權訪問漏洞。這在一些監控很嚴的系統中是不被允許的,所以需要A

zookeeper相關create以及ACL許可權

客戶端 初始化zookeeper 建立zookeeper節點 api: create(final String path, byte data[], List<ACL> acl, CreateMode create

centos7用戶、組以及acl權限的操作

gin 附加 家目錄 切換 groupdel centos7 txt passwd user 用戶:a. 添加用戶: useradd lee #添加用戶,並建立家目錄 useradd lee -s /sbin/nologin -M #添加用戶,禁止登錄,沒有家

使用Java API、Curator操作zookeeper的acl許可權

zk原生api操作acl許可權 預設匿名許可權 ZooKeeper提供瞭如下幾種驗證模式(scheme): digest:Client端由使用者名稱和密碼驗證,譬如user:password,digest的密碼生成方式是Sha1摘要的base64形式 auth:不使用任何id

檔案許可權以及acl設定

下面的是檔案許可權的管理 ll 檢視檔案drwxrwxrwx. 2 root root 4096 Apr  7 20:14 ckd ls -l d   rwxr-xr-x  3 kiosk kiosk  33 Aug 27 09:47 directory/file [1]

Python中集合(set)的基本操作以及一些常見的用法

python set 集合 集合的一些常見用法 Python除了List、Tuple、Dict等常用數據類型外,還有一種數據類型叫做集合(set),集合的最大特點是:集合裏邊的元素是不可重復的並且集合內的元素還是無序的,所以一般情況下集合常用的兩個場景是:1.去重(如:列表去重);2.關

Python中time模塊和datetime模塊的常用操作以及幾種常用時間格式間的轉換

pyrhon time datatime 幾種常用時間格式的轉換 最常見以及常用的幾種時間格式 1、時間戳(timestamp),時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。 2、時間元組(struct_time),共有九個元素組。 3、格式化時間(fo

Tomcat和myeclipse的相關操作以及myeclipse的激活方法

java部署WEB應用:1、創建應用目錄2、創建WEB-INF3、Classes、lib、web、xml(examples)4、創建Servlet:A、創建類 implements ServletB、Service(request,response)C、實現代碼5、編譯ServletJavac -d . h

關於利用PHP訪問MySql數據庫的邏輯操作以及增刪改查實例操作

自增 刪除 nbsp bsp 增刪 sso 成員 執行 ech PHP訪問MySql數據庫 <?php //造連接對象$db = new MySQLi("localhost","root","","0710_test");//寫SQL語句$sql = "select

C#多線程の遇見長耗時操作以及多任務

reat obj let zed when local ade counter args 4.0用 Task.Factory.StartNew(()=>{});4.0以下用 ThreadPool.QueueUserWorkItem(()=>{}

交換機、路由器以及acl、DHCP的應用實例

配置ip des pan 獲取 water 開啟 static stat tina 實驗名稱:交換機、路由器以及acl、DHCP的應用實例要求:拓撲:配置:sw1創建VLAN 10 2001口加入VLAN10,並給VLAN10 配置網關 192.168.10.25402、0

在eclipse中使用github進行代碼的上傳操作以及如何建立分支

默認 java github 根據 最好 建立 右擊 遠程 gpo Eclipse或STS對github進行基本操作 一.Github上傳代碼 1. 首先新建一個maven或者其他java項目。 接著把本地默認的git存放項目地址改變一下。 以上git項目存放地址

『MXNet』第一彈_基礎操作以及常見層實現

sco 交叉熵 tor 內存數據 softmax war 反向 shuff 數字 MXNet是基礎,Gluon是封裝,兩者猶如TensorFlow和Keras,不過得益於動態圖機制,兩者交互比TensorFlow和Keras要方便得多,其基礎操作和pytorch極為相似,但

Linux下對MySQL/MariaDB數據庫的基本操作以及linux mysql添加用戶,刪除用戶,以及用戶權限的授予

信息 查看 let quit mar 普通用戶 表名 mys xxxx 文章引用地址:https://www.cnblogs.com/Glory-D/p/7518541.html、https://www.cnblogs.com/zhchoutai/p/6929103.htm

Linux系統基礎知識(二)基於linux系統下的用戶管理操作以及文件操作補充

c99 數據塊 upa 系統數據 精確 passwd 列表 sudo 3.4 1、(思考)系統中為什麽要有用戶 1.1用戶??系統中最底層的安全設定,回收(限制)權利。1.2組??共享權利。分為以下兩種:??(1)附加組:由用戶決定的組(每個用戶不一定都有);??(2)初始

關於ORACLE數據庫的一些用戶操作以及novcat連接oracle

開啟 file ron 刪除 http 背景 def drop 用戶名 背景:最近接觸的項目用的是oracle,之前用的都是mysql,所以不是太懂,記錄下oracle方面的知識 oracle的賬號操作: 註意:創建用戶和刪除用戶以及授權,一般用戶沒有權限的,建議使用超

數據庫CRUD操作以及MyBatisd的配置使用

file 操作 name creat 抽象 order by pad wait depend • 業務字段設計 • 數據庫創建 • CRUD操作 • MyBatis集成 • 註解和XML定義 &bull

【轉】JavaScript 節點操作 以及DOMDocument屬性和方法

表示 位置 clas 句柄 doc elements nta XML sele 最近發現DOMDocument對象很重要,還有XMLHTTP也很重要 註意大小寫一定不能弄錯. 屬性: 1Attributes 存儲節點的屬性列表(只讀) 2childNodes 存儲節點的子

EXT各個控制元件隱藏不可編輯等操作以及一些控制元件操作

//FieldSet2 $get(‘FieldSet’).hide(); //TextField設定 不可編輯 Ext.getCmp(“TextField”).readOnly = true; //帶文字框 $get(‘TextField’).setDisabled(true);//不帶

poiExcel表格所有操作以及資料匯入匯出

這個是本人在學習中記錄的筆記以供大家參考 Poi簡介: 1.1什麼是poi Apache POI [1]  是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對Microsoft Offi