介绍

Aapche Ranger是以插件的形式集成到HDFS中,由Ranger Admin管理访问策略,Ranger插件定期轮询Admin更新策略到本地,并根据策略信息进行用户访问权限的判定。其中提供管理员管理策略、插件的Ranger web和Ranger Plugin,与Admin之间的通信是基于HTTP的RESTful架构。Ranger集成HDFS的架构图如下:

Ranger对HDFS访问控制的实现原理

HDFS本身是有访问控制机制的,即在身份认证机制之后通过查询ACLs来对用户的权限检查,该权限检查的实现代码是INodeAttributeProvider抽象类中接口AccessControlEnforcer的checkPermission方法。Ranger将HDFS NameNode 的Inode attribute的提供类即INodeAttributeProvider抽象类修改为Ranger自己写的类,该类继承了INodeAttributeProvider抽象类。即在hdfs-site.xml文件中修改如下配置项。

<name>dfs.namenode.inode.attributes.provider.class</name>
<value>org.apache.ranger.authorization.hadoop.RangerHdfsAuthorizer</value>

Ranger 插件的初始化过程

动态加载类

在Namenode启动过程中编译RangerHdfsAuthorizerorizer类(包名为ranger-hdfs-plugin-shim),将RangerHdfs的相关类动态加载进虚拟机,并实例化具体实现类RangerHdfsAuthorizerorizer(包名为ranger-hdfs-plugin)。

 rangerPluginClassLoader = RangerPluginClassLoader.getInstance(RANGER_PLUGIN_TYPE, this.getClass());
@SuppressWarnings("unchecked")
Class<INodeAttributeProvider> cls = (Class<INodeAttributeProvider>) Class.forName(RANGER_HDFS_AUTHORIZER_IMPL_CLASSNAME, true, rangerPluginClassLoader);
activatePluginClassLoader();
rangerHdfsAuthorizerImpl = cls.newInstance();

插件初始化

初始化RangerPlugin,如上面的类图可知,RangerHdfsPlugin是RangerBasePlugin类的子类,其具体的初始化是由父类的初始化方法来实现的。该方法主要完成了以下几个功能:

(1)调用cleanup()方法,主要完成清空了refresher、serviceName、policyEngine这三个变量的值。
(2)读取配置文件,并设置以下变量的初始值。

  • serviceType:Ranger提供访问控制服务的类型。
  • serviceName:Ranger提供访问控制服务的名称。
  • appId:由Ranger提供服务的组件ID。
  • propertyPrefix:Ranger插件的属性前缀。
  • pollingIntervalMs:刷新器定期更新策略的轮询间隔时间。Ranger 插件会定期从Ranger Admin拉取新的策略信息,并保存在Hdfs缓存中。
  • cacheDir:从Ranger Admin拉取策略到Hdfs插件的临时存放目录。

(3)设置PangerPolicyEngineOptions类的成员变量值。

  • evaluatorType:评估器的类型。在Ranger对Hdfs的访问权限的鉴权阶段需要策略评估器根据策略判断是否具有访问权限。
  • cacheAuditResults:是否缓存审计。
  • disableContextEnrichers:是否使用上下文增强器。
  • disableCustomConditions:是否使用自定义条件。在Ranger0.5版本之后加入上下文增强器和用户自定义条件这样的“钩子”函数以增加授权策略的可扩展性。
  • disableTagPolicyEvaluation:是否使用基于标签的策略评估。在Ranger0.6版本以后,Ranger不仅仅支持基于资源的策略,还支持基于标签的策略,该策略的优点是资源分类与访问授权的分离,标记的单个授权策略可用于授权跨各种Hadoop组件访问资源。

(4)调用createAdminClient(),创建RangerAdmin与RangerPlugin通信的客户端。这里使用的基于RESTful的通信风格,所以创建RangerAdminClient类的实例对象。

(5)创建PolicyRefresher类的对象,调用startRefresher()开启策略刷新器,根据轮询间隔时间定期从Ranger Admin 拉取更新的策略。

策略更新

Ranger插件更新策略的流程图如下:

这部分主要讲Ranger插件如何通过调用Ranger定义好的API获取策略。这里使用了jersey来构建RESTful服务。

(1)Jersey客户端的实现

      RangerAdminRESTClient # getServicePoliciesIfUpdated()

 if (isSecureMode) {
PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
public ClientResponse run() {
// 创建WebResource实例,并根据URI和查询参数(lastKnownVersion、pluginId)构建URL
WebResource secureWebResource = createWebResource(RangerRESTUtils.REST_URL_POLICY_GET_FOR_SECURE_SERVICE_IF_UPDATED + serviceName)
.queryParam(RangerRESTUtils.REST_PARAM_LAST_KNOWN_POLICY_VERSION, Long.toString(lastKnownVersion))
.queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
// 发送GET请求,并且mime类型为Json
return secureWebResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
};
};
response = user.doAs(action);
}else{
WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName)
.queryParam(RangerRESTUtils.REST_PARAM_LAST_KNOWN_POLICY_VERSION, Long.toString(lastKnownVersion))
.queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
}
if(response != null && response.getStatus() == 200) { //200:请求成功
ret = response.getEntity(ServicePolicies.class);
} else if(response != null && response.getStatus() == 304) { // 304:未修正
// no change
}

在RangerRESTUtils类中定义了参数的值:

public static final String REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED = "/service/plugins/policies/download/";
public static final String SERVICE_NAME_PARAM = "serviceName";
public static final String LAST_KNOWN_TAG_VERSION_PARAM = "lastKnownVersion";
public static final String REST_MIME_TYPE_JSON = "application/json" ;

(2)服务端的实现

      ServiceREST # getServicePolicesIfUpdate()

 @GET
@Path("/policies/download/{serviceName}")
@Produces({ "application/json", "application/xml" })
public ServicePolicies getServicePoliciesIfUpdated(@PathParam("serviceName") String serviceName, @QueryParam("lastKnownVersion") Long lastKnownVersion, @QueryParam("pluginId") String pluginId, @Context HttpServletRequest request) throws Exception {
ServicePolicies ret = null;
int httpCode = HttpServletResponse.SC_OK;
String logMsg = null;
RangerPerfTracer perf = null; if (serviceUtil.isValidateHttpsAuthentication(serviceName, request)) {
if(lastKnownVersion == null) {
lastKnownVersion = Long.valueOf(-1);
}
try {
ServicePolicies servicePolicies = svcStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion); // 从数据库获取更新策略的过程
if(servicePolicies == null) {
httpCode = HttpServletResponse.SC_NOT_MODIFIED;
logMsg = "No change since last update";
} else {
ret = filterServicePolicies(servicePolicies);
httpCode = HttpServletResponse.SC_OK;
logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : 0) + " policies. Policy version=" + ret.getPolicyVersion();
}
}
}
return ret;
}

Apache Ranger对HDFS的访问权限控制的原理分析(一)的更多相关文章

  1. MongoDB 安全和访问权限控制

    MongoDB的访问控制能够有效保证数据库的安全,访问控制是指绑定Application监听的IP地址,设置监听端口,使用账户和密码登录 一,访问控制的参数 1,绑定IP地址 mongod 参数:-- ...

  2. (转)浅析Java中的访问权限控制

    原文地址: http://www.cnblogs.com/dolphin0520/p/3734915.html 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下 ...

  3. 使用nginx和iptables做访问权限控制(IP和MAC)

    之前配置的服务器,相当于对整个内网都是公开的 而且,除了可以通过80端口的nginx来间接访问各项服务,也可以绕过nginx,直接ip地址加端口访问对应服务 这是不对的啊,所以我们要做一些限制 因为只 ...

  4. [THINKING IN JAVA]访问权限控制

    6 访问权限控制 6.1 包:库单元 package.import.import *.import static: 修改classpath环境变量可以将自己写的类库添加至环境变量并在任何java程序中 ...

  5. Java成员的访问权限控制

    Java中的访问权限控制包含两个部分: 类的访问权限控制 类成员的访问权限控制 对类来说,访问权限控制修饰符可以是public或者无修饰符(默认的包访问权限): 对于类成员来说,访问权限控制修饰符可以 ...

  6. 浅析Java中的访问权限控制

    浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但 ...

  7. redis密码设置、访问权限控制等安全设置

    redis作为一个高速数据库,在互联网上,必须有对应的安全机制来进行保护,方法有2,如下. 1.比较安全的办法是采用绑定IP的方式来进行控制.  请在redis.conf文件找到如下配置 # If y ...

  8. JAVA访问权限控制[zhuan]

    Java的访问权限控制修饰符,从最大权限到最小权限依次是:public.protected.包访问权限(默认,没有关键字)和private.对于类的访问权限只能是:public和包访问权限(但内部类可 ...

  9. C++中public/protect/private三种访问权限控制

    一.成员访问权限控制 1.public (1)public成员变量可以被成员函数访问  [访问性] (2)public成员可以被实体对象访问  [访问性] (3)public成员可以成为子类成员  [ ...

随机推荐

  1. 列表总结Canvas和SVG的区别

    参考链接: 菜鸟教程 HTML5 内联SVG 经典面试题(讨论canvas与svg的区别) Canvas | SVG ---|--- 通过 JavaScript 来绘制 2D 图形|是一种使用 XML ...

  2. QQ好友在线/离线,怎么测试?

    即时通讯是目前internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷,那么今天主要针对QQ好友在线状态/QQ群友在线状态功能出发,一起思考其中的实现原理以及我们如何去测试此功能? 当大 ...

  3. gzip 与 gunzip 语法与示例

    gzip 与 gunzip 语法与示例 语法: gunzip -c 被压缩的文件 > 已解压的文件示例: 将 catalina.out.gz 文件解压到 catalina.out 文件中: gu ...

  4. CSS -- 练习(待续优化)

    啊啊啊  错误百出啊 错点总结: 字符全角半角.清楚浮动.结尾</div>有点乱找不到对应的了.注释要写好. <!DOCTYPE html> <html lang=&qu ...

  5. AutoMapper.RegExtension[.NET Core版本] 介绍

    Technorati 标签: AutoMapper.RegExtension,AutoMapper.RegExtension .NET CORE AutoMapper.RegExtension 为一个 ...

  6. Nginx网站使用CDN之后禁止用户真实IP访问的方法

    做过面向公网WEB的运维人员经常会遇见恶意扫描.拉取.注入等图谋不轨的行为,对于直接对外的WEB服务器,我们可以直接通过 iptables .Nginx 的deny指令或是程序来ban掉这些恶意请求. ...

  7. ActiveMQ Part 1 : 基本安装配置(windows 版本)

    1. 安装启动服务 A) 首先下载并安装最新的 JDK(本文使用:jdk-8u66-windows-x64.exe) B) 从官网下载最新的安装包(本文下载版本为:http://activemq.ap ...

  8. Grafana关键表结构分析

    Grafana默认使用SQLite存储数据表,默认数据库文件存储在/var/lib/grafana/grafana.db中,可以将文件拷贝到Widnows中,使用Navicat for SQLite进 ...

  9. unity3d屏蔽Windows10输入法

    在win10上,如果安装了某些输入法(比如QQ输入法),会造成unity的键盘事件被输入法捕获而不能触发的情况.只有将输入法切换到英文状态下才能响应键盘事件. 解决办法有, 1:用户主动切换输入法,甚 ...

  10. MongoDB Sharding

    sharding集群中的组件: 1.mongos:router,可以通过keepalived实现高可用. 2.config server:元数据服务器,这里要借助zookeeper存放配置信息. 3. ...