4.kerberos 与 sentry 原理及使用

教程 阿布都的都 ⋅ 于 2023-01-06 17:18:44 ⋅ 1081 阅读

1. 安全认证与权限管理的必要性

  • 非安全集群

    没有安全认证的集群,任何用户都可以进行Hadoop命令操作,权限管理混乱,是个用户就能查询,毫无安全保证。

file

  • 安全认证集群

    安全认证集群,非法用户即使能够登陆操作系统,也不能操作Hadoop集群,必须通过安全认证才可以操作集群数据。集群与数据安全都得到了保障。

file

  • 多租户设计愿景

    我们期望合理规划用户,并且针对不同用户开放不同的数据权限,乃至于不同用户分配不同的资源,如企业中有多个部门,我们可以针对不同的部门创建相应的用户,并且对用户进行安全认证,然后针对用户做数据权限管理,每个部门只能访问到有权限的数据,避免跨部门数据使用,甚至误删除。

    多租户设计:

    ​ 1)数据管理

    ​ hive的库、表、字段等。

    ​ hbase的命名空间、表、列族等。

    ​ 2)资源管理

    ​ yarn 的 CPU、内存、io(磁盘和网络)

    ​ 资源池配置

    ​ 资源调度:公平调度

file

2. kerberos

2.1 kerberos原理

​ Kerberos是一个用于鉴定身份(authentication)的协议, 它采取对称密钥加密(symmetric-key cryptography),密钥不会在网络上传输。在Kerberos中,未加密的密码(unencrypted password)不会在网络上传输,因此攻击者无法通过嗅探网络来偷取用户的密码。

​ 在cdh大数据平台中充当这秘钥的角色,cdh平台中组件会集成kerberos服务,意味着一旦开启,在请求访问组件服务时必须先通过kerberos秘钥认证。

在keberos Authentication中,Kerberos有三个实体:Client、Server和 KDC(包含 AS 和 TGS)。

2.1.1 keberos 术语说明

​ KDC(key distribution center):密钥发放中心。

​ AS(authentication service):认证服务,索取身份信息,发放 TGT。

​ TGS(ticket granting service):票据授权服务,索取TGT,发放ST。

​ TGT(ticket granting ticket):票据授权票据,由KDC的AS发放,有有效期。有了这个票据,可以申请多个server的票据。

​ ST(server ticket):服务票据,由KDC的TGS发放,访问任何的server都需要一张有效的ST。

​ Authenticator:验证器,与票据结合用来证明提交票据的client就是其所声明的身份,内容包括{user, address, start_time, lifetime},验证器是 client 自己构建,只能“被使用一次”。

秘钥说明:

长秘钥:长期保持不变的秘钥,时间充足的话,容易被破解。

​ 每个实体有自己的长秘钥:

​ client 的长秘钥: 原理图简称 cmk。

​ KDC 的长秘钥:原理图简称 kmk。

​ server的长秘钥:原理图简称 smk。

短秘钥(sessionkey):经常变动的秘钥,有过期时间,没有充足的时间,不容易破解。

​ lk:client 与 KDC 间 数据传输和身份验证。

​ sk: client 与 server 间 数据传输和身份验证。

2.1.2 原理图与认证过程

file

Kerberos认证的过程:

​ 1)Client向KDC(AS)发起请求需要一个TGT,TGT是Server无关的,即用一个TGT可以申请多个Server的ticket。发送的请求中包含用Client长秘钥(cmk)加密的一些信息(包括ClientName,timestamp,TGS ServerName)。

​ 2)AS收到Client发来的请求,从数据库中拿到Client的长秘钥(cmk)进行解密,验证ClientName和Timestamp。

​ 3)验证通过后给Client发送一个response,该response中包括两部分:

​ 用Client长秘钥(cmk)加密的短秘钥(lk)

​ 用KDC长秘钥(kmk)加密的TGT,该TGT里面也包含了短秘钥lk(用于后面解密TGT,因为KDC不保留任何短秘钥lk),还包含了ClientName和过期时间。

​ 以上就是Kinit 做的事情。

​ 真正运行访问Service的程序时,进行一下步骤:

​ 4)Client向TGS发送一个请求,其中包括:

​ 用KDC长秘钥(kmk)加密的TGT

​ 用短秘钥(lk)加密的Authenticator(自己的信息)

​ 要访问的Server Name

​ 5)TGS收到Client发来的请求,先用KDC的长秘钥(kmk)解密TGT,拿到了短秘钥(lk),再用短秘钥(lk)解密Authenticator进行Client信息验证。

​ 6)验证通过则向Client发送一个response,其中包括:

​ 用短秘钥(lk)加密的短秘钥(sk)

​ 使用Server的长秘钥(smk)进行加密的ST,这个ST里面包含了短秘钥(sk)以及 Client的一些信息(这里称为ClientInfo)

​ 7)Client收到TGS发来的response后,用短秘钥(lk)解密得到短秘钥(sk), 向server发送请求,其中包括:

​ Client用短秘钥(sk)加密自己的Authenticator(包含ClientInfo2)

​ TGS发给client的加密ST一起发给Server

​ 8)Server收到这两组数据包后,先用server的长秘钥(smk)解密 ST,得到了ST里的短秘钥(sk)和C1Info, 然后再用短秘钥(sk)解密Authenticator,得到了Authenticator里的C1Info2。用C1Info1和C1Info2比较,如果相同即认证成功。

一段对白加深理解:

用户要去游乐场,首先要在门口检查用户的身份(即 CHECK 用户的 ID 和 PASS), 如果用户通过验证,游乐场的门卫 (AS) 即提供给用户一张门卡 (TGT)。

这张卡片的用处就是告诉游乐场的各个场所,用户是通过正门进来,而不是后门偷爬进来的,并且也是获取进入场所一把钥匙。

现在用户有张卡,但是这对用户来说不重要,因为用户来游乐场不是为了拿这张卡的而是为了游览游乐项目,这时用户摩天楼,并想游玩。

这时摩天轮的服务员 (server) 拦下用户,向用户要求摩天轮的 (ST) 票据,用户说用户只有一个门卡 (TGT), 那用户只要把 TGT 放在一旁的票据授权机 (TGS) 上刷一下。

票据授权机 (TGS) 就根据用户现在所在的摩天轮,给用户一张摩天轮的票据 (ST), 这样用户有了摩天轮的票据,现在用户可以畅通无阻的进入摩天轮里游玩了。

当然如果用户玩完摩天轮后,想去游乐园的咖啡厅休息下,那用户一样只要带着那张门卡 (TGT). 到相应的咖啡厅的票据授权机 (TGS) 刷一下,得到咖啡厅的票据 (ST) 就可以进入咖啡厅

当用户离开游乐场后,想用这张 TGT 去重新玩摩天轮,由于用户的 TGT 已经过期,进不去游乐场,在用户离开游乐场那刻开始,用户的 TGT 就已经被销毁。

2.2 kerberos使用

2.2.1 进入管理界面

kadmin.local

2.2.2 创建principal(认证主体)

使用管理员创建认证主体,即principal,principal由主体名@域名组成,域名一般都设置为公司的域名。

# 语法格式:
# addprinc -pw 密码 主体名@域名

# 创建hdfs认证主体
addprinc -pw hdfs hdfs@HAINIU.COM
# 创建hive 认证主体
addprinc -pw hive hive@HAINIU.COM
# 创建hbase 认证主体
addprinc -pw hbase hbase@HAINIU.COM

file

  • 生成keytab凭证

给主体principal生成keytab凭证,用于后面的kinit认证操作,此处的参数-norandkey意义为不随机生成密码,沿用创建主体时的密码,这样就可以即能使用keytab认证也能使用密码认证了。

# 语法格式:
# xst -norandkey -k 主体文件生成位置 主体名

# 生成hdfs的keytab
xst -norandkey -k /data/hdfs.keytab hdfs
# 生成hive的keytab
xst -norandkey -k /data/hive.keytab hive
# 生成hbase的keytab
xst -norandkey -k /data/hbase.keytab hbase

exit

file

2.2.3 kerberos认证

2.2.3.1 认证的两种方式

进行安全认证,共有两种方式,如下:

1)主体加密码的方式认证

此种方式适合测试用。

# 用主体加密码的方式认证
kinit hdfs
# 输入密码,即创建主体principal时-pw设置的密码
password
# 查看当前票据
klist

# 销毁当前票据
kdestroy

file

2)使用keytab认证

此种方式适合生产环境用,比如在脚本中加入认证。

# 使用keytab认证 参数kt意义为keytab文件路径 后面接要认证的主体名,keytab文件要和主体名一致
kinit -kt /data/hdfs.keytab hdfs

# 查看当前票据
klist

file

2.2.3.2 验证hadoop操作

通过安全认证后再操作Hadoop集群,验证是否可以正常使用Hadoop命令。

hadoop fs -ls /

file

2.3.3.3 认证的一些操作

# 查看票据
klist

# 销毁票据
kdestroy

# 删除主体(该操作需要管理员用户才能执行,需要进入kadmin.local界面下操作)
kadmin.local
    delprinc '主体名'

2.3.3.4 启用kerberos认证环境下连接hive

​ 在kerberos认证环境下连接hive,通过两种认证方式的任何一种认证都可以。连接时可以直接使用hive的client端连接,或者使用beeline的方式连接,由于hive集成sentry以后不能用hive client方式执行权限管理,所以推荐用beeline 连接方式。

# 先认证
kinit -kt /data/xxxx.keytab xxxx或者kinit xxxx 输入密码
# 后通过beeline连接hive, 在内部通过 !q 退出beeline
# hiveserver2服务地址: jdbc:hive2://worker-1:10000
# worker-1@HAINIU.COM 中的 worker-1 是对应的kerberos 服务端主机名
beeline -u "jdbc:hive2://worker-1:10000/;principal=hive/worker-1@HAINIU.COM"

file

3. sentry

3.1 sentry原理

sentry是Cloudera公司开源开源组件,后贡献给Apache,提供数据访问控制,并且支持细粒度权限控制,支持hive、impala、hbase等

sentry组成分为三部分:

  1. binding层

本层有两个功能实现:

  • 实现请求拦截

  • 接管grant/revoke功能
  1. policy engine层
  • 接收到binding层权限请求,对比provider层查询返回的服务端权限是否一致
  1. policy provider层
  • 查询服务端权限,沟通sentry权限管理元数据库

sentry权限管理流程图:

file

3.2 sentry权限管理-hive

3.2.1 kerberos 认证环境下连接hive

  • 通过kerberos认证连接hive
kinit -kt /data/hive.keytab hive
  • 使用kerberos认证方式登录hive

使用beeline的方式连接hive,第一个worker-1为hiveserver2所在节点的域名,第二个worker-1为kerberos的server服务器域名,不要混淆。

beeline -u "jdbc:hive2://worker-1:10000/;principal=hive/worker-1@HAINIU.COM"

3.2.2 sentry操作

sentry在hive中只能对用户组进行授权。

file

sentry一些常用操作,如下:

-- 创建角色
create role user1_role;
-- 查看角色列表
show roles;
-- 给角色赋予数据库权限
grant all on database db1 to role user1_role;
-- 给角色赋予表权限
grant select on table db2.test2 to role user1_role;
-- 给角色赋予表中的某一列的权限
grant select(id) on table db2.test2 to role user1_role;

-- 授权角色给用户组
grant role user1_role to group user1;

-- 查看角色权限
show grant role user1_role on database db1;
show grant role user1_role on table test1;

-- 查看某个组都授权了哪些角色
show role grant group hainiu;

-- 删除角色
drop role user1_role;

-- 权限收回
revoke select on table db2.test2 from role user1_role;
revoke all on database db2 from role user2_role;

3.2.2.1 准备测试用的库和表

开启sentry后的hive客户端不能授权,要用beeline。

1)创建超级管理员角色,并赋予hive

-- 认证
kinit hive 
-- 连接hive
beeline -u "jdbc:hive2://worker-1:10000/;principal=hive/worker-1@HAINIU.COM"

-- 创建超级角色
create role admin_role;
-- 给超级角色赋予server级别的所有权限
grant all on server server1 to role admin_role;

-- 其中: server1 是在sentry-site.xml 中配置
    <property>
        <name>sentry.hive.server</name>
        <value>server1</value>
     </property>

-- 给hive 赋予超级角色
grant role admin_role to group hive;
-- 查看hive的权限情况
show role grant group hive;

-- 注意:
--  可以将超级角色赋给linux其它用户组,这样其他用户组也有了超级权限。
--  如果只有sentry,每个用户如果用超级管理员登录,就没有权限
--  必须要kerberos 和 sentry 配套使用。

file

2)继续创建测试用的库和表

-- 创建db1库
create database db1;
-- 创建db2库
create database db2;
-- 在db2库中创建test1表
create table db2.test1(id string, name string);
-- 在db2库中创建test2表
create table db2.test2(id string, name string);

3.2.2.2 库、表、列权限测试

1)创建 user1 用户并创建user1 认证主体, 连接hive发现没有查看其它库的权限

useradd user1
passwd user1

# 进入kerberos管理界面
kadmin.local
# 创建 user1 认证主体
addprinc -pw user1 user1@HAINIU.COM

# 退出kerberos管理界面
exit

su - user1
# 没注册kerberos认证,不能执行hdfs
hadoop fs -ls /
# 注册后,可执行hdfs
kinit user1

hadoop fs -ls /
# 通过beeline连接hive
beeline -u "jdbc:hive2://worker-1:10000/;principal=hive/worker-1@HAINIU.COM"
# 发现user1用户没有权限操作hive
show databases;
create database db3;

file

2)用带有超级角色的hive用户创建user1_role角色

-- 创建角色 user1_role
create role user1_role;
-- 给角色赋予数据库权限
grant all on database db1 to role user1_role;

-- 查看角色权限
show grant role user1_role on database db1;

file

3) 给user1_role角色赋予库的权限

-- 给 user1 加入 user1_role角色,此时:该角色有db1库的所有权限
grant role user1_role to group user1;

-- 查看某个组都授权了哪些角色
show role grant group user1;

-- user1 有了操作db1库的所有权限
create table db1.test1(id int);
show tables in db1;
drop table db1.test1;
show tables in db1;

4) 给user1_role角色赋予表的权限

-- 给角色赋予表权限
-- 给 user1_role角色赋予db2.test1表的select权限,此时:该角色有db1库的所有权限、db2.test1的select权限
grant select on table db2.test1 to role user1_role;

-- 查看角色权限
show grant role user1_role on table db2.test1;

-- user1 又增加了能查询 db2.test1表的权限
select * from db2.test1;

file

5)给user1_role角色赋予表字段的权限

-- 给角色赋予表字段的权限
-- 给 user1_role角色赋予db2.test2表id字段的查询权限
-- 此时:该角色有db1库的所有权限、db2.test1的select权限、db2.test2的id字段的查询权限
grant select(id) on table db2.test2 to role user1_role;

-- 查看角色权限
show grant role user1_role on table db2.test2;

-- 能查询
select id from db2.test2;
-- 不能查询
select name from db2.test2;

file

6)收回user1_role角色中db2.test1 的select权限

-- 权限收回
revoke select on table db2.test1 from role user1_role;
-- 查看角色权限
show grant role user1_role on table db2.test1;
-- 查询 db2.test2 的 id字段不报错
select id from db2.test2;
-- 查询 db2.test1 报错
select * from db2.test1;

file

7)收回user1_role角色中db2 的all权限

revoke all on database db2 from role user1_role;

-- 查看角色权限
show grant role user1_role on database db2;

-- 查看db2库下的表只有default
show tables in db2;

file

8)删除角色

-- 删除角色
drop role user1_role;

-- 查看role列表
show roles;

3.3 sentry权限管理-hbase

3.3.1 Hbase ACLs的访问级别

HBase ACLs的访问分为5个级别:

​ Read(R) : 可以读取给定范围内数据的权限

​ Write(W) : 可以在给定范围内写数据

​ Executor(X) : 可以在指定表执行Endpoints类型的协处理

​ Create(C) : 可以在给定范围内创建和删除表(包括非该用户创建的表)

​ Admin(A) : 可以执行集群操作,如平衡数据等

3.3.2 hbase权限操作

3.3.2.1 使用普通用户测试

使用 user1 用户登录 hbase,此时user1 没有任何权限

# 安全认证
kinit -kt /data/user1.keytab user1
# 登陆hbase
hbase shell
# 查看当前登陆用户
whoami
# 查看命名空间(什么也没有)
list_namespace
# 创建表(不能创建)
create 'testacl','cf'

file

开启sentry后因为没有给user1用户授权所以该用户没有任何权限,list为空,也没有创建表的权限。

3.3.2.2 使用超级管理员测试

在cdh中hbase的超级管理员配置的为hbase用户,所以我们使用hbase用户做安全认证,然后进入hbase shell进行测试。

# 使用hbase用户进行认证,hbase的keytab生成需要kerberos管理员用户在kadmin.local中生成。
kinit -kt /data/hbase.keytab hbase
hbase shell
# 查看当前操作用户
whoami
# 查看命名空间列表
list_namespace
# 建表
create 'testacl','cf'
# 删表
disable 'testacl'
drop 'testacl'

file

可以发现超级用户是可以操作的,但是这不符合我们多租户设计的愿景

3.3.2.3 使用超级用户给普通用户授管理员权限

使用超级用户给普通用户授权,语法如下:


# ---【注意:这是语法,别执行】----------------
# CA权限 = RWXCA
# 给【user1用户组】赋予CA权限
grant '@user1', 'CA'

# 给【user1用户】赋予CA权限
grant 'user1', 'CA'

# user_permission是查看当前所有用户及组权限
user_permission '.*'
# 查看当前表的所有用户及组权限
user_permission '命名空间:表名'

给user1用户组赋予CA全局权限

# 给user1用户组赋予CA全局权限
grant '@user1', 'CA'

# 通过user_permission ‘.*’查看当前HBase所有的授权;
user_permission '.*'

赋权限后查看:

file

当为用户或用户组拥有CA权限时,用户和用户组创建表时会默认的为当前操作用户添加该表的RWXCA权限

file

注意:

​ 拥有Admin(A)权限的用户,可以为其它用户进行任何级别授权,在使用HBase授权时需要慎用;

​ 在CDH中HBase支持Global、NameSpace、Table、ColumnFamily范围授权,无法支持Row级别授权;

3.3.2.4 命名空间acl授权

给user2用户组赋予xinniu命名空间 CA权限

1)创建 user2用户并创建user2认证主体,连接hbase

useradd user2
passwd user2

# 进入kerberos管理界面
kadmin.local
# 创建 user1 认证主体
addprinc -pw user2 user2@HAINIU.COM

# 退出kerberos管理界面
exit

su - user2
hbase shell

2)给user2用户组赋予xinniu命名空间 CA权限

# 用超级用户创建xinniu命名空间
create_namespace 'xinniu'

# 给user2用户组赋予xinniu命名空间 CA权限
grant '@user2','RWXCA','@xinniu'

3)用user2操作xinniu命名空间

# 在xinniu命名空间下建表、查询都可以
create 'xinniu:testacl', 'cf'
scan 'xinniu:testacl'
# 但在default命名空间操作,就报错了
create 'testacl1', 'cf'

file

file

3.3.2.5 表acl授权

1)使用超级管理员用户,创建一个新的命名空间,并且创建两张表,同时插入数据

# 创建命名空间 xinniu1
create_namespace 'xinniu1'

# 创建表 xinniu1:tableacl
create 'xinniu1:tableacl','cf'
put 'xinniu1:tableacl','x0002','cf:datadate','20210518'

# 创建表 xinniu1:tableacl1
create 'xinniu1:tableacl1','cf'
put 'xinniu1:tableacl1','x0002','cf:datadate','20210518'

2)给 user2 用户 赋予 xinniu1:tableacl 表的所有权限

grant 'user2','RWXCA','xinniu1:tableacl'

3)使用user2用户进行测试

# 查看 xinniu1命名空间下的表,发现只能看到 tableacl表
list_namespace_tables 'xinniu1'
# 也只能查询tableacl表
scan 'xinniu1:tableacl'

# 由于查询tableacl1表没有权限,所以权限错误
scan 'xinniu1:tableacl1'

file

由于查询tableacl1表没有权限,所以权限错误

file

3.3.2.6 列族acl授权

1)使用管理员创建 xinniu1:tableacl2表 并添加数据

# 创建多列族表
create 'xinniu1:tableacl2', 'cf1', 'cf2'

# 添加数据
put 'xinniu1:tableacl2', 'X0001', 'cf1:name', 'n1'
put 'xinniu1:tableacl2', 'X0001', 'cf2:datadate', '20210518'
put 'xinniu1:tableacl2', 'X0002', 'cf1:name', 'n2'
put 'xinniu1:tableacl2', 'X0002', 'cf2:datadate', '20210518'

2)使用管理员给 user2 用户 赋予 xinniu:tableacl1 表 cf1列族赋予 RW权限

grant 'user2','RW','xinniu1:tableacl2','cf1'

3)使用user2用户进行测试

# 查看xinniu1命名空间的表列表里有 tableacl2
list_namespace_tables 'xinniu1'
# 但查询的时候,只能查询出cf1列族
scan 'xinniu1:tableacl2'

file

3.3.2.6 权限收回

1)收回 表的权限

# ***管理员操作***
# 收回 user2 用户的 赋予 xinniu1:tableacl2 表的所有权限
revoke 'user2', 'xinniu1:tableacl2', 'cf1'

# ***user2操作***
# 查看xinniu1命名空间的表列表里没有 tableacl2
list_namespace_tables 'xinniu1'

file

2)收回命名空间权限

要先收下收回命名空间下表的权限

# ***管理员操作***
# 收回 user2 用户的 赋予 xinniu:testacl 表的所有权限
revoke 'user2', 'xinniu:testacl'

user_permission '.*'

# ***user2操作***
# 查看命名空间列表,此时没有xinniu
list_namespace

# 查看表列表,此时里面没有 xinniu:testacl
list
版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-阿布都的都,http://hainiubl.com/topics/76032
成为第一个点赞的人吧 :bowtie:
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter