提高數(shù)據(jù)的安全性和可控性,數(shù)?;?Ranger 實(shí)現(xiàn)的 Spark SQL 權(quán)限控制實(shí)踐之路
在企業(yè)級(jí)應(yīng)用中,數(shù)據(jù)的安全性和隱私保護(hù)是極其重要的。Spark 作為數(shù)棧底層計(jì)算引擎之一,必須確保數(shù)據(jù)只能被授權(quán)的人員訪問,避免出現(xiàn)數(shù)據(jù)泄露和濫用的情況。為了實(shí)現(xiàn)Spark SQL 對(duì)數(shù)據(jù)的精細(xì)化管理及提高數(shù)據(jù)的安全性和可控性,數(shù)?;?Apache Ranger 實(shí)現(xiàn)了 Spark SQL 對(duì)數(shù)據(jù)處理的權(quán)限控制。
本文基于 Apahce Spark 2.4.8 和 Apache Ranger 2.2 進(jìn)行原理講解,和大家聊聊「袋鼠云一站式大數(shù)據(jù)基礎(chǔ)軟件數(shù)棧」基于 Ranger 在 Spark SQL 權(quán)限控制上的實(shí)踐探索之路。
基于Ranger實(shí)現(xiàn)Spark SQL權(quán)限控制
Apache Ranger 是一個(gè)開源的權(quán)限管理框架,可以提供對(duì) Hadoop 生態(tài)系統(tǒng)的安全訪問控制。Ranger 為開發(fā)者提供了一種可擴(kuò)展的框架,可以進(jìn)行統(tǒng)一的數(shù)據(jù)安全管理,內(nèi)置包括對(duì) Hadoop、Hive、HBase、Kafka 等多個(gè)組件的訪問控制。
Ranger 內(nèi)置并沒有提供 Spark 的權(quán)限控制插件,需要開發(fā)者自己實(shí)現(xiàn),基于 Ranger 數(shù)棧實(shí)現(xiàn)了 Spark SQL 對(duì)庫、表、列和 UDF 的訪問權(quán)限控制、行級(jí)別權(quán)限控制和數(shù)據(jù)脫敏三方面的權(quán)限管理與控制。接下來我們分兩部分對(duì)其實(shí)現(xiàn)原理進(jìn)行講解,分別是自定義 Ranger 插件和 Spark SQL Extensions 機(jī)制。
自定義 Ranger 插件
在 Ranger 中添加一個(gè)新服務(wù)的權(quán)限校驗(yàn)可分為兩部分:第一部分是為 Ranger 增加新服務(wù)模塊;第二部分是在新服務(wù)中增加 Ranger 權(quán)限校驗(yàn)插件。
● Ranger 增加新服務(wù)模塊
Ranger 增加新服務(wù)模塊是在 Ranger Admin Web UI 界面增加對(duì)應(yīng)服務(wù)模塊,用來為對(duì)應(yīng)服務(wù)添加對(duì)應(yīng)資源的授權(quán)策略。新服務(wù)模塊增加可以分為以下三個(gè)步驟:
? 為新服務(wù)定義描述文件,文件名為 ranger-servicedef-< serviceName>.json,在描述文件中定義了服務(wù)的名字、在 ranger admin web 界面中顯示的名稱、新服務(wù)訪問類定義、需要用來進(jìn)行權(quán)限校驗(yàn)的資源列表和需要進(jìn)行校驗(yàn)的訪問類型列表等。
ranger-servicedef-< serviceName>.json 內(nèi)容主要部分參數(shù)解析如下:
? 開發(fā) Ranger 中新服務(wù)模塊對(duì)應(yīng)的實(shí)現(xiàn)類,并將該類名填寫到 ranger-servicedef-< serviceName>.json 中 implClass 字段上。新服務(wù)模塊的實(shí)現(xiàn)類需要繼承抽象類 RangerBaseService,RangerBaseService 是 Ranger 中所有服務(wù)的基類,它定義了一組公共方法和屬性,以便所有服務(wù)都可以共享和繼承。RangerBaseService 提供了基本功能,如訪問控制,資源管理和審計(jì)跟蹤等。
開發(fā)新服務(wù)模塊的實(shí)現(xiàn)類是比較容易的,通過繼承 RangerBaseService 并實(shí)現(xiàn) validateConfig 和 lookupResource 兩個(gè)方法即可,validateConfig 方法是用來驗(yàn)證服務(wù)的配置是否正確,lookupResource 方法定義了加載資源的方法。
? 第一步和第二部完成后分別將配置文件 ranger-servicedef-< serviceName>.json 和新服務(wù)模塊對(duì)應(yīng)的實(shí)現(xiàn)類 jar 包放到 Ranger Admin 的 CLASSPATH 中,并使用 Ranger Admin 提供的 REST API 向 Ranger 注冊(cè)定義的服務(wù)類型,這樣就能在 Ranger Admin UI 界面看到新服務(wù)的模塊并能通過界面配置對(duì)應(yīng)權(quán)限控制。
● 新服務(wù)中增加 Ranger 權(quán)限校驗(yàn)插件
新服務(wù)中要實(shí)現(xiàn) Ranger 的權(quán)限校驗(yàn)需要開發(fā)對(duì)應(yīng)的權(quán)限控制插件并注冊(cè)到新服務(wù)中,該插件實(shí)現(xiàn)的時(shí)候需要在服務(wù)中找到一個(gè)切入點(diǎn)來攔截資源的訪問請(qǐng)求并調(diào)用 Ranger API 來授權(quán)訪問。接下來介紹一下 Ranger 權(quán)限校驗(yàn)插件開發(fā)中比較重要的4個(gè)類:
? RangerBasePlugin:Ranger 權(quán)限校驗(yàn)的核心類,主要負(fù)責(zé)拉取策略、策略緩存更新及完成資源訪問的權(quán)限校驗(yàn)
? RangerAccessResourceImpl:對(duì)鑒權(quán)資源進(jìn)行封裝的實(shí)現(xiàn)類,調(diào)用鑒權(quán)接口時(shí)需要構(gòu)造這么一個(gè)類
? RangerAccessRequestImpl:請(qǐng)求資源訪問的實(shí)現(xiàn)類,包含鑒權(quán)資源的封裝對(duì)象、用戶、用戶組、訪問類型等信息,調(diào)用鑒權(quán)接口 isAccessAllowed 時(shí)需要將 RangerAccessRequestImpl 作為參數(shù)傳入
? RangerDefaultAuditHandler:審計(jì)日志的處理類
實(shí)現(xiàn) Ranger 權(quán)限校驗(yàn)插件分為以下步驟:
? 編寫目標(biāo)類繼承 RangerBasePlugin,通常只需要在目標(biāo)類實(shí)現(xiàn)的構(gòu)造方法中調(diào)用父類的構(gòu)造函數(shù)并填入對(duì)應(yīng)的服務(wù)類型名稱和重寫 RangerBasePlugin 的 init 方法并在重寫的 init 方法中調(diào)用父類的 init 方法。
RangerBasePlugin 的 init 方法中實(shí)現(xiàn)了策略的拉取并會(huì)啟動(dòng)一個(gè)后臺(tái)線程定時(shí)更新本地緩存的策略。
? 編寫承上啟下的類,用于配置在目標(biāo)服務(wù)中能夠攔截目標(biāo)服務(wù)所有的資源請(qǐng)求并能調(diào)用 RangerBasePlugin 的 isAccessAllowed 方法進(jìn)行資源請(qǐng)求鑒權(quán)。對(duì)于 Spark SQL 實(shí)現(xiàn) Ranger 的權(quán)限校驗(yàn)來說我們基于 Spark SQL 的 Extensions 機(jī)制(后文會(huì)進(jìn)行講解),通過自定義一個(gè) Spark Extensions 注冊(cè)到 Spark 中來在 SQL 語法解析階段通過遍歷生成的抽象語法樹完成資源訪問的權(quán)限校驗(yàn)。
Spark SQL Extensions 機(jī)制
Spark SQL Extensions 是在 SPARK-18127 中被引入,提供了一種靈活的機(jī)制,使得 Spark 用戶可以在 SQL 解析的 Parser、Analyzer、Optimizer 以及 Planner 等階段進(jìn)行自定義擴(kuò)展,包括自定義 SQL 語法解析、新增數(shù)據(jù)源等等。

SparkSessionExtensions 為 Spark SQL Extensions 機(jī)制的核心類,SparkSessionExtensions 保存了用戶自定義的擴(kuò)展規(guī)則,包含以下方法:
? buildResolutionRules:構(gòu)建擴(kuò)展規(guī)則添加到 Analyzer 的 resolution 階段
? injectResolutionRule:向 Analyzer 的 resolution 階段注冊(cè)擴(kuò)展規(guī)則生成器
? buildPostHocResolutionRules:構(gòu)建擴(kuò)展規(guī)則添加到 Analyzer 的 post-hoc resolution 階段
? injectPostHocResolutionRule:向 Analyzer 的 post-hoc resolution 階段注冊(cè)擴(kuò)展規(guī)則生成器
? buildCheckRules:構(gòu)建擴(kuò)展檢查規(guī)則,該規(guī)則將會(huì)在 analysis 階段之后運(yùn)行,用于檢查 LogicalPlan 是否存在問題
? injectCheckRule:注冊(cè)擴(kuò)展檢查規(guī)則生成器
? buildOptimizerRules:構(gòu)建擴(kuò)展優(yōu)化規(guī)則,將在 optimizer 階段被調(diào)用執(zhí)行
? injectOptimizerRule:注冊(cè)擴(kuò)展優(yōu)化規(guī)則生成器
? buildPlannerStrategies:構(gòu)建擴(kuò)展物理執(zhí)行計(jì)劃策略,用于將 LogicalPlan 轉(zhuǎn)換為可執(zhí)行文件
? injectPlannerStrategy:注冊(cè)擴(kuò)展物理執(zhí)行計(jì)劃策略生成器
? buildParser:構(gòu)建擴(kuò)展解析規(guī)則
? injectParser:注冊(cè)擴(kuò)展解析規(guī)則生成器
基于 Spark SQL Extensions 機(jī)制實(shí)現(xiàn)自定義規(guī)則會(huì)很容易,首先編寫類實(shí)現(xiàn) Function1[SparkSessionExtensions, Unit] ,SparkSessionExtensions 作為函數(shù)入?yún)?,調(diào)用 SparkSessionExtensions 對(duì)應(yīng)方法將自定義的解析規(guī)則注冊(cè)到對(duì)應(yīng)的 SQL 解析階段執(zhí)行,然后將編寫的類通過參數(shù) spark.sql.extensions 指定注冊(cè)到 Spark 中。
Spark SQL權(quán)限控制在數(shù)棧中的實(shí)踐
Spark 在數(shù)棧中主要應(yīng)用于離線數(shù)倉的場(chǎng)景,對(duì)離線數(shù)據(jù)進(jìn)行批處理。大多數(shù)場(chǎng)景下數(shù)據(jù)大多都是存在業(yè)務(wù)庫中的如 MySQL、Oracle 等,在數(shù)棧上會(huì)先使用 ChunJun 進(jìn)行數(shù)據(jù)采集將數(shù)據(jù)從業(yè)務(wù)庫同步到 Hive 庫的 ODS 層,然后通過 Hive 或者 Spark 引擎進(jìn)行數(shù)據(jù)的批處理計(jì)算,最后再通過 ChunJun 將結(jié)果數(shù)據(jù)同步到對(duì)應(yīng)業(yè)務(wù)庫中。

對(duì)應(yīng)的業(yè)務(wù)庫大多都是關(guān)系型數(shù)據(jù)庫,每個(gè)關(guān)系型數(shù)據(jù)庫也都已經(jīng)具有非常完善的權(quán)限管理機(jī)制,在早期的數(shù)棧中是缺少對(duì) Hive 上數(shù)據(jù)的安全管控的,這也就導(dǎo)致 Hive 上的數(shù)據(jù)可以被每個(gè)用戶獲取查看,缺少了數(shù)據(jù)隱私保護(hù)。
為了解決 Hive 數(shù)據(jù)安全的問題,我們選擇了使用 Ranger 來對(duì) Hive 進(jìn)行權(quán)限控制。
Ranger 是一個(gè)非常全面的數(shù)據(jù)安全管理框架,它提供了 Web UI 供用戶進(jìn)行權(quán)限策略設(shè)置,使得 Ranger 更加易用。Ranger 安全相關(guān)的功能也十分豐富,管控力度更細(xì),支持?jǐn)?shù)據(jù)庫表級(jí)別權(quán)限管理,也支持行級(jí)別過濾和數(shù)據(jù)脫敏等非常實(shí)用的功能。對(duì) Ranger 進(jìn)行擴(kuò)展也比較靈活,在 Ranger 上能夠很輕松實(shí)現(xiàn)一個(gè)新服務(wù)的權(quán)限管控。
在數(shù)棧上 Spark 用來處理 Hive 中的數(shù)據(jù),Hive 使用 Ranger 進(jìn)行了數(shù)據(jù)的權(quán)限管控,所以為了保證數(shù)據(jù)安全數(shù)棧基于 Ranger 自研了 Spark SQL 的權(quán)限管控插件。
上文我們提到為一個(gè)新服務(wù)自定義 Ranger 權(quán)限管控插件分為兩部分來完成,第一部分是在 Ranger Admin Web UI 界面增加對(duì)應(yīng)的服務(wù)模塊,考慮到 Spark 只用來處理 Hive 中的數(shù)據(jù)所以在權(quán)限策略這個(gè)地方應(yīng)該要和 Hive 保持一致,所以在 Spark SQL 基于 Ranger 實(shí)現(xiàn)權(quán)限控制插件時(shí)沒有重復(fù)造輪子而是直接復(fù)用 HADOOP SQL 服務(wù)模塊,和 Hive 共同使用同一套策略,所以我們只需要在 Spark 端開發(fā) Ranger 的權(quán)限管理插件。

基于 Spark SQL Extensions 機(jī)制,我們編寫了類 RangerSparkSQLExtension,并在該類中將實(shí)現(xiàn)好的鑒權(quán) Rule、行級(jí)過濾 Rule 和數(shù)據(jù)脫敏 Rule 通過調(diào)用 SparkSessionExtensions.injectOptimizerRule 方法注冊(cè)將到 SQL 解析的 Optimizer 階段。
以數(shù)據(jù)脫敏 Rule 為例,當(dāng)匹配到數(shù)據(jù)脫敏的 Rule 后,該 Rule 會(huì)為 Logical Plan 增加一個(gè) Project 節(jié)點(diǎn)并增加 masking_function 函數(shù)調(diào)用的邏輯。通過下圖展示匹配數(shù)據(jù)脫敏 Rule 前后的變化,以 select name from t1 where id = 1 為例:

總結(jié)
數(shù)棧一直致力于數(shù)據(jù)的安全和隱私保護(hù),實(shí)現(xiàn) Spark SQL 基于 Ranger 的權(quán)限控制是數(shù)棧在數(shù)據(jù)安全探索的其中一點(diǎn)。本文講述了基于 Ranger 實(shí)現(xiàn) Spark SQL 權(quán)限校驗(yàn)的原理,基于 Ranger 賦予了 Spark SQL 在權(quán)限管控方面,更強(qiáng)的管控力度、更豐富的能力。
未來在保證安全的前提下數(shù)棧將對(duì)性能進(jìn)行進(jìn)一步的優(yōu)化,比如將權(quán)限校驗(yàn) Rule 注冊(cè)到 SQL 優(yōu)化器上,可能會(huì)被執(zhí)行多次增加,這樣就會(huì)增加一些不必要的鑒權(quán)。期待大家對(duì)數(shù)棧的持續(xù)關(guān)注。
《數(shù)據(jù)治理行業(yè)實(shí)踐白皮書》下載地址:https://fs80.cn/l134d5?
《數(shù)棧V6.0產(chǎn)品白皮書》下載地址:https://fs80.cn/cw0iw1
想了解或咨詢更多有關(guān)袋鼠云大數(shù)據(jù)產(chǎn)品、行業(yè)解決方案、客戶案例的朋友,瀏覽袋鼠云官網(wǎng):https://www.dtstack.com/?src=szbzhan
同時(shí),歡迎對(duì)大數(shù)據(jù)開源項(xiàng)目有興趣的同學(xué)加入「袋鼠云開源框架釘釘技術(shù) qun」,交流最新開源技術(shù)信息,qun 號(hào)碼:30537511,項(xiàng)目地址:https://github.com/DTStack