本文目的:整合prestosql333使用Ambari中的ranger0.7.1进行资源权限控制
在搭建整合前,先对ranger各个角色有个大概认知
同时我把这篇文章涉及到使用编译好的plugin都分享给大家,百度云网盘自取:
链接:https://pan.baidu.com/s/1QC2pWRSeph7aN7IBNwKLfg
提取码:zpy5
如果你希望使用trino整合ranger,请参考我写的另一篇文章对ranger的presto原生插件进行改造:trino整合ranger
一、ranger介绍
Ranger 是大数据领域的一个集中式安全管理框架,实现对 Hadoop 生态组件的集中式安全管理。用户可以通过 Ranger 实现对集群中数据的安全访问,它主要是对 Hadoop 平台组件进行监管、启动服务以及资源访问进行控制,其核心思想为:
- 用户可以使用 Ranger 提供的 REST API 或者使用 Ranger 提供 Web UI 对大数据组件进行集中化管理。
- 可以针对大数据组件进行基于角色、属性进行授权。
- 针对大数据组件所涉及到安全的审计进行集中管理。
Ranger 主要是由 Ranger Admin、Ranger UserSync、Ranger Plugin 三个组件构成的,其中 Ranger Admin、Ranger UserSync 都是一个单独的 JVM 进程,而 Ranger Plugin 需要根据不同组件安装在不同节点上。
比如prestosql和ranger整合时,需要有presto-ranger-plugins的实现,将这个插件对应的jar包配置到presto的cordinator即可实现通过定时拉取rangerAdmin保存的policy来鉴权
-
** Ranger Admin**:管理用户配置好的策略及创建的服务、审计日志及 Report、将配置好的策略及创建的服务持久化到数据库中并提供给 Plugin 定期查询。
一般来说,我们实现的plugin或者ranger自带实现的plugin安装到对应的组件的时候,都会启动一个PolicyRefresher线程,每隔30秒拉取一次最新的策略,缓存到本地。
-
Ranger UserSync:将 LDAP、File、Unix 的相关信息同步到 Ranger Admin 中,例如,将用户的 LDAP 目录访问系统或者 Unix 中用户的信息及组信息进行同步,同步 Unix 用户及组信息需要开启 unixAuthenticationService 进程,同时对同步过来的信息进行持久化。
-
Ranger Plugin:Plugin 会被部署在需要的服务节点中,并会定期到 Ranger Admin 同步策略信息。
二、prestosql集成ranger
1、环境准备
请准备好prestosql-333版本和ranger2.1.0.tar.gz以及ranger0.7.1.tar.gz
其中如果你的ranger如果是2.0.0以上的版本,部署好了之后,只需要安装插件就可以使用。但是本文有点特殊,具体的需求如下:
公司的ranger0.7.1版本在ambari安装使用了很久很久,如果对其升级的话,会比较麻烦,但是ranger0.7.1中并无拓展presto的支持,故此,这里将ranger2.1.0的ranger-plugin的实现,加载到ranger-admin中,然后再讲ranger2.1.0的插件安装到prestosql333中,实现权限控制。
2、具体流程
1、下载ranger2.1.0
git clone https://github.com/apache/ranger.git
解压,导入到idea中。或者你不用idea直接解压也ok,idea为了方便看代码,后续做插件修改之类的。
修改ranger根目录的pom.xml文件
<repository>
<id>apache.snapshots.https</id>
<name>Apache Development Snapshot Repository</name>
<!-- <url>https://repository.apache.org/content/repositories/snapshots</url>-->
<url>https://repo1.maven.org/maven2/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>apache.public.https</id>
<name>Apache Development Snapshot Repository</name>
<url>https://repository.apache.org/content/repositories/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
然后键入打包命令
mvn -DskipTests=true clean compile package install assembly:assembly
ls target/
#target 目录下为所有压缩包
打包完成如上图所示。
2、presto-ranger的plugin安装
随后,我们获取到 ranger-2.1.0-presto-plugin.tar.gz 进行解压,然后修改其中的install.properties
# Location of Policy Manager URL
# Example: POLICY_MGR_URL=http://policymanager.xasecure.net:6080 你的ranger地址
POLICY_MGR_URL=http://10.5.xxx.xxx:6080
# This is the repository name created within policy manager
# Example: REPOSITORY_NAME=prestodev
#注意,这里的名称必须和你再ranger配置presto时起的策略管理模块名称一致
REPOSITORY_NAME=prestodev
#Presto component installed directory
#COMPONENT_INSTALL_DIR_NAME=../presto
#你的presto地址,定位到家目录
COMPONENT_INSTALL_DIR_NAME=/opt/app/presto-server-333
#为了简单,此处不开启审计功能
XAAUDIT.SOLR.ENABLE=false
#虽然文档中没有提及,不设置的话,enable-presto-plugin.sh脚本执行出错
XAAUDIT.SUMMARY.ENABLE=false
以root身份执行脚本./enable-presto-plugin.sh
+ Fri Feb 18 15:58:50 CST 2022 : Saving current JCE file: /etc/ranger/prestodev/cred.jceks to /etc/ranger/prestodev/.cred.jceks.20220218155850 ...
+ Fri Feb 18 15:58:51 CST 2022 : Saving current JCE file: /etc/ranger/prestodev/cred.jceks to /etc/ranger/prestodev/.cred.jceks.20220218155851 ...
backup of /opt/presto-precluster/trino/presto-server-333/etc/access-control.properties to /opt/presto-precluster/trino/presto-server-333/etc/.access-control.properties.20220218155852 ...
Add or Update properties file: [/opt/presto-precluster/trino/presto-server-333/etc/access-control.properties] ...
Property access-control.name updated successfully with : 'ranger'
Linking config files
Ranger Plugin for presto has been enabled. Please restart presto to ensure that changes are effective.
执行完成后,你会发现presto-server-333目录的etc和plugins目录下多出了ranger插件安装好的jar和xml文件。
etc目录:
-rw-r--r-- 1 root root 27 Feb 18 15:58 access-control.properties
drwxr-xr-x 2 root root 81 Feb 10 15:34 catalog
-rw-r--r-- 1 root root 805 Feb 10 18:10 config.properties
-rw-r--r-- 1 root root 803 Feb 10 16:53 config.properties-2
-rw-r--r-- 1 root root 256 Feb 9 16:39 hdfs_jaas.conf
-rw-r--r-- 1 root root 362 Feb 10 16:57 jvm.config
-rw-r--r-- 1 root root 27 Feb 9 16:39 log.properties
-rw-r--r-- 1 root root 78 Feb 9 16:46 node.properties
-rwxr--r-- 1 presto presto 2065 Feb 18 15:58 ranger-policymgr-ssl.xml
-rwxr--r-- 1 presto presto 11599 Feb 18 15:58 ranger-presto-audit.xml
-rwxr--r-- 1 presto presto 2665 Feb 18 15:58 ranger-presto-security.xml
-rw-r--r-- 1 presto presto 69 Feb 18 15:58 ranger-security.xml
plugin:
lrwxrwxrwx 1 root root 79 Feb 18 15:58 bootstrap-0.192.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/bootstrap-0.192.jar
lrwxrwxrwx 1 root root 78 Feb 18 15:58 bval-jsr-2.0.0.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/bval-jsr-2.0.0.jar
lrwxrwxrwx 1 root root 83 Feb 18 15:58 configuration-0.192.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/configuration-0.192.jar
lrwxrwxrwx 1 root root 78 Feb 18 15:58 guava-26.0-jre.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/guava-26.0-jre.jar
lrwxrwxrwx 1 root root 75 Feb 18 15:58 guice-4.2.2.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/guice-4.2.2.jar
lrwxrwxrwx 1 root root 90 Feb 18 15:58 javax.annotation-api-1.3.2.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/javax.annotation-api-1.3.2.jar
lrwxrwxrwx 1 root root 78 Feb 18 15:58 javax.inject-1.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/javax.inject-1.jar
lrwxrwxrwx 1 root root 73 Feb 18 15:58 log-0.192.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/log-0.192.jar
lrwxrwxrwx 1 root root 81 Feb 18 15:58 log-manager-0.192.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/log-manager-0.192.jar
lrwxrwxrwx 1 root root 95 Feb 18 15:58 ranger-plugin-classloader-2.1.0.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/ranger-plugin-classloader-2.1.0.jar
lrwxrwxrwx 1 root root 85 Feb 18 15:58 ranger-presto-plugin-impl -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/ranger-presto-plugin-impl
lrwxrwxrwx 1 root root 95 Feb 18 15:58 ranger-presto-plugin-shim-2.1.0.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/ranger-presto-plugin-shim-2.1.0.jar
lrwxrwxrwx 1 root root 80 Feb 18 15:58 slf4j-api-1.7.25.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/slf4j-api-1.7.25.jar
lrwxrwxrwx 1 root root 90 Feb 18 15:58 validation-api-2.0.1.Final.jar -> /opt/presto-precluster/trino/ranger-2.1.0-presto-plugin/lib/validation-api-2.0.1.Final.jar
Ranger访问策略本地缓存目录 /etc/ranger/ 请确保这个目录有访问权限。
目录权限修改为presto启动用户
3、ambari的ranger0.7.1提供对presto的支持
同样,在ranger2.1.0的/agents-common/src/main/resources/service-defs路径下找到ranger-servicedef-presto.json文件。
https://blog.csdn.net/hncscwc/article/details/120052354 这篇博客有详细讲解这个定义文件的每一个key的含义,如果有调整需求可以参考修改
然后键入
curl -u admin:admin -X POST -H "Accept: application/json" -H "Content-Type: application/json" -d @ranger-servicedef-presto.json "http://xx.xx.xx.xx:6080/service/public/v2/api/servicedef"
将这个presto定义的策略,上传到ranger0.7.1的服务器中,登录就可以查看到多出了presto选项。
配置策略,生成prestodev的policy管理模块
当你发现,连接的时候不通,你可以去查看ranger的日志,你会发现缺少presto的jar包。我们要做的是需要将prestosql用到的连接jar包发上ranger0.7.1中,具体plugin的jar包存放位置在ranger-release-ranger-0.7.1/target/ranger-0.7.1-admin/ews/webapp/WEB-INF/classes/ranger-plugins/
创建presto目录,并将其修改成ranger用户和用户组
[root@xx ranger-plugins]# chown ranger:ranger presto/
[root@xx ranger-plugins]# ll
total 0
drwxr-xr-x 2 ranger ranger 52 Jun 22 2018 atlas
drwxr-xr-x 2 ranger ranger 214 Jun 22 2018 hbase
drwxr-xr-x 2 ranger ranger 51 Jun 22 2018 hdfs
drwxr-xr-x 2 ranger ranger 249 Jun 22 2018 hive
drwxr-xr-x 2 ranger ranger 52 Jun 22 2018 kafka
drwxr-xr-x 2 ranger ranger 50 Jun 22 2018 kms
drwxr-xr-x 2 ranger ranger 188 Jun 22 2018 knox
drwxr-xr-x 2 ranger ranger 51 Jun 22 2018 nifi
drwxr-xr-x 2 ranger ranger 6 Feb 18 16:16 presto
drwxr-xr-x 2 ranger ranger 51 Jun 22 2018 solr
drwxr-xr-x 2 ranger ranger 52 Jun 22 2018 storm
drwxr-xr-x 2 ranger ranger 120 Jun 22 2018 yarn
上传ranger-2.1.0对应这个目录下的presto引用的jar包即可。
root@ubuntu:/home/luohaizhang/ideaProjects/ranger/ranger-release-ranger-0.7.1/target/ranger-0.7.1-admin/ews/webapp/WEB-INF/classes/ranger-plugins/presto# ll
total 7096
drwxr-xr-x 2 root root 4096 Feb 16 11:10 ./
drwxr-xr-x 14 ranger ranger 4096 Feb 16 11:07 ../
-rw-r--r-- 1 root root 6591116 Feb 16 11:10 presto-jdbc-333.jar
-rw-r--r-- 1 root root 609360 Feb 16 11:10 presto-spi-333.jar
-rw-r--r-- 1 root root 49316 Feb 16 10:22 ranger-presto-plugin-2.1.0.jar
加入后不用重启,直接test Connection ,你可能还会收到connection failed,此时不是你的问题。直接点击save。等ranger默认生成好策略后,再次尝试,你就发现testConnection返回成功了。
此时就可以配置相应的对策了。
3、配置ranger对策注意事项
ranger配置好了之后,需要做的是在ranger设置权限,然后通过prestosql访问,验证是否ok。但presto通过ranger权限校验这一步,有些注意点,这里可以参考https://help.aliyun.com/document_detail/156416.html#p-1uo-eyy-3d9
这篇文章介绍的是E-MapReduce平台的ranger配置。不过他们可能做了些小的调整,比如说在rangerAdmin界面配置policy的时候,在选择catalogs时可以单独选择。而如果你使用的是官方ranger提供的ranger-servicedef-presto.json文件来整合的ranger,则该界面会要求你必须填写catalog和tablename和column。
Ranger Presto权限控制与Ranger Hive和Ranger Hbase等权限控制不同,Ranger Presto采用的是权限分层次控制的策略。
- 配置的权限应该与所属的层次保持一致。如果配置的权限与所属的层次不相符,则该权限配置将不起作用。
- Presto会对用户进行两次权限检查,首先检查该用户是否有访问Catalog的权限,其次检查本次访问所涉及到的权限。
基于上面提供的ranger的presto权限配置案例。这里讲解下,使用官方ranger的时候,如何去配置presto权限来控制用户访问presto资源。
下面几个样例,以hive用户访问presto为例子。在presto服务器上可以通过presto-cli连接上prestoserver。然后使用 --user hive指定连接的用户
一定要指定,否则无权限访问。
键入命令
./jdk-11.0.14/bin/java -jar presto-cli-333-executable.jar --server http://localhost:8999 --catalog mysql-dmp --schema test --user hive
jdk自己指定,用jdk8也行。
样例一、配置catalog的访问权限
用户hive想要访问catalog:mysql-dmp。此时需要如下配置:
具体的权限permissions的用法和上面发的文档链接一样。参考配置即可。
样例二、配置访问某个具体catalog下的schema
当然,如果你想要使用show table命令,你还要新建一个policy,指定如下配置
具体的原因是:
- 如果您需要执行
show schemas
命令,则需要配置对Catalog的Show权限。同理,如果您需要执行show tables
命令,则需要配置对Schema的Show权限。 - 因为Presto在鉴权完成后,还会对获取到的Schema和Table的列表进行一次筛选,只显示具有Select权限的Schema和Table,所以您还需要配置Schema和Table的Select权限。当您在执行Show命令时,只会显示出具有Select权限的Schema和Table。
- 只有拥有Catalog的Select权限时,才能显示出该Catalog下您具有权限的Schema和Table
参考上面发的文档连接,有更详细说明
样例三、配置访问某个表
首先你要配置hive用户能够访问到这个表所属的catalog(样例一),然后能访问到对应的schema(样例二),最后才配置访问具体的表。
表的配置所选择的catalog和schema,请确保你有权限访问。因为ranger在校验presto表层级的资源访问权限时,会先访问是否有catalog资源权限(查询你是否有将这个用户加入到这个catalog资源下,参考样例一)。然后会访问你是否有catalog对应的这个schema的访问权限。是分开不同policy来逐一判断的。不懂的可以看上面发的文档连接。
然后表一层的policy只是在前面catalog和schema权限校验通过后,用于校验表和对应的列的。按需求配置即可。
以上就是比较常用的权限配置,在配置的时候按照样例一、样例二、样例三逐个配置就可以限制某个用户访问某个表的资源和某个列的资源了。
4、问题总结
1、按照上述配置弄好后,通过ssl连接开启kerberos访问权限的presto的时候提示
“Access Denied: User xxx@EMR.xxx.COM cannot impersonate user xxx”。
此时您需要修改config.properties
配置文件,先添加自定义配置,设置http-server.authentication.krb5.user-mapping.pattern
的值为(.+)@EMR\\.[0-9]+\\.COM**
,然后重启PrestoMaster。
当然,这个表达式的值要符合上面提示的信息。
2. 出现在ranger中配置用户组权限不起作用
问题的描述为在ranger中配置的用户组,启用某个权限,但是在presto使用某个用户且该用户为这个组内的成员时,访问启用的这一资源时,仍然报无权限错误。而单独配置该用户名称使用这个权限就可以。
那么这种情况通过debug presto-ranger插件的源码,进入到RangerSystemAccessControl
中的createAccessRequest
方法,这个方法就是获取presto客户端的具体用户组权限(也就是访问presto时,–user指定用户的所属用户组)。
private RangerPrestoAccessRequest createAccessRequest(RangerPrestoResource resource, SystemSecurityContext context, PrestoAccessType accessType) {
Set<String> userGroups = null;
//默认为false
if (this.useUgi) {
UserGroupInformation ugi = UserGroupInformation.createRemoteUser(context.getIdentity().getUser());
String[] groups = ugi != null ? ugi.getGroupNames() : null;
if (groups != null && groups.length > 0) {
userGroups = new HashSet(Arrays.asList(groups));
}
} else {
userGroups = context.getIdentity().getGroups();
}
RangerPrestoAccessRequest request = new RangerPrestoAccessRequest(resource, context.getIdentity().getUser(), (Set)userGroups, accessType);
return request;
}
通过debug发现this.useUgi默认是false,于是走了系统默认的组权限,发现默认groups为空,故获取不到user指定用户的组权限,进而在后面ranger权限校验的时候,报无权限异常。而开启了useUgi参数后,会根据当前的user进行远程kerberos认证,认证后便可以通过ugi拿到具体的用户组,实现组的权限校验。
那么useUgi又在哪个配置文件可以指定这个参数呢?这里你可以顺着代码往上找,最终发现他是读取presto安装目录下的etc/access-control.properties
的ranger.use_ugi
参数,我们只需要手动指定为true即可:
access-control.name=ranger
ranger.use_ugi=true