Kerberos安全认证-连载11-HBase Kerberos安全配置及访问_kerberos hbase

本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。

最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。

最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。

学习路线图

其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。

相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。

网络安全工具箱

当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。

项目实战

最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

面试题

归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

#所有节点切换成hbase用户
su hbase
cd ~

#node1~node5所有节点生成SSH密钥
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

#node1~node5所有节点公钥复制到node1节点上,这个过程需要输入yes和密码
ssh-copy-id node1

#将node1 authorized_keys文件分发到node1~node5各节点,这个过程需要输入密码
[hbase@node1 ~]$ cd ~/.ssh/
[hbase@node1 .ssh]$ scp authorized_keys node2:`pwd`
[hbase@node1 .ssh]$ scp authorized_keys node3:`pwd`
[hbase@node1 .ssh]$ scp authorized_keys node4:`pwd`
[hbase@node1 .ssh]$ scp authorized_keys node5:`pwd`

#两两节点进行ssh测试,这一步骤必须做,然后node1~node5节点退出当前hbase用户
exit

​​​​​​​2) 创建HBase服务Princial主体并写入到keytab文件

在kerberos服务端node1节点执行如下命令创建HBase服务主体:

[root@node1 ~]# kadmin.local -q "addprinc -pw 123456 hbase/node3"
[root@node1 ~]# kadmin.local -q "addprinc -pw 123456 hbase/node4"
[root@node1 ~]# kadmin.local -q "addprinc -pw 123456 hbase/node5"

在kerberos服务端node1节点执行如下命令将hbase主体写入到keytab文件:

#node1节点执行命令,将主体写入到keytab
[root@node1 ~]# kadmin.local -q "ktadd -norandkey -kt /home/keytabs/hbase.service.keytab hbase/node3@EXAMPLE.COM"
[root@node1 ~]# kadmin.local -q "ktadd -norandkey -kt /home/keytabs/hbase.service.keytab hbase/node4@EXAMPLE.COM"
[root@node1 ~]# kadmin.local -q "ktadd -norandkey -kt /home/keytabs/hbase.service.keytab hbase/node5@EXAMPLE.COM"

以上命令执行完成后,在node1节点/home/keytabs目录下生成hbase.service.keytab文件,将该文件分发到各个节点并赋权,这里可以只发送到node3~node5 Hbase所在节点,为了保证各个大数据集群节点的keytabs一致,这里分发到所有节点。

[root@node1 ~]# scp /home/keytabs/hbase.service.keytab node2:/home/keytabs/
[root@node1 ~]# scp /home/keytabs/hbase.service.keytab node3:/home/keytabs/
[root@node1 ~]# scp /home/keytabs/hbase.service.keytab node4:/home/keytabs/
[root@node1 ~]# scp /home/keytabs/hbase.service.keytab node5:/home/keytabs/

分发完成后,在集群各个节点上执行如下命令,修改hbase.service.keytab密钥文件所属用户和组信息:

chown root:hadoop /home/keytabs/hbase.service.keytab
chmod 770 /home/keytabs/hbase.service.keytab

​​​​​​​3) 修改hbase-site.xml配置文件

在所有hbase节点中修改HBASE_HOME/conf/hbase-site.xml文件内容,配置支持kerberos,向hbase-site.xml文件中追加如下内容:

  <!-- hbase开启安全认证 -->
  <property>
    <name>hbase.security.authorization</name>
    <value>true</value>
  </property>
  <!-- hbase配置kerberos安全认证 -->
  <property>
  	<name>hbase.security.authentication</name>
  	<value>kerberos</value>
  </property>
  <!-- HMaster配置kerberos安全凭据认证 -->
  <property>
  	<name>hbase.master.kerberos.principal</name>
  	<value>hbase/_HOST@EXAMPLE.COM</value>
  </property>
  <!-- HMaster配置kerberos安全证书keytab文件位置 -->
  <property>
  	<name>hbase.master.keytab.file</name>
  	<value>/home/keytabs/hbase.service.keytab</value>
  </property>
  <!-- Regionserver配置kerberos安全凭据认证 -->
  <property>
  	<name>hbase.regionserver.kerberos.principal</name>
  	<value>hbase/_HOST@EXAMPLE.COM</value>
  </property>
  <!-- Regionserver配置kerberos安全证书keytab文件位置 -->
  <property>
  	<name>hbase.regionserver.keytab.file</name>
  	<value>/home/keytabs/hbase.service.keytab</value>
  </property>

这里可以先在node3节点进行配置,配置完成后分发到node4、node5节点:

[root@node3 ~]# scp /software/hbase-2.2.6/conf/hbase-site.xml node4:/software/hbase-2.2.6/conf/
[root@node3 ~]# scp /software/hbase-2.2.6/conf/hbase-site.xml node5:/software/hbase-2.2.6/conf/

​​​​​​​4) 准备hdfs-site.xml和core-site.xml文件

HBase底层存储使用HDFS,这里需要将Hadoop中hdfs-site.xml和core-site.xml文件发送到hbase各个节点HBASE_HOME/conf/目录中。在node3~node5各个HBase节点中执行如下命令:

#node3~node5各个节点执行
cp /software/hadoop-3.3.4/etc/hadoop/hdfs-site.xml /software/hbase-2.2.6/conf/
cp /software/hadoop-3.3.4/etc/hadoop/core-site.xml /software/hbase-2.2.6/conf/

​​​​​​​​​​​​​​5) 准备zk-jaas.conf文件

HBase中会使用zookeeper管理元数据和选主,这里由于Zookeeper中已经开启了Kerberos认证,所以需要准备zk-jaas.conf文件连接zookeeper时进行认证。在HBase各个节点HBASE_HOME/conf目录下创建zk-jaas.conf文件,写入如下内容,不同的节点设置的principal是对应HBase主机节点。

node3节点HBASE_HOME/conf/zk-jaas.conf文件内容:

Client {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/home/keytabs/hbase.service.keytab"
  useTicketCache=false
  principal="hbase/node3@EXAMPLE.COM";
};

node4节点HBASE_HOME/conf/zk-jaas.conf文件内容:

Client {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/home/keytabs/hbase.service.keytab"
  useTicketCache=false
  principal="hbase/node4@EXAMPLE.COM";
};

node5节点HBASE_HOME/conf/zk-jaas.conf文件内容:

Client {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/home/keytabs/hbase.service.keytab"
  useTicketCache=false
  principal="hbase/node5@EXAMPLE.COM";
};

​​​​​​​​​​​​​​6) 修改hbase-env.sh配置

在各个hbase节点上配置HBASE_HOME/conf/hbase-env.sh,将HBASE_OPTS选项修改为如下:

#node3~node5各个节点修改hbase-env.sh中的HBASE_OPTS配置
export HBASE_OPTS="$HBASE_OPTS -XX:+UseConcMarkSweepGC -Djava.security.auth.login.config=/software/hbase-2.2.6/conf/zk-jaas.conf"

​​​​​​​​​​​​​​7) 修改HBase安装目录权限

在HBase各个节点创建HBASE_HOME/logs目录,如果该目录不存在需要提前创建,存在即可忽略,该目录为HBase日志目录,需要将该目录权限修改为root:hadoop、访问权限为770,否则hbase用户在启动Hbase集群时没有向该目录写日志权限。

#在node3~node5 HBase节点执行命令创建HBASE_HOME/logs
mkdir -p /software/hbase-2.2.6/logs

将各个节点的hbase安装目录权限修改为root:hadoop,logs目录访问权限为770:

#在node3~node5 HBase节点执行命令
chown -R root:hadoop  /software/hbase-2.2.6
chmod -R 770 /software/hbase-2.2.6/logs

​​​​​​​3. HBase启动及访问验证

在启动HBase集群之前,需要将Zookeeper和HDFS集群重启,Zookeeper和HDFS启动命令如下:

#停止hadoop集群
[root@node1 ~]# stop-all.sh 

#node3~node5节点,重启zookeeper
[root@node3 ~]# zkServer.sh restart
[root@node3 ~]# zkServer.sh restart
[root@node3 ~]# zkServer.sh restart

#启动HDFS集群
[root@node1 ~]# start-all.sh 

如果没有配置Kerberos认证时HBase之前启动过,在HDFS中将会有/hbase 目录,需要使用hdfs超级管理员用户将该目录的用户和所属组修改成hbase:hadoop。

#在node5节点执行
[root@node5 ~]# su hdfs
[hdfs@node5 ~]$ kinit hdfs
Password for hdfs@EXAMPLE.COM: 123456

[hdfs@node5 logs]$ hdfs dfs -ls /
Found 6 items
drwxr-xr-x   - root     supergroup          0 2023-05-23 10:50 /hbase

#修改用户和所属组
[hdfs@node5 logs]$ hadoop dfs -chown -R hbase:hadoop /hbase

在HBase主节点node4上执行如下命令启动HBase集群:

#无需切换hbase用户,可以直接在node4节点执行如下命令启动hbase集群
[root@node4 ~]# sudo -i -u hbase start-hbase.sh

注意:以上启动Hbase集群命令中没有切换到hbase用户,sudo为使用超级用户权限执行命令,-i表示交互模式执行命令,-u指定切换的用户。

HBase启动后,可以通过http://node4:16010进行访问:

​​​​​​​4. HBase Shell操作HBase

在node3~node5任意节点登录hbase shell,可以看到如果节点没有进行用户认证,读取HBase数据时没有权限:

#假设在node4登录hbase客户端
[root@node4 ~]# klist
klist: No credentials cache found (filename: /tmp/krb5cc_0)

[root@node4 ~]# hbase shell
hbase(main):001:0> list
TABLE                                                                                                                                            

ERROR: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)

如果想要正常读取HBase中的数据需要进行客户端认证,这里以zhangsan用户为例,进行Kerberos主体认证,认证后操作HBase,操作如下:

#进行用户认证
[root@node4 ~]# kinit zhangsan
Password for zhangsan@EXAMPLE.COM: 123456
[root@node4 ~]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: zhangsan@EXAMPLE.COM

#登录hbase shell
[root@node4 ~]# hbase shell
                                                                                                                           
hbase(main):001:0> create 'person','cf1','cf2'
Created table person

hbase(main):002:0> list
person

hbase(main):003:0> put 'person','row1','cf1:id','1'
                                                                                                                        
hbase(main):004:0> put 'person','row1','cf1:name','zs'
                                                                                                                          
hbase(main):005:0> put 'person','row1','cf1:age',18
                                                                                                                       
hbase(main):006:0> scan 'person'
ROW                                   COLUMN+CELL                                                                                                
 row1                                 column=cf1:age, timestamp=1684317908851, value=18                                                          
 row1                                 column=cf1:id, timestamp=1684317879179, value=1                                                            
 row1                                 column=cf1:name, timestamp=1684317894358, value=zs 

​​​​​​​5. Java API操作HBase

java API操作经过Kerberos安全认证的HBase按照如下步骤实现即可。

1) 准备krb5.conf文件

将node1 kerberos服务端/etc/krb5.conf文件存放在IDEA项目中的resources资源目录中或者本地Window固定的某个目录中,用于编写代码时指定访问Kerberos的Realm。

2) 生成用户keytab文件

在kerberos服务端node1节点上,执行如下命令,对zhangsan用户主体生成keytab密钥文件。

#在node1 kerberos服务端执行
[root@node1 ~]# kadmin.local -q "ktadd -norandkey -kt /root/zhangsan.keytab zhangsan@EXAMPLE.COM"

以上命令执行之后,在/root目录下会生成zhangsan.keytab文件,将该文件复制到IDEA项目中的resources资源目录中或者本地window固定的某个目录中,该文件用于编写代码时认证kerberos。

3) 准备访问HDFS需要的资源文件

将HDFS中的core-site.xml 、hdfs-site.xml 、yarn-site.xml、hbase-site.xml文件上传到项目resources资源目录中。

4) 编写代码操作********HBase

项目代码中引入如下maven依赖:

<!-- hbase依赖包 -->
<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-server</artifactId>
  <version>2.2.6</version>
</dependency>
<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-client</artifactId>
  <version>2.2.6</version>
</dependency>

编写Java代码操作Kerberos认证的HBase代码如下:

/**
 * Java API 操作Kerberos 认证的HBase
 */
public class OperateAuthHBase {

    private static Configuration conf;
    private static Connection connection;
    private static Admin admin;

    /**
     * 初始化:进行kerberos认证并设置hbase configuration
     */
    static {
        try {
            String principal = "zhangsan@EXAMPLE.COM";
            String keytabPath = "D:\\idea_space\\KerberosAuth\\KerberosAuthHBase\\src\\main\\resources\\zhangsan.keytab";

            conf = HBaseConfiguration.create();
            // 设置Kerberos 认证
            System.setProperty("java.security.krb5.conf", "D:\\idea_space\\KerberosAuth\\KerberosAuthHBase\\src\\main\\resources\\krb5.conf");
            conf.set("hadoop.security.authentication", "kerberos");
            UserGroupInformation.setConfiguration(conf);
            UserGroupInformation.loginUserFromKeytab(principal, keytabPath);

            //设置zookeeper集群地址及端口号
            conf.set("hbase.zookeeper.quorum","node3,node4,node5");
            conf.set("hbase.zookeeper.property.clientPort","2181");

            //创建连接
            connection = ConnectionFactory.createConnection(conf);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    public static void main(String[] args) throws IOException {
        try{
            //获取Admin对象
            admin = connection.getAdmin();

            //创建表
            createHBaseTable("tbl1", "cf1");
            System.out.println("===========================");

            //查看Hbase中所有表
            listHBaseTables();
            System.out.println("===========================");

            //向表中插入数据
            putTableData("tbl1","row1", "cf1", "id", "100");
            putTableData("tbl1","row1", "cf1", "name", "zs");
            putTableData("tbl1","row1", "cf1", "age", "18");

            putTableData("tbl1","row2", "cf1", "id", "200");
            putTableData("tbl1","row2", "cf1", "name", "ls");
            putTableData("tbl1","row2", "cf1", "age", "19");
            System.out.println("===========================");

            //查询表中的数据
            scanTableData("tbl1");
            System.out.println("===========================");

            //查询指定row数据
            getRowData("tbl1", "row1","cf1","name");
            System.out.println("===========================");

            //删除指定row数据
            deleteRowData("tbl1", "row1","cf1","name");
            System.out.println("===========================");

            //查询表中的数据
            scanTableData("tbl1");
            System.out.println("===========================");

            //删除表
            deleteHBaseTable("tbl1");

            //查看Hbase中所有表
            listHBaseTables();
            System.out.println("===========================");
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(admin != null) {
                admin.close();
            }
            if(connection != null) {
                connection.close();
            }
        }

    }

    //判断表是否存在
    private static boolean isTableExist(String tableName) {
        try {
            return admin.tableExists(TableName.valueOf(tableName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    private static void createHBaseTable(String tableName, String... cfs) {
        if(isTableExist(tableName)) {
            System.out.println("表已经存在!");
            return;
        }
        if(cfs == null || cfs.length == 0){
            System.out.println("列族不能为空!");
            return;
        }
        TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName));
        List<ColumnFamilyDescriptor> cFDBList = new ArrayList<>();
        for (String cf : cfs) {
            cFDBList.add(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(cf)).build());
        }
        tableDescriptorBuilder.setColumnFamilies(cFDBList);
        try {
            admin.createTable(tableDescriptorBuilder.build());
            System.out.println("创建表" + tableName + "成功!");
        } catch (IOException e) {
            System.out.println("创建失败!");
            e.printStackTrace();
        }

    }

    //查看Hbase中所有表
    private static void listHBaseTables() {
        try {
            TableName[] tableNames = admin.listTableNames();
            System.out.println("打印所有命名空间表名:");
            for (TableName tableName : tableNames) {
                System.out.println(tableName);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //向表中插入数据
    private static void putTableData(String tableName, String rowKey, String cf, String column, String value) {
        Table table = null;
        try {
            table = connection.getTable(TableName.valueOf(tableName));
            Put p = new Put(Bytes.toBytes(rowKey));
            p.addColumn(Bytes.toBytes(cf), Bytes.toBytes(column), Bytes.toBytes(value));
            table.put(p);
            System.out.println("插入数据成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeTable(table);
        }


    }

    //查询表中的数据
    private static void scanTableData(String tableName) {
        if(tableName == null || tableName.length() == 0) {
            System.out.println("请正确输入表名!");
            return;
        }
        Table table = null;
        try {
            table = connection.getTable(TableName.valueOf(tableName));
            Scan scan = new Scan();

            ResultScanner resultScanner = table.getScanner(scan);
            Iterator<Result> iterator = resultScanner.iterator();
            while(iterator.hasNext()) {
                Result result = iterator.next();
                Cell[] cells = result.rawCells();
                for(Cell cell : cells) {
                    //得到rowkey
                    System.out.println("rowkey: " + Bytes.toString(CellUtil.cloneRow(cell)));
                    //得到列族
                    System.out.println("列族: " + Bytes.toString(CellUtil.cloneFamily(cell)));
                    System.out.println("列: " + Bytes.toString(CellUtil.cloneQualifier(cell)));
                    System.out.println("值: " + Bytes.toString(CellUtil.cloneValue(cell)));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeTable(table);
        }
    }

    //查询指定row数据
    private static void getRowData(String tableName, String rowkey,String colFamily, String col) {
        Table table = null;
        try {
            table = connection.getTable(TableName.valueOf(tableName));
            Get g = new Get(Bytes.toBytes(rowkey));
            // 获取指定列族数据
            if(col == null && colFamily != null) {
                g.addFamily(Bytes.toBytes(colFamily));
            } else if(col != null && colFamily != null) {
                // 获取指定列数据
                g.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col));
            }
            Result result = table.get(g);
            System.out.println("查询指定rowkey 数据如下");

            for(Cell cell : result.rawCells()) {
                //得到rowkey
                System.out.println("rowkey: " + Bytes.toString(CellUtil.cloneRow(cell)));
                //得到列族
                System.out.println("列族: " + Bytes.toString(CellUtil.cloneFamily(cell)));
                System.out.println("列: " + Bytes.toString(CellUtil.cloneQualifier(cell)));
                System.out.println("值: " + Bytes.toString(CellUtil.cloneValue(cell)));
            }

        } catch (IOException e) {


### 给大家的福利


**零基础入门**


对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)


同时每个成长路线对应的板块都有配套的视频提供:


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)


因篇幅有限,仅展示部分资料


网络安全面试题


![](https://img-blog.csdnimg.cn/img_convert/80674985176a4889f7bb130756893764.png)


绿盟护网行动


![](https://img-blog.csdnimg.cn/img_convert/9f3395407120bb0e1b5bf17bb6b6c743.png)


还有大家最喜欢的黑客技术


![](https://img-blog.csdnimg.cn/img_convert/5912337446dee53639406fead3d3f03c.jpeg)


**网络安全源码合集+工具包**


![](https://img-blog.csdnimg.cn/img_convert/5072ce807750c7ec721c2501c29cb7d5.png)


![](https://img-blog.csdnimg.cn/img_convert/4a5f4281817dc4613353c120c9543810.png)

**所有资料共282G**,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值