概述

Z K作为一个分布式协调框架、内部存储着一些分布式系统运行时状态的元数据。如何有效的保护这些数据的安全、如何做一个比较好的权限控制显得非常的重要。

ZK 为我们提供一套完善的 ACL(access control list,访问控制列表) 权限控制机制来保障数据的安全。

ACL 介绍

我们可以从三个方面来理解 ACL 机制

  • Scheme 权限模式
  • Id 授权对象
  • Permission 权限

通常使用 scheme:id:permission 来标志一个有效的 ACL 信息、我们先来看看我们默认的数据节点里面的 ACL 数据

getACl /

我们也可以看到他也是分为三部分的

  • world 对应的就是 scheme
  • anyone 对应的就是 id
  • cdrwa 对应的就是 permission

下面我们就分别介绍它们

权限

  • create:c 数据节点的创建权限、允许授权对象在该数据节点下创建子节点。
  • delete:d 子节点的删除权限、允许授权对象删除该数据节点的子节点
  • read:r 数据节点的读取权限、允许授权对象对该数据节点读取数据内容和获取子节点列表信息
  • write:w 数据节点的更新权限、允许授权对象对数据节点的数据内容进行更新
  • admin:a 数据节点的管理权限、允许授权对象对该数据节点进行 ACL 相关的设置操作

权限模式

如果按分类来说、ZK 中其实只有两种权限模式,一种是基于IP/IP段的,一种是基于账号密码的。

但是可以细分为以下四种

  • IP
  • digest
  • world
  • super

IP

IP 模式可以针对数据节点设置 IP 地址或设置 IP 网段的方式进行配置。

[zk: localhost:2181(CONNECTED) 44] create /acl_ip data ip:127.0.0.1:cdrwa
Created /acl_ip

我们创建了数据节点 acl_ip 并且为这个节点设置了 ACL ,使用的是 IP 这种模式、授权对象就是 127.0.0.1 这个 ip,而权限则是五种权限全部都赋予了。我们在另外本机电脑的另一个 zkClient 中访问该数据节点

[zk: 127.0.0.1:2181(CONNECTED) 21] get /acl_ip
data
cZxid = 0x520
ctime = Sat May 16 13:04:40 CST 2020
mZxid = 0x520
mtime = Sat May 16 13:04:40 CST 2020
pZxid = 0x520
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: 127.0.0.1:2181(CONNECTED) 22] getAcl /acl_ip
'ip,'127.0.0.1
: cdrwa

digest

就是我们常见的账号密码模式

username:password

但是对于我们在命令行中、我们输入的并不是一个原始的密码、而是需要我们对 username:password 进行加密和编码之后的值。

[zk: localhost:2181(CONNECTED) 46] create /acl_digest data digest:foo:Jfg7TYUBs/6KEtdDWd5OB6bdD2Q=:wrcda
Created /acl_digest
[zk: localhost:2181(CONNECTED) 47] getAcl /acl_digest
'digest,'foo:Jfg7TYUBs/6KEtdDWd5OB6bdD2Q=
: cdrwa

原始的数据是: username 为 foo, password 为 true,但是在命令行中输入的 password 已然不是我们原本的 true 了

原因也很简单、安全嘛、那它的加密以及编码的逻辑是啥?

在源代码中 org.apache.zookeeper.server.auth.DigestAuthenticationProvider#generateDigest

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

可以看到其先对 username:password 进行SHA1 的加密、然后再进行 base64 的编码,最后得出来的就是我们返回的就是我们在命令行中输入的 foo:Jfg7TYUBs/6KEtdDWd5OB6bdD2Q= 这个字符串。

   String idPassword = "foo:true";
System.out.println(generateDigest(idPassword));
// 打印结果为
foo:Jfg7TYUBs/6KEtdDWd5OB6bdD2Q=

我们现在在另一个 zkClient 中增加 digest 信息然后访问这个数据节点

[zk: localhost:2181(CONNECTED) 9] addauth digest foo:true
[zk: localhost:2181(CONNECTED) 10] get /acl_digest
data
cZxid = 0x521
ctime = Sat May 16 13:41:55 CST 2020
mZxid = 0x521
mtime = Sat May 16 13:41:55 CST 2020
pZxid = 0x521
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0

world

world 是一种最开放的权限控制模式,事实上这种权限控制几乎没有任何的作用、数据节点的访问权限对所有用户开放,我们默认的就是这种权限模式。这种模式其实就是一种特殊的 digest 模式,只不过它的 id 只有一个 anyone

super

super 就是超级用户的意思、也是一种特殊的 digest。 在这个模式下、超级用户可以对任意的数据节点进行任意的操作。

授权对象

  • IP 授权模式下、授权对象就是 ip
  • digest 授权模式下、授权对象就是 username:base64(sha1(username:password))
  • world 授权模式下、只有一个授权对象 anyone
  • super 授权模式下、跟 digest 授权模式一样

super 授权模式介绍

如何配置一个超级管理员的授权对象呢?

假如我们配置的账号密码为 foo:foo 我们可以在启动 zkServer 的时候加入如下的系统属性

-Dzookeeper.DigestAuthenticationProvider.superDigest=foo:qllW6iET90npPATKMTxiFSiQ5Ns=

可以在启动 zkServer 的时候在 idea 的配置中加上这个参数

然后启动 server 则可

如果我们使用的是已经是官方编译好的zk、则可以在 bin 目录下修改 zkServer.sh 脚本的内容

nohup "$JAVA"
"-Dzookeeper.log.dir=${ZOO_LOG_DIR}"
"-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"
"-Dzookeeper.DigestAuthenticationProvider.superDigest=foo:qllW6iET90npPATKMTxiFSiQ5Ns=" \

加上我们的系统变量、然后启动则可

foo:foo 为 super 授权对象 的 username 和 password

/acl_super 节点的 username 和 password 都是 super 这个字符串

// super:super
[zk: localhost:2181(CONNECTED) 2] create /acl_super data digest:super:gG7s8t3oDEtIqF6DM9LlI/R+9Ss=:wrdca
Created /acl_super
[zk: localhost:2181(CONNECTED) 3] getAcl /acl_super
'digest,'super:gG7s8t3oDEtIqF6DM9LlI/R+9Ss=
: cdrwa
[zk: localhost:2181(CONNECTED) 4] get /acl_super
Authentication is not valid : /acl_super
[zk: localhost:2181(CONNECTED) 5] addauth digest foo:foo
[zk: localhost:2181(CONNECTED) 6] get /acl_super
data
cZxid = 0x52b
ctime = Sat May 16 15:18:18 CST 2020
mZxid = 0x52b
mtime = Sat May 16 15:18:18 CST 2020
pZxid = 0x52b
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0

super 授权模式验证部分源码

    private static final String superDigest = System.getProperty("zookeeper.DigestAuthenticationProvider.superDigest");

public KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte[] authData) {
String id = new String(authData);
try {
String digest = generateDigest(id);
if (digest.equals(superDigest)) {
cnxn.addAuthInfo(new Id("super", ""));
}
cnxn.addAuthInfo(new Id(getScheme(), digest));
return KeeperException.Code.OK;
} catch (NoSuchAlgorithmException e) {
LOG.error("Missing algorithm", e);
}
return KeeperException.Code.AUTHFAILED;
}

我们看到当我们的 digest 等于 superDigest 的时候、就会向 ServerCnxn 中增加多一个 Id 对象

private Set<Id> authInfo = Collections.newSetFromMap(new ConcurrentHashMap<Id, Boolean>());

而在我们访问节点的时候、触发 checkACL

org.apache.zookeeper.server.ZooKeeperServer#checkACL

 public void checkACL(ServerCnxn cnxn, List<ACL> acl, int perm, List<Id> ids, String path, List<ACL> setAcls) throws KeeperException.NoAuthException {

				// acl 为空
if (acl == null || acl.size() == 0) {
return;
}
// super 授权模式
for (Id authId : ids) {
if (authId.getScheme().equals("super")) {
return;
}
} for (ACL a : acl) {
Id id = a.getId();
if ((a.getPerms() & perm) != 0) {
// world 授权模式
if (id.getScheme().equals("world") && id.getId().equals("anyone")) {
return;
}
....
....
}
}
// 抛出异常
throw new KeeperException.NoAuthException();
}

相关文章

ZooKeeper 数据模型

编译运行Zookeeper源码

Zookeeper Watcher 流程分析(结合源码)

Zookeeper-Access Control List(ACL)的更多相关文章

  1. Windows Azure Virtual Network (10) 使用Azure Access Control List(ACL)设置客户端访问权限

    <Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的China Azure. 我们在创建完Windows Azure Virtual Machi ...

  2. Phalcon 訪问控制列表 ACL(Access Control Lists ACL)

    Phalcon在权限方面通过 Phalcon\Acl 提供了一个轻量级的 ACL(訪问控制列表). Access Control Lists (ACL) 同意系统对用户的訪问权限进行控制,比方同意訪问 ...

  3. [笔记] Access Control Lists (ACL) 学习笔记汇总

    一直不太明白Windows的ACL是怎么回事,还是静下心来看一手的MSDN吧. [翻译] Access Control Lists [翻译] How Access Check Works Modify ...

  4. Oracle ACL(Access Control List)

    在oralce 11g中假如你想获取server的ip或者hostname,执行如下语句 SELECT utl_inaddr.get_host_address FROM dual;  //获取IP S ...

  5. windows访问控制列表 --ACL(Access Control List)

    1.定义 ACL是一个windows中的表示用户(组)权限的列表. Access Control List(ACL) Access Control Entry(ACE) ... 2.分类 ACL分为两 ...

  6. SELINUX、Security Access Control Strategy && Method And Technology Research - 安全访问控制策略及其方法技术研究

    catalog . 引言 . 访问控制策略 . 访问控制方法.实现技术 . SELINUX 0. 引言 访问控制是网络安全防范和客户端安全防御的主要策略,它的主要任务是保证资源不被非法使用.保证网络/ ...

  7. Method and system for implementing mandatory file access control in native discretionary access control environments

    A method is provided for implementing a mandatory access control model in operating systems which na ...

  8. Extensible Access Control List Framework

    Methods, systems, and products for governing access to objects on a filesystem. In one general embod ...

  9. Security Access Control Strategy && Method And Technology Research - 安全访问控制策略及其方法技术研究

    1. 访问控制基本概念 访问控制是网络安全防范和客户端安全防御的重要基础策略,它的主要任务是保证资源不被非法使用.保证网络/客户端安全最重要的核心策略之一. 访问控制包括 入网访问控制 网络权限控制 ...

  10. Oracle ACL (Access Control List)详解

    在Oracle11g中,Oracle在安全方面有了很多的改进,而在网络权限控制方面,也有一个新的概念提出来,叫做ACL(Access Control List), 这是一种细粒度的权限控制.在ACL之 ...

随机推荐

  1. Java实现 蓝桥杯VIP 算法训练 Hanoi问题

    问题描述 如果将课本上的Hanoi塔问题稍做修改:仍然是给定N只盘子,3根柱子,但是允许每次最多移动相邻的M只盘子(当然移动盘子的数目也可以小于M),最少需要多少次? 例如N=5,M=2时,可以分别将 ...

  2. Java实现 LeetCode 257 二叉树的所有路径

    257. 二叉树的所有路径 给定一个二叉树,返回所有从根节点到叶子节点的路径. 说明: 叶子节点是指没有子节点的节点. 示例: 输入: 1 / \ 2 3 \ 5 输出: ["1->2 ...

  3. OC 语言特点以及与其他语言的区别

    OC 作为一门面向对象的语言,兼容c语言的语法,又有区别于其他面向对象语言的地方: 特点: 1.使用自动释放池,通过引用计数处理对象的内存管理. 2.拥有id这种通用对象类型. 3.分类,功能强大,不 ...

  4. el-upload配合vue-cropper实现上传图片前裁剪

    需求背景 上传一个封面图,在上传之前需要对图片进行裁剪,上传裁剪之后的图片,类似微信的上传头像. 技术方案 上传肯定是用element的 el-upload 组件实现上传,非常方便,各种钩子函数. 裁 ...

  5. Hadoop之hadoop fs和hdfs dfs、hdfs fs三者区别

      适用范围 案例 备注 小记 hadoop fs 使用范围最广,对象:可任何对象       hadoop dfs 只HDFS文件系统相关       hdfs fs 只HDFS文件系统相关(包括与 ...

  6. 除了FastJson,你也应该了解一下Jackson(二)

    概览 上一篇文章介绍了Jackson中的映射器ObjectMapper,以及如何使用它来实现Json与Java对象之间的序列化和反序列化,最后介绍了Jackson中一些序列化/反序列化的高级特性.而本 ...

  7. 变分(图)自编码器不能直接应用于下游任务(GAE, VGAE, AE, VAE and SAE)

        自编码器是无监督学习领域中一个非常重要的工具.最近由于图神经网络的兴起,图自编码器得到了广泛的关注.笔者最近在做相关的工作,对科研工作中经常遇到的:自编码器(AE),变分自编码器(VAE),图 ...

  8. Windows 程序设计(4) MFC-02 基本控件-下

    1. TabCtrl 标签控件 1.1 创建主窗口 1)CMFCTabControlDlg,拖拽标签控件 2)增加变量 CTabCtrl m_tabCtrl 3)设置相关成员变量和处理函数 CFile ...

  9. cocos2dx 启用cjson

    在appDelegate.cpp文件中添加 #if __cplusplus extern "C" { // 加入此代码的目的,防止污染引擎的scripting目录 #include ...

  10. PHP丨PHP基础知识之条件语IF判断「理论篇」

    if语句是指编程语言(包括c语言.C#.VB.java.php.汇编语言等)中用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一. if语句概述 if语句是指编程语言(包 ...