阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

分布式服务Dubbo+Zookeeper安全认证

450次阅读
没有评论

共计 7590 个字符,预计需要花费 19 分钟才能阅读完成。

前言

由于之前的服务都是在内网,Zookeeper 集群配置都是走的内网 IP,外网不开放相关端口。最近由于业务升级,购置了阿里云的服务,需要对外开放 Zookeeper 服务。

问题

Zookeeper+dubbo,如何设置安全认证?不想让其他服务连接 Zookeeper,因为这个 Zookeeper 服务器在外网。

查询官方文档:

Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。

分布式服务 Dubbo+Zookeeper 安全认证

流程说明:

  • 服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
  • 服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址
  • 监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址

支持以下功能:

  • 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
  • 当注册中心重启时,能自动恢复注册数据,以及订阅请求
  • 当会话过期时,能自动恢复注册数据,以及订阅请求
  • 当设置 < dubbo:registry check=”false” /> 时,记录失败注册和订阅请求,后台定时重试
  • 可通过 < dubbo:registry username=”admin” password=”1234″ /> 设置 zookeeper 登录信息
  • 可通过 < dubbo:registry group=”dubbo” /> 设置 zookeeper 的根节点,不设置将使用无根树
  • 支持 * 号通配符 < dubbo:reference group=”” version=”” />,可订阅服务的所有分组和所有版本的提供者

官网文档第五条,明确说明了可以通过 username 和 password 字段设置 zookeeper 登录信息。

以下是 registry 参数说明:

分布式服务 Dubbo+Zookeeper 安全认证

但是,如果在 Zookeeper 上通过 digest 方式设置 ACL,然后在 dubbo registry 上配置相应的用户、密码,服务就注册不到 Zookeeper 上了,会报 KeeperErrorCode = NoAuth 错误。

但是查阅 ZookeeperRegistry 相关源码并没有发现相关认证的地方,搜遍全网很少有问类似的问题,这个问题似乎并没有多少人关注。

Zookeeper 中的 ACL

概述

传统的文件系统中,ACL 分为两个维度,一个是属组,一个是权限,子目录 / 文件默认继承父目录的 ACL。而在 Zookeeper 中,node 的 ACL 是没有继承关系的,是独立控制的。Zookeeper 的 ACL,可以从三个维度来理解:一是 scheme; 二是 user; 三是 permission,通常表示为

scheme:id:permissions

下面从这三个方面分别来介绍:

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)

permission: zookeeper 目前支持下面一些权限:

  • CREATE(c): 创建权限,可以在在当前 node 下创建 child node
  • DELETE(d): 删除权限,可以删除当前的 node
  • READ(r): 读权限,可以获取当前 node 的数据,可以 list 当前 node 所有的 child nodes
  • WRITE(w): 写权限,可以向当前 node 写数据
  • ADMIN(a): 管理权限,可以设置当前 node 的 permission

客户端管理

我们可以通过以下命令连接客户端进行操作:

./zkCli.sh 

帮助

[zk: localhost:2181(CONNECTED) 2] help
ZooKeeper -server host:port cmd args
        connect host:port
        get path [watch]
        ls path [watch]
        set path data [version]
        rmr path
        delquota [-n|-b] path
        quit 
        printwatches on|off
        create [-s] [-e] path data acl
        stat path [watch]
        close 
        ls2 path [watch]
        history 
        listquota path
        setAcl path acl
        getAcl path
        sync path
        redo cmdno
        addauth scheme auth
        delete path [version]
        setquota -n|-b val path

简单操作

[zk: localhost:2181(CONNECTED) 12] ls /
[dubbo, test, zookeeper]
[zk: localhost:2181(CONNECTED) 13] create /itstyle  data ip:192.168.1.190:cdrw
Created /itstyle
[zk: localhost:2181(CONNECTED) 14] getAcl /itstyle
'ip,'192.168.1.190
: cdrw

zkclient 操作代码

import Java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;

public class Acl {private static final String zkAddress = "192.168.1.190:2181";  
    private static final String testNode = "/dubbo";  
    private static final String readAuth = "read-user:123456";  
    private static final String writeAuth = "write-user:123456";  
    private static final String deleteAuth = "delete-user:123456";  
    private static final String allAuth = "super-user:123456";  
    private static final String adminAuth = "admin-user:123456";  
    private static final String digest = "digest";  
   
    privatestaticvoidinitNode() throws NoSuchAlgorithmException {ZkClient zkClient = new ZkClient(zkAddress);  
        System.out.println(DigestAuthenticationProvider.generateDigest(allAuth));
        zkClient.addAuthInfo(digest, allAuth.getBytes());  
        if (zkClient.exists(testNode)) {zkClient.delete(testNode);  
            System.out.println("节点删除成功!");  
        }  
   
        List<ACL> acls = new ArrayList<ACL>();  
        acls.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(allAuth))));
        acls.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(allAuth))));  
        acls.add(new ACL(ZooDefs.Perms.READ, new Id(digest, DigestAuthenticationProvider.generateDigest(readAuth))));  
        acls.add(new ACL(ZooDefs.Perms.WRITE, new Id(digest, DigestAuthenticationProvider.generateDigest(writeAuth))));  
        acls.add(new ACL(ZooDefs.Perms.DELETE, new Id(digest, DigestAuthenticationProvider.generateDigest(deleteAuth))));  
        acls.add(new ACL(ZooDefs.Perms.ADMIN, new Id(digest, DigestAuthenticationProvider.generateDigest(adminAuth))));  
        zkClient.createPersistent(testNode, testNode, acls);  
   
        System.out.println(zkClient.readData(testNode));  
        System.out.println("节点创建成功!");  
        zkClient.close();}  
   
    privatestaticvoidreadTest() {ZkClient zkClient = new ZkClient(zkAddress);  
        try {System.out.println(zkClient.readData(testNode));// 没有认证信息,读取会出错  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
   
        try {zkClient.addAuthInfo(digest, adminAuth.getBytes());  
            System.out.println(zkClient.readData(testNode));//admin 权限与 read 权限不匹配,读取也会出错  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
   
        try {zkClient.addAuthInfo(digest, readAuth.getBytes());  
            System.out.println(zkClient.readData(testNode));// 只有 read 权限的认证信息,才能正常读取  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
   
        zkClient.close();}  
   
    privatestaticvoidwriteTest() {ZkClient zkClient = new ZkClient(zkAddress);  
   
        try {zkClient.writeData(testNode, "new-data");// 没有认证信息,写入会失败  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
   
        try {zkClient.addAuthInfo(digest, writeAuth.getBytes());  
            zkClient.writeData(testNode, "new-data");// 加入认证信息后, 写入正常  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
   
        try {zkClient.addAuthInfo(digest, readAuth.getBytes());  
            System.out.println(zkClient.readData(testNode));// 读取新值验证  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
   
        zkClient.close();}  
   
    privatestaticvoiddeleteTest() {ZkClient zkClient = new ZkClient(zkAddress);  
        zkClient.addAuthInfo(digest, deleteAuth.getBytes());  
        try {System.out.println(zkClient.readData(testNode));  
            zkClient.delete(testNode);  
            System.out.println("节点删除成功!");  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
        zkClient.close();}  
   
    privatestaticvoidchangeACLTest() {ZkClient zkClient = new ZkClient(zkAddress);  
        // 注:zkClient.setAcl 方法查看源码可以发现,调用了 readData、setAcl 二个方法  
        // 所以要修改节点的 ACL 属性,必须同时具备 read、admin 二种权限  
        zkClient.addAuthInfo(digest, adminAuth.getBytes());  
        zkClient.addAuthInfo(digest, readAuth.getBytes());  
        try {List<ACL> acls = new ArrayList<ACL>();  
            acls.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(adminAuth))));  
            zkClient.setAcl(testNode, acls);  
            Map.Entry<List<ACL>, Stat> aclResult = zkClient.getAcl(testNode);  
            System.out.println(aclResult.getKey());  
        } catch (Exception e) {System.err.println(e.getMessage());  
        }  
        zkClient.close();}  
   
    publicstaticvoidmain(String[] args) throws Exception {initNode();  
   
        System.out.println("---------------------");  
   
        readTest();  
   
        System.out.println("---------------------");  
   
        writeTest();  
   
        System.out.println("---------------------");  
   
        changeACLTest();  
   
        System.out.println("---------------------");  
   
        deleteTest();}  
}

总结

大部分服务大都是部署在内网的,基本很少对外网开放,然而 Dubbo 的 zookeeper 用户权限认证貌似真的不起作用,如果非要对外开放只能通过 iptables 或者 firewall 进行 IP Access Control,如果是阿里云服务器的话安全组也是个不错的选择。

在 CentOS7 上安装 Zookeeper-3.4.9 服务 http://www.linuxidc.com/Linux/2016-09/135052.htm 

ZooKeeper 官方文档翻译——ZooKeeper Overview 3.4.6  http://www.linuxidc.com/Linux/2016-12/138025.htm 

CentOS 下 ZooKeeper 3.4.8 集群环境搭建 http://www.linuxidc.com/Linux/2016-12/137958.htm 

CentOS 7 下 Zookeeper 集群安装 http://www.linuxidc.com/Linux/2017-01/139733.htm 

ZooKeeper 学习总结  http://www.linuxidc.com/Linux/2016-07/133179.htm 

Linux 下安装 Zookeeper 集群 http://www.linuxidc.com/Linux/2017-01/139545.htm 

Zookeeper3.4.6 的安装 http://www.linuxidc.com/Linux/2015-05/117697.htm 

Linux 下 Zookeeper 集群的安装  http://www.linuxidc.com/Linux/2017-03/141400.htm 

CentOS 7 下安装 Zookeeper 单机版  http://www.linuxidc.com/Linux/2015-05/117697.htm

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-12/149605.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计7590字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7994033
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞...
240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

  240 元左右!五盘位 NAS 主机,7 代 U 硬解 4K 稳如狗,拓展性碾压同价位 在 NA...
星哥带你玩飞牛NAS-8:有了NAS你可以干什么?软件汇总篇

星哥带你玩飞牛NAS-8:有了NAS你可以干什么?软件汇总篇

星哥带你玩飞牛 NAS-8:有了 NAS 你可以干什么?软件汇总篇 前言 哈喽各位玩友!我是是星哥,不少朋友私...
让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级 大家好,我是星哥,之前写了一篇文章 自己手撸一...
在Windows系统中通过VMware安装苹果macOS15

在Windows系统中通过VMware安装苹果macOS15

在 Windows 系统中通过 VMware 安装苹果 macOS15 许多开发者和爱好者希望在 Window...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛 NAS 硬件 03:五盘位 +N5105+ 双网口的成品 NAS 值得入手吗 前言 大家好,我...
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare 也瘫了连监控都挂,根因藏在哪? 最近两天的互联网堪称“故障...
多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞...
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...