介绍

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. 算法模板——splay区间反转 2

    实现功能:同splay区间反转 1(基于BZOJ3223 文艺平衡树) 这次改用了一个全新的模板(HansBug:琢磨了我大半天啊有木有),大大简化了程序,同时对于splay的功能也有所完善 这里面没 ...

  2. Android中的WebView实战详解(一)

    一.为什么要用WebView? 1.兼容已有的项目2.可动态更新 二.WebView怎样使用? WebView是一个控件,如在布局中设置: <WebView android:id="@ ...

  3. iPhone 上显示桌面版页面

    在用智能电话的浏览器打开页面时,很多网站会根据浏览器的屏幕大小自动调整显示布局,或跳转到移动设备使用的专用面上来优化显示.一些情况下,这种优化可能不是用户希望的,比如优化后的页面缺少桌面版的功能. 这 ...

  4. RPC漏洞

    DCOM漏洞:利用这个漏洞攻击者只需发送特殊形式的清求到远程计算机上的135端口,轻则会造成拒绝服务攻击,严重的甚至可以让远程攻击者以本地管理员权限执行任何操作. 攻击过程:扫描也可用xscan+DC ...

  5. YARN 命令总结

    起因:YARN 使用capability schedule queue调度container,spark 的app卡死在YARN的队列里面无法出来,无奈请教大神时,可用[yarn applicatio ...

  6. java学习笔记 --- String类

    一.定义 就是由多个字符组成的一串数据.也可以看成是一个字符数组. 注意: 1.字符串是常量:它们的值在创建之后不能更改.为什么? 意思就是说字符串确定了,就会在常量池中生成这个字符串. 所以说它的值 ...

  7. ie旋转滤镜Matrix

    旋转一个元素算是一个比较常见的需求了吧,在支持CSS3的浏览器中可以使用transform很容易地实现,这里有介绍:http://www.css88.com/archives/2168,这里有演示ht ...

  8. linux命令之查看字符集

    lucifer@abc:~$ locale -a 查看本地字符集lucifer@abc:~$ locale -m 查看所有支持的字符集将文件从gb2312转为utf8iconv -f gb2312 - ...

  9. js获取url中的参数方法

    直接调用函数即可,函数如下: function getURLParam(name) { return decodeURIComponent((new RegExp('[?|&]' + name ...

  10. XJOI练习2神奇的供水系统

    神奇的供水系统 在游遍神秘岛过程中,Z4发现每一个小岛上都有若干个奇怪的类似小水缸似的立方体,这另到Z4相当迷惑不解!这天晚上,忽然下起了一场大雨,在中心岛小树屋上类似那个圆形石槽中间的小孔中涌出了一 ...