1. 程式人生 > >Apache Ranger剖析:Hadoop生態圈的安全管家

Apache Ranger剖析:Hadoop生態圈的安全管家

前言

2016年,Hadoop迎來了自己十週歲生日。過去的十年,Hadoop雄霸武林盟主之位,號令天下,引領大資料技術生態不斷髮展壯大,一時間百家爭鳴,百花齊放。然而,兄弟多了不好管,為了搶佔企業級市場,各家都迭代出自己的一套訪問控制體系,不管是老牌系統(比如HDFS、HBase),還是生態新貴(比如Kafka、Alluxio),ACL(Access Control List)支援都是Roadmap裡被關注最高的issue之一。

歷史證明跳出混沌狀態的最好方式就是——出臺標準。於是,Hadoop兩大廠Cloudera和Hortonworks先後發起標準化運動,分別開源了Sentry和Ranger,在centralized訪問控制領域展開新一輪的角逐。

Ranger在0.4版本的時候被Hortonworks加入到其Hadoop發行版HDP裡,目前作為Apache incubator專案,最新版本是0.6。它主要提供如下特性:

  • 基於策略(Policy-based)的訪問許可權模型

  • 通用的策略同步與決策邏輯,方便控制外掛的擴充套件接入

  • 內建常見系統(如HDFS、YARN、HBase)的控制外掛,且可擴充套件

  • 內建基於LDAP、檔案的使用者同步機制,且可擴充套件

  • 統一的管理介面,包括策略管理、審計檢視、外掛管理等

本文將從許可權模型、總體架構、系統外掛三個角度來展開,剖析Ranger如何實現centralized訪問控制。

許可權模型

訪問許可權無非是定義了”使用者-資源-許可權“這三者間的關係,Ranger基於策略來抽象這種關係,進而延伸出自己的許可權模型。為了簡化模型,便於理解,我用以下表達式來描述它:

Policy = Service + List<Resource> + AllowACL + DenyACL
AllowACL = List<AccessItem> allow + List<AccssItem> allowException
DenyACL = List<AccessItem> deny + List<AccssItem> denyException
AccessItem = List<User/Group> + List<AccessType>

接下來從”使用者-資源-許可權”的角度來詳解上述表達:

  • 使用者:由User或Group來表達;User代表訪問資源的使用者,Group代表使用者所屬的使用者組。

  • 資源:由(Service, Resource)二元組來表達;一條Policy唯一對應一個Service,但可以對應多個Resource。

  • 許可權:由(AllowACL, DenyACL)二元組來表達,兩者都包含兩組AccessItem。而AccessItem則描述一組使用者與一組訪問之間的關係——在AllowACL中表示允許執行,而DenyACL中表示拒絕執行。

下表列出了幾種常見系統的模型實體列舉值:
Ranger模型實體列舉值

關於許可權這個部分,還有一點沒有解釋清楚:為什麼AllowACL和DenyACL需要分別對應兩組AccessItem?這是由具體使用場景引出的設計:

以AllowACL為例,假定我們要將資源授權給一個使用者組G1,但是使用者組裡某個使用者U1除外,這時只要增加一條包含G1的AccessItem到AllowACL_allow,同時增加一條包含U1的AccessItem到AllowACL_allowException即可。類似的原因可反推到DenyACL。

既然現在一條Policy有(allow, allowException, deny, denyException)這麼四組AccessItem,那麼判斷使用者最終許可權的決策過程是怎樣的?

總體來說,這四組AccessItem的作用優先順序由高到低依次是:

denyException > deny > allowException > allow

訪問決策樹可以用以下流程圖來描述:

Created with Raphaël 2.1.0使用者請求資源找到所有資源 匹配的Policy有denyAccessItem匹配有denyExceptionAccessItem匹配有allowAccessItem匹配有allowExceptionAccessItem匹配拒絕訪問/決策下放允許訪問拒絕訪問yesnoyesnoyesnoyesno

這裡要對決策下放做一個解釋:如果沒有policy能決策訪問,Ranger可以選擇將決策下放給系統自身的訪問控制層,比如HDFS的ACL。

總體架構

Ranger的總體架構如下圖所示,主要由以下三個元件構成:

  • AdminServer: 以RESTFUL形式提供策略的增刪改查介面,同時內建一個Web管理頁面。

  • AgentPlugin: 嵌入到各系統執行流程中,定期從AdminServer拉取策略,根據策略執行訪問決策樹,並且定期記錄訪問審計。外掛的實現原理將在後文詳細介紹。

  • UserSync: 定期從LDAP/File中載入使用者,上報給AdminServer。

Ranger總體架構

系統外掛

前文已經提到,系統外掛主要負責三件事:

  • 定期從AdminServer拉取策略

  • 根據策略執行訪問決策樹

  • 定期記錄訪問審計

以上執行邏輯是通用的,可由所有系統外掛引用,因此剩下的問題是如何把這些邏輯嵌入到各個系統的訪問決策流程中去。目前Ranger裡有兩種做法:

  • 實現可擴充套件介面:多數的系統在實現時都有考慮功能擴充套件性的問題,一般會為核心的模組暴露出可擴充套件的介面,訪問控制模組也不例外。Ranger通過實現訪問控制介面,將自己的邏輯嵌入各個系統。下表列出了Ranger外掛對幾個常見系統的擴充套件介面:

Ranger外掛擴充套件介面

  • 程式碼注入:不排除有少數系統沒有將訪問控制模組暴露出擴充套件點,這個時候Ranger依賴Java程式碼注入機制(java.lang.instrument)來實現邏輯嵌入。以HDFS外掛為例,Ranger利用ClassFileTransformer,直接修改HDFS訪問控制類FSPermissionChecker的ClassFile,將checkPermission方法替換成Ranger的自定義實現。

後話

隨著Hadoop生態圈進軍企業級市場,資料安全逐漸成為關注焦點。Ranger作為標準化的訪問控制層,引入統一的許可權模型與管理介面,極大地簡化了資料許可權的管理。不過,Ranger目前處於孵化專案,在功能性與穩定性上仍然有較大的提升空間,其能否覆蓋更多的系統,一統江湖成為標準,讓我們拭目以待。