默认zookeeper无权限认证功能, 修改些代码实现认证
zookeeper包括四个内置的scheme,包括world,auth,digest,ip,默认为world,权限相当于任何人可操作。我们现在要做的是加入一种认证方式,使用digest这种username:password方式比较适合我们。 但是zookeeper带的zkCli.sh在设置Acl时,如果scheme为digest密码采用明文会有问题


经过研究发现digest的密码生成方式是Sha1摘要的base64形式,所以我们可以用其它语言生成密码摘要然后操作。


在cli下使用getAcl查看权限, 使用setAcl为/加权限,操作有权限的节点要先使用


        [zk: localhost:2181(CONNECTED) 21] setAcl /pomelo digest:pomelo:zOL5mkauOP5kV9xnATsWSNNqEdw=:cdrwa
        cZxid = 0x271
        ctime = Thu Jul 18 18:54:57 CST 2013
        mZxid = 0x271
        mtime = Thu Jul 18 18:54:57 CST 2013
        pZxid = 0x272
        cversion = 1
        dataVersion = 0
        aclVersion = 1
        ephemeralOwner = 0x0
        dataLength = 6
        numChildren = 1
            [zk: localhost:2181(CONNECTED) 22] getAcl /pomelo
        'digest,'pomelo:zOL5mkauOP5kV9xnATsWSNNqEdw=
        : cdrwa
            [zk: localhost:2181(CONNECTED) 23] getAcl /
        'world,'anyone
            : cdrwa
        [zk: localhost:2181(CONNECTED) 25] ls /pomelo
        Authentication is not valid : /pomelo
        [zk: localhost:2181(CONNECTED) 26] addauth digest pomelo:pomelo
        [zk: localhost:2181(CONNECTED) 27] ls /pomelo
        [master]
        [zk: localhost:2181(CONNECTED) 28]     
修改pomelo app.js配置, 如果配置setACL: true在连接时会自动为path下的节点设置密码。如果要访问的节点原来有权限的话可以设置为setACL: false


            app.enable('masterHA');
            app.set('masterHAConfig',
                {
                    server : '127.0.0.1:2181',
                    path : '/pomelo/master',
                    setACL: true,
                    username : 'pomelo',
                    password : 'pomelo'




            });


修改/pomelo/lib/master/zookeeper.js


    var logger = require('pomelo-logger').getLogger(__filename);
        var crypto = require('crypto');




    var zookeeperClient = null;




    function getClient(app) {
        if (!zookeeperClient) {
            zookeeperClient = new Zookeeper(app);
        }




        return zookeeperClient;
    }




    function Zookeeper(app, opts) {
        this.app = app;
        var config = app.get('masterHAConfig');




        var timeout = config.timeout || 5000;
        this.hosts = config.server || '127.0.0.1:2181';
        this.path = config.path || '/pomelo/master';
        this.username = config.username || 'pomelo';
        this.password = config.password || 'pomelo';
        this.setACL = config.setACL;
        this.lockPath = this.path + '/lock';
        this.nodePath = this.lockPath + '/' + this.app.serverId + '-';
        this.version = null;
        this.onDataSet = false;
        this.authentication = this.username + ':' + this.password;
        var shaDigest = crypto.createHash('sha1').update(this.authentication).digest('base64');
        this.acls = [
            new zookeeper.ACL(
                zookeeper.Permission.ALL,
                new zookeeper.Id('digest', this.username+':'+shaDigest)
            )
        ];




        this.client = zookeeper.createClient(this.hosts, {sessionTimeout: timeout});




        var self = this;
        this.client.once('connected', function () {
            if(self.setACL) {
                self.client.addAuthInfo('digest', new Buffer(self.authentication));
                self.client.setACL(self.path, self.acls, -1, function (error, stat) {
                    if (error) {
                        console.log('Failed to set ACL: %s.', error);
                        return;
                    }
                    console.log('ACL is set to: %j', self.acls);
                });
            }
            watchNode(self.client, self.path, onMasterUpdate.bind(self));
        });




        this.client.connect();
    }



关于 ACL

Zookeeper的ACL,可以从三个维度来理解:一是scheme; 二是user; 三是permission,通常表示为scheme:id:permissions

授权方式:

1. scheme: scheme对应于采用哪种方案来进行权限管理,zookeeper实现了一个pluggable的ACL方案,可以通过扩展scheme,来扩展ACL的机制。zookeeper缺省支持下面几种scheme:

2.

auth: 它不需要id, 只要是通过authentication的user都有权限(zookeeper支持通过kerberos来进行authencation, 也支持username/pass<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>形式的authentication)

3.

digest: 它对应的id为username:BASE64(SHA1(pass<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>)),它需要先通过username:password形式的authentication

4.

ip: 它对应的id为客户机的IP地址,设置的时候可以设置一个ip段,比如ip:192.168.1.0/16, 表示匹配前16个bit的IP段

5.

super: 在这种scheme情况下,对应的id拥有超级权限,可以做任何事情(cdrwa

6.

world: 它下面只有一个id, 叫anyone, world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的: cdrwa

每个ACL 都会有一个权限列表

r表示"read",w表示"write",c表示"create",d表示"delete",a表示"admin"

Zookeeper 权限定义:

权限描述备注
CREATE有创建子节点的权限
READ有读取节点数据和子节点列表的权限
WRITE有修改节点数据的权限无创建和删除子节点的权限
DELETE有删除子节点的权限
ADMIN有设置节点权限的权限


ZooKeeper 四字命令    功能描述

conf    输出相关服务配置的详细信息。

cons    列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。包括“接受 / 发送”的包数量、会话 id 、操作延迟、最后的操作执行等等信息。

dump    列出未经处理的会话和临时节点。

envi    输出关于服务环境的详细信息(区别于 conf 命令)。

reqs    列出未经处理的请求

ruok    测试服务是否处于正确状态。如果确实如此,那么服务返回“imok ”,否则不做任何相应。

stat    输出关于性能和连接的客户端的列表。

wchs    列出服务器 watch 的详细信息。

wchc    通过 session 列出服务器 watch 的详细信息,它的输出是一个与watch 相关的会话的列表。wchp    通过路径列出服务器 watch 的详细信息。它输出一个与 session相关的路径。