zookeeper的几种授权方式
不罗嗦了,直接来干货。如有问题,可随时交流。
zookeeper授权方式设置
一、设置授权
1.1、IP白名单方式
备注:对需要进行白名单设置的路径进行设置,此处设置的路径没有继承关系,即设置了/test的白名单,但是/test/test2依然没有设置为白名单。
setAcl /test ip:127.0.0.1:cdrwa
多个ip之间用逗号隔开,如:
setAcl /test ip:127.0.0.1:cdrwa,ip:192.168.10.3:cdrwa
通过此IP白名单设置之后,即只允许设定过的IP服务器才能进行访问,其他机器无法访问。
1.2、auth模式
1.2.1、添加用户
addauth digest ramboo:ramboo
可以添加多个用户,如
addauth digest ramboo1:ramboo1
addauth digest ramboo2:ramboo2
addauth digest ramboo3:ramboo3
1.2.2、设置Acl权限
此处假如对/auth路径进行设置,则
setAcl /auth auth:ramboo1:ramboo1:cdrwa
备注:****此处虽然设置了ramboo1用户的权限,但是zk会默认添加所有存在的用户。此处需要注意。
1.2.3、查看Acl权限
getAcl /auth
结果如下所示:
'digest,'ramboo1:JXpHVJcEMUsIf5MM6u7TlOp3pqo=
: cdrwa
'digest,'ramboo2:lTTHGKOT6A3iEwj/SV5meGTXbAM=
: cdrwa
'digest,'ramboo3:b8+HkvFoPszTILQTMB1YFQ+Yvus=
: cdrwa
备注:如果退出了客户端,再进入的时候,需要重新添加用户,才可访问,即授权。
1.3、digest模式
此模式,和auth模式的区别在于:
1、digest设置Acl的时候,可以不用先添加用户,而auth设置Acl的时候,是需要提前设置用户的,否则报错。
2、digest设置的密码要用密文,auth设置的密码是明文。
3、auth设置的,只需设置一个用户,就可以把所有用户设置进去,而digest不行,只能对本次设置的用户有效。也就是auth模式忽略id。
1.3.1、生成密文密码
在Linux下执行如下命令
echo -n xing:xing | openssl dgst -binary -sha1 | openssl base64
结果为:
kgk4DGva6vqOBYMGbMsXBZuFCXE=
1.3.2、设置Acl权限
此处假如对/digest路径进行设置,则
setAcl /digest digest:xing:kgk4DGva6vqOBYMGbMsXBZuFCXE=:cdrwa
备注:此处的密文密码不要随意更改,否则不知道对应的明文是多少,后续就没办法访问对应节点,切记!
备注:此处的密文密码不要随意更改,否则不知道对应的明文是多少,后续就没办法访问对应节点,切记!
备注:此处的密文密码不要随意更改,否则不知道对应的明文是多少,后续就没办法访问对应节点,切记!
1.3.3、查看Acl权限
此时如果没有添加xing这个用户,需要先添加,才可查看。添加命令如下:
addauth digest xing:xing
添加后,可查看:
getAcl /digest
结果为:
'digest,'xing:kgk4DGva6vqOBYMGbMsXBZuFCXE=
: cdrwa
备注:如果要添加多个用户,则用逗号隔开,如下所示:
setAcl /digest digest:xing:kgk4DGva6vqOBYMGbMsXBZuFCXE=:cdrwa,digest:hang:YQRsX4vWAT6BHGo7yQi6tFSYxKc=:cdrwa
二、忘记密码修复方式
如果对上述设置授权后,忘记密码了,怎么办?方法如下:
进入配置文件zoo.cfg,修改配置,设置跳过Acl验证,配置如下:
skipACL=yes
重启zookeeper。
启动后,可按照第一节所述的方式,重新进行Acl设置即可。
三 利用zookeeper c api进行zk实例的初始化和权限添加
利用zookeeper c api进行zk实例的初始化和权限添加时,喷到了一个情况:如代码所示
zk = zookeeper_init(url.c_str(), watcher, 30000, 0, 0, 0);
if(zk != NULL)
{
AC_INFO("zk connect sucess, hostip=%s", url.c_str());
}
else
{
AC_ERROR("zk connect error, hostip=%s", url.c_str());
return false;
}
<<<<<<
int rc = zoo_add_auth(zk, "digest", userauth.c_str(), userauth.length(), NULL, NULL);
if(rc == ZOK)
AC_INFO("zk addauth sucess, userauth=%s", userauth.c_str());
else
{
AC_ERROR("zk addauth error, userauth=%s", userauth.c_str());
return false;
}
结果zoo_add_auth失败,rc = -9;查看源码得知,这是zoo_add_auth函数的参数失效所致,即zoo_state(zk) = 0;为什么呢?
原来,zookeeper_init是一个异步函数,未等zk初始化成功,就执行了zoo_add_auth函数,而zoo_add_auth传入的zk必须是创建好的,否则就返回-9.
基于此,在<<<<<<出添加如下代码,即可解决
while(zoo_state(zk) == 0)
{
}