记录Zookeeper被玩坏后的60分钟

楔子

前段时间在研究Zookeeper配置统一管理系统的时候,意外把开发环境的Zookeeper的权限搞坏了,导致了所有服务都无法把信息上传至Zookeeper。由于公司的所有人都共用一套开发环境,如果此时有人需要更新服务,那么势必会造成服务无法正常启动。Zookeeper的权限修复火速开始了。

正文

首先先看一下正常状态的Zookeeper权限设置

[zk: localhost:2181(CONNECTED) 10] ls /
[zookeeper, config]
[zk: localhost:2181(CONNECTED) 11] getAcl /config
'world,'anyone
: r
'ip,'192.168.0.106
: cdrwa
[zk: localhost:2181(CONNECTED) 12]

根节点下有两个节点一个zookeeper和config,config的访问权限对于192.168.0.106下用户有Zookeeper的完全访问权限,而从其他机器进行访问就只有只读权限了。

由于实验用的Zookeeper配置管理系统并不是放置在192.168.0.106机器下,所以我就对config节点的访问权限进行了修改,但是中途出现了错误导致config的权限变成了对所有访问者都只有只读权限(如下所示),这就造成了严重的问题,该套环境上的其他同事都无法对config节点下的所有数据进行修改。

[zk: 192.168.0.106(CONNECTED) 3] getAcl /config
'world,'anyone
: r
[zk: 192.168.0.106(CONNECTED) 4]

本着自己弄坏的,自己的修的原则,下面开始了Zookeeper权限修复的旅程。

进过了一番的折腾,发现只有使用Zookeeper的超级管理员用户才能对节点权限进行修复。其实Zookeeper的超级用户也是为了在发生这种情况下,最后的拯救措施(瞎猜的)。

1. 获取Zookeeper的超级管理员权限

首先我们需要先想好Zookeeper的超级管理员登录账号和密码,这里我们设定为super:superman,这里是明文,往Zookeeper中设置的时候密码需要写成密文,这时我们就需要借助org.apache.zookeeper.server.auth.DigestAuthenticationProvider来计算密码的密文

String m = DigestAuthenticationProvider.generateDigest("super:superman");
System.out.println(m);

输出为super:SQe25qcxXpeEUnoR1zBktlwk6jA=

下面我们开始设置Zookeeper的超级管理员,在zkServer.sh中找到以下内容

nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \

然后在后面追加以下内容

"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:SQe25qcxXpeEUnoR1zBktlwk6jA="

然后就合并成以下形式


nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:SQe25qcxXpeEUnoR1zBktlwk6jA="\  
    -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &  

最后重启Zookeeper,登录超级管理员

[zk: localhost:2181(CONNECTED) 3] addauth digest super:superman
[zk: localhost:2181(CONNECTED) 4]

这个时候就能随意的修改节点的权限

2. Zookeeper的权限管理

下面我们来讲讲Zookeeper的权限管理

2.1 Zookeeper支持的权限类型
  • CREATE: 你可以创建子节点。
  • READ: 你可以获取节点数据以及当前节点的子节点列表。
  • WRITE: 你可以为节点设置数据。
  • DELETE: 你可以删除子节点。
  • ADMIN: 可以为节点设置权限。
2.2 Zookeeper支持的权限设置模式(Scheme)

这里所有的权限设置格式都遵循scheme:id:permission

以下为所有的scheme列表

  • world:代表所有用户,该模式下id这里为一个该固定值,anyone
  • digest:该模式下,id为user:pwd,这里的pwd为编码过后的值
  • auth:该模式下,id为user,表示只有指定用户具有访问权限
  • host:该模式下,id为主机名,其中需要注意的是host可以只是主机名的后缀,例如id=corp.com可以匹配 host1.corp.comhost2.corp.com 主机名的机器,而主机名为 host1.store.com 的机器是无法匹配的
  • ip:该模式与host的模式类似,只不过这里的ip就是ip地址
2.3 单权限模式设置
2.3.1 world模式
[zk: 192.168.0.111(CONNECTED) 9] create /config/world null
Created /config/world
[zk: 192.168.0.111(CONNECTED) 10] setAcl /config/world world:anyone:r
[zk: 192.168.0.111(CONNECTED) 12] getAcl /config/world
'world,'anyone
: r
[zk: 192.168.0.111(CONNECTED) 13]

我们在config节点下创建一个world节点,然后为其设置权限为对于所有人都只有只读权限

2.3.2 digest模式
[zk: 192.168.0.111(CONNECTED) 6] create /config/digest null
Created /config/digest
[zk: 192.168.0.111(CONNECTED) 14] setAcl /config/digest digest:user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=:cdwra
[zk: 192.168.0.111(CONNECTED) 15] getAcl /config/digest
'digest,'user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=
: cdrwa
[zk: 192.168.0.111(CONNECTED) 2] addauth digest user:123456
[zk: 192.168.0.111(CONNECTED) 3] get /config/digest
null

我们在config节点下创建一个digest节点,然后为其设置权限为只有使用账号密码为user:123456的用户才有完全的访问权限

2.3.3 auth模式
[zk: 192.168.0.111(CONNECTED) 7] create /config/auth null
Created /config/auth
[zk: 192.168.0.111(CONNECTED) 8] addauth digest user:123456
[zk: 192.168.0.111(CONNECTED) 9] setAcl /config/auth auth:user:cdwra
[zk: 192.168.0.111(CONNECTED) 10] getAcl /config/auth
'digest,'user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=
: cdrwa
[zk: 192.168.0.111(CONNECTED) 11]

我们在config节点下创建一个digest节点,然后添加一个账号和密码为user:123456的认证用户,然后对该用户添加操作权限。这个时候我们通过getAcl查看/config/auth节点的控制权限与上面的/config/digest一模一样,因此使用auth模式与digest模式的效果是完全一样的。

2.3.4 ip模式
[zk: 192.168.0.111(CONNECTED) 9] create /config/ip null
Created /config/ip
[zk: 192.168.0.111(CONNECTED) 10] setAcl /config/ip ip:192.168.0.106:cdwra
[zk: 192.168.0.111(CONNECTED) 12] getAcl /config/ip
'ip,'192.168.0.106
: cdrwa
[zk: 192.168.0.111(CONNECTED) 13]

我们在config节点下创建一个ip节点,然后为其设置权限为只有ip地址为192.168.0.106的用户才有完全的访问权限

2.3.5 host模式
[zk: 192.168.0.111(CONNECTED) 9] create /config/host null
Created /config/host
[zk: 192.168.0.111(CONNECTED) 10] setAcl /config/host host:corp.com:cdwra
[zk: 192.168.0.111(CONNECTED) 12] getAcl /config/host
'host,'corp.com
: cdrwa
[zk: 192.168.0.111(CONNECTED) 13]

我们在config节点下创建一个host节点,然后为其设置权限为只有主机名为corp.com的用户才有完全的访问权限

2.4 组合权限模式设置

如果我们需要对Zookeeper的节点进行复杂的权限设置,例如一开始我们在正文所看到的权限设置

[zk: localhost:2181(CONNECTED) 11] getAcl /config
'world,'anyone
: r
'ip,'192.168.0.106
: cdrwa

要实现这样的设置需要执行以下命令

[zk: 192.168.0.111(CONNECTED) 10] setAcl /config world:anyone:r,ip:192.168.0.106:cdrwa

多种权限设置以逗号分隔开,如果还需要允许以账号密码user:123456登录的用户也拥有config节点的完全访问权限则如下设置

[zk: 192.168.0.111(CONNECTED) 12] setAcl /config world:anyone:r,ip:192.168.0.106:cdrwa,digest:user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=:cdwra
2.5 节点访问权限的继承性

最后我们来讲一下Zookeeper节点的权限是否具有继承性。其实Zookeeper的Acl准确的来说只是一种访问控制,并不是完整的权限管理。由于Acl控制节点并没有递归机制,这就导致了子节点的访问控制无法继承父节点的访问空。下面让我们通过一个简单的例子来感受一下。

我们现在在config节点下再创建一个noAcl节点,两个节点的访问控制分别如下:

[zk: 192.168.0.111(CONNECTED) 4] getAcl /config
'digest,'user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=
: cdrwa
[zk: 192.168.0.111(CONNECTED) 5] getAcl /config/noAcl
'world,'anyone
: cdrwa
[zk: 192.168.0.111(CONNECTED) 6]

我们现在不使用user用户登录,这时候查看config节点的内容和config下的子节点

[zk: 192.168.0.111(CONNECTED) 6] get /config
Authentication is not valid : /config
[zk: 192.168.0.111(CONNECTED) 7] ls /config
Authentication is not valid : /config
[zk: 192.168.0.111(CONNECTED) 8]

均显示没有权限操作config节点,但是我们现在查看一下noAcl节点的内容

[zk: 192.168.0.111(CONNECTED) 8] get /config/noAcl
hello

这个时候我们可以很清楚的查看noAcl节点里面的内容,如果我们需要保护noAcl节点的话,只能对其单独设置访问控制。这个时候大家可能会对Zookeeper的访问设置抱有一定的质疑。其实我们没有必要将这种缺陷扩大化。首先Zookeeper中主要放置的都是一些与业务无关的系统配置信息,其次是对于系统外部用户而言,如果get不到config节点下的子节点列表,那么就何谈获取子节点的内容了。如果真的子节点内的信息比较关键,那么单独为其进行访问控制又何尝不可。


至此本文的所有内容到此结束。现在做一下下期预告,简要的介绍一下zkCli的使用说明。

欢迎关注微信公众号,在这里可以提前看到下一期文章哦~

mark

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值