zookeeper acl認證機制及dubbo、kafka集成、zooviewer/idea zk插件配置


ZooKeeper的ACL機制

zookeeper通過ACL機制控制znode節點的訪問權限。

首先介紹下znode的5種操作權限:
CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、刪、改、查、管理權限,這5種權限簡寫為crwda(即:每個單詞的首字符縮寫)
注:這5種權限中,delete是指對子節點的刪除權限,其它4種權限指對自身節點的操作權限

身份的認證有4種方式:

  • world:默認方式,相當於全世界都能訪問
  • auth:代表已經認證通過的用戶(cli中可以通過addauth digest user:pwd 來添加當前上下文中的授權用戶)
  • digest:即用戶名:密碼這種方式認證,這也是業務系統中最常用的,下面解決dubbo認證用的就是這種模式。
  • ip:使用Ip地址認證

一般使用[scheme:id:permissions]來表示acl權限。

我們在zk的客戶端可以進行節點權限的查看和設置。

[zk: localhost:2181(CONNECTED) 3] create /test data
Created /test
[zk: localhost:2181(CONNECTED) 2] getAcl /test
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 3] addauth digest user:password
[zk: localhost:2181(CONNECTED) 4] setAcl /test auth:user:password:cdrwa
[zk: localhost:2181(CONNECTED) 5] getAcl /test
'digest,'user:V28q/NynI4JI3Rk54h0r8O5kMug=
: cdrwa    

從上述操作可以看出,zk新創建的znode默認訪問方式為world。我們通過addauth和setAcl給/test節點設置訪問權限為digest,操作權限為cdrwa,用戶名為user,密碼為password。

另啟zk客戶端,執行ls /test,發現當前用戶已經無法訪問/test節點,提示信息為“Authentication is not valid”。解決方法就是addauth添加認證用戶了,並且必須使用用戶名和密碼明文進行認證。

[zk: localhost:2181(CONNECTED) 0] ls /test
Authentication is not valid : /test
[zk: localhost:2181(CONNECTED) 4] addauth digest user:password
[zk: localhost:2181(CONNECTED) 5] ls /test
[] 
[zk: localhost:2181(CONNECTED) 6] create /test/leaf data
Created /test/leaf
[zk: localhost:2181(CONNECTED) 7] getAcl /test/leaf
'world,'anyone
: cdrwa

addauth添加digest認證用戶user后,即可正常訪問/test節點了。

另外,還有一點需要注意,znode的ACL是相互獨立的。也就是說,任意不同節點可以用不同的acl列表,互不影響,並且ACL是不可被繼承的,節點並不會繼承父節點的訪問權限,且是節點級別控制的,有些節點可以啟用acl,有些可以不啟用,最典型的比如dubbo啟用、kafka不啟用

我們在/test下創建leaf節點,可發現,leaf節點的認證方式為world,即任何用戶都有訪問權限。

設置super超級管理員用戶

 一旦我們為某一個節點設置了acl,那么其余的未授權的節點是無法訪問或者操作該節點的,那么系統用久了以后,假如忘記了某一個節點的密碼,那么就無法再操作這個節點了,所以需要這個super超級管理員用戶權限,其作用還是很大的。超級用戶只能在啟動服務器的時候添加,且digest必須是密文。

String m = DigestAuthenticationProvider.generateDigest("super:admin"); // 得到哈希值

打開zk目錄下的/bin/zkServer.sh服務器腳本文件,找到如下一行:
nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"
加一個超管的配置項,如下:
"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs="

然后重啟zkServer.sh即可。

 

四字命令

ZooKeeper中有一系列的命令可以查看服務器的運行狀態,它們的長度通常都是4個英文字母,因此又被稱之為“四字命令”。

使用方式: echo {command} | nc localhost 2181

需要首先使用yum install nc安裝。

詳細的四字命令介紹可參見https://www.jianshu.com/p/c96c9f8c2433。

分布式服務Dubbo+Zookeeper安全認證:KeeperErrorCode = NoAuth解決

網上搜了一圈,只有https://www.jianshu.com/p/02ada8d1858a和https://www.zhihu.com/question/45720203/answer/140188334提到了相關可行的解決方法。因為我們使用的是內部集成后的dubbo(maven-shade-plugin二次打包的LZ也經常這么干),且已經走的是curator而非zkclient,所以僅僅將dubbo.registry.client改成curator不解決問題。

public CuratorZookeeperClient(URL url) {
        super(url);
        Builder builder = CuratorFrameworkFactory.builder().connectString(url.getBackupAddress()).retryPolicy(new RetryNTimes(2147483647, 1000)).connectionTimeoutMs(url.getParameter("timeout", 5000)).sessionTimeoutMs(url.getParameter("session", 60000));
        String authority = url.getAuthority();
        if (authority != null && authority.length() > 0) {
            builder = builder.authorization("digest", authority.getBytes());
        }

        this.client = builder.build();
        this.client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
            public void stateChanged(CuratorFramework client, ConnectionState state) {
                if (state == ConnectionState.LOST) {
                    CuratorZookeeperClient.this.stateChanged(0);
                } else if (state == ConnectionState.CONNECTED) {
                    CuratorZookeeperClient.this.stateChanged(1);
                } else if (state == ConnectionState.RECONNECTED) {
                    CuratorZookeeperClient.this.stateChanged(2);
                }

            }
        });
        this.client.start();
    }

所以簡單的方法就是自己修改CuratorZookeeperClient,將zk的認證用戶名和密碼注入進來,如下:

public CuratorZookeeperClient(URL url) {
        super(url);
        String username = null;
        String password = null;
        // 加載配置文件
        try {
            ResourceBundle bundle = ResourceBundle.getBundle("application");
            username = bundle.getString("rpc.registry.username");
            password = bundle.getString("rpc.registry.password");
        } catch (Exception e) {
            // NOP
        }

        if (username != null && password != null) {
            url = url.setUsername(username).setPassword(password);
        }
        Builder builder = CuratorFrameworkFactory.builder().connectString(url.getBackupAddress()).retryPolicy(new RetryNTimes(2147483647, 1000)).connectionTimeoutMs(url.getParameter("timeout", 5000)).sessionTimeoutMs(url.getParameter("session", 60000));
        String authority = url.getAuthority();
        if (authority != null && authority.length() > 0) {
            builder = builder.authorization("digest", authority.getBytes());
        }

        this.client = builder.build();
        this.client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
            public void stateChanged(CuratorFramework client, ConnectionState state) {
                if (state == ConnectionState.LOST) {
                    CuratorZookeeperClient.this.stateChanged(0);
                } else if (state == ConnectionState.CONNECTED) {
                    CuratorZookeeperClient.this.stateChanged(1);
                } else if (state == ConnectionState.RECONNECTED) {
                    CuratorZookeeperClient.this.stateChanged(2);
                }

            }
        });
        this.client.start();
    }

 dubbo認證是解決了,還有kafka、日常管理用的zooviewer和idea集成的zk插件呢。。。。所以繼續kafka。。

kafka連接zookeeper認證

注:僅僅啟用認證的話,dubbo客戶端即使不配置SASL,也是可以正常訪問的,但是這樣就失去了意義。

這一部分主要參考了https://www.orchome.com/500、https://codeforgeek.com/how-to-set-up-authentication-in-kafka-cluster/以及https://blog.csdn.net/sdksdk0/article/details/95336382。關於SASL和kerberos的詳細介紹,參見:kerberos與sasl入坑指南

除了配置認證外,還可以選擇啟用或者不啟用acl。 

客戶端工具

zooinspector,3.4.14之后的版本都支持認證,可以下載使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM