同程旅遊Hadoop安全實踐

來源:互聯網
上載者:User
關鍵字 Hadoop 企業安全 同程旅遊
同程旅遊Hadoop安全實踐

0x01 背景

當前大一點的公司都採用了共用Hadoop集群的模式。

共用Hadoop是指:資料存儲方面,公有/私有的檔目錄混合存放在hdfs上,不同的使用者根據需求訪問不同的資料; 計算資源方面,管理員按部門或業務劃分若干個佇列,每個佇列分配一定量的資源,每個使用者/組只能使用某個佇列中得資源。 這種模式可以減小維護成本,避免資料過度冗余,減少硬體成本。 但這種類似于雲存儲/雲計算的方式,面臨的一個最大問題就是安全。 在同程,資訊安全是滲透到每個部門的,資料安全又是重中之重。 本文就Hadoop安全分享了同程旅遊大資料架構部在這方面的實踐。

然而,Hadoop是缺乏安全機制的。 其中最關鍵的一個問題是,Client的使用者名和使用者組名的隨意性。 Hadoop預設從環境變數中取HADOOP_USER_NAME作為當前使用者名,如果為空則從系統參數裡取HADOOP_USER_NAME,如果還為空則獲取當前系統使用者名,添加到user.name和group.name屬性中。 使用者甚至可以通過conf.set(「user.name」,root),conf.set(「group.name」,」root」)直接指定使用者名和使用者組為root。 這樣提交到集群的請求就可以以root的身份讀寫本不屬於自己的檔目錄,使用本屬於別人的計算資源。

Hadoop團隊也意識到了資料安全方面的缺失,並增加了許可權認證授權機制。 使用者的login name會通過RPC頭部傳遞給RPC,之後RPC使用Simple Authentication and Security Layer(SASL)確定一個許可權協定(一般使用kerberos協定),完成RPC授權[2 ]。 然而,在hadoop集群中啟用kerberos認證有以下一些問題:

1. Kerberos生成證書和配置步驟十分複雜,debug排錯也晦澀,沒有一定經驗很難上手; 2. 延展性不佳。 機器的擴容和減少都要造成證書的重新生成和分發,給運維造成很大困難; 3. 存在單點失敗,中心KDC中心伺服器承載所有使用者的金鑰,掛掉時整個系統可能癱瘓。 同時要求嚴格的時鐘同步,不然會導致認證失敗。

基於以上的原因,以及同程自身Hadoop集群的特性(總承載接近數十P的資料量,日增數十T ,上層依賴上百個平臺/服務,數萬+的資料搬運/運算任務),給Hadoop增加安全機制無疑是給高速運行的汽車換輪子, 要求系統做到服務零中斷,輪流升級無停機。 我們自主研發了一個羽量級的Hadoop使用者認證機制。

0x02 基本構想

身份驗證最常見的方法就是使用者名和密碼校驗,符合我們簡單易用的要求。 首先,我們要讓使用者在與Hadoop交互之前讀取到一個配置好的,和使用者自身相關聯的密碼,將此密碼保存並攜帶在每次與Hadoop交互的請求中以供驗證。 另外,我們知道使用者在對Hadoop做任何操作之前都會和namenode交互,拿到相關的block的資訊,檔讀寫的租約等等。 那很自然的想到可以在namenode 這層做使用者身份驗證操作。 而使用者名和密碼的映射表可以通過配置和遠端RPC 的形式實現熱載入。

0x03 具體實施

使用者載入密碼

使用者資訊在Hadoop裡是以UserGroupInformation這個類實現的。 如果subject為空,或者對應的principal為空,說明尚未登錄過,就會調用getLoginUser()方法。 首先會創建LoginCoNtext,並調用login()方法,完成後調用login.commit()。 我們在commit()方法中加入讀取密碼配置的操作,並存儲在subject的credential中。 密碼可以配置在使用者的home目錄下,或者classpath下。 由於login方法只會在使用者第一次啟動的時候調用,所以避免了重複載入的問題。

Namenode載入使用者名和密碼的映射表

我們新增加了一個讓namenode 讀取集群使用者名和密碼的映射表的RPC服務。 目前Hadoop大部分的 RPC 調用已經採用google的protobuf 協定,替代了1.0時代自己的一套writable的協定。

我們根據protobuf的規範,定義一個叫做RefreshCheckUserPaswordProtocol.proto的協定檔,在檔裡我們分別定義RPC調用的請求和應答消息

message RefreshCheckUserPasswordRequestProto{} messageRefreshCheckUserPasswordResponseProto {} 內容為空, 因為不需要傳入參數再定義調用的服務 service RefreshCheckUserPasswordProtocolService { rpcrefreshCheckUserPassword() returns( RefreshCheckUserPasswordResponseProto); } 通過protobuf命令列工具生成對應的request,response,以及service 的java類 因為新增的協定是在namenode上執行的,所以要註冊在namenodeProtocols裡 extendsClientProtocol, DatanodeProtocol, NamenodeProtocol, RefreshAuthorizationPolicyProtocol, RefreshUserMappingsProtocol, RefreshCallQueueProtocol, GenericRefreshProtocol, GetUserMappingsProtocol, HAServiceProtocol, RefreshCheckUserPasswordProtocol{} 並且在namenodeProtocols的實現類NameNodeRpcServer裡增加具體函式呼叫 RefreshCheckUserPasswordProtocolServerSideTranslatorPB refreshCheckUserPasswordXlator (); BlockingService RefreshCheckUserPasswordProtocolService .newReflectiveBlockingService( refreshCheckUserPasswordXlator); 在dfsadmin的shell命令列中增加了調用此服務的入口 (.( cmd)){ exitCoderefreshCheckUserPassword(); } () throwsIOException { Configuration getConf(); .set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, .get(DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_ KEY, )); DistributedFileSystem getDFS(); URI .getUri(); HAUtil.isLogicalUri(, ); () { .getHost(); ListProxyAndInfoRefreshCheckUserPasswordProtocolHAUtil.getProxiesForAllNameNodesInNameservice(, , RefreshCheckUserPasswordProtocol.); (ProxyAndInfoRefreshCheckUserPasswordProtocol) { { .getProxy().refreshCheckUserPassword(); .. println(.getAddress()); }(e){ .. println(.getAddress()); .. println(e.getMessage()); } } } { RefreshCheckUserPasswordProtocolrefreshProtocol NameNodeProxies.createProxy(,FileSystem.getDefaultUri(), RefreshCheckUserPasswordProtocol.). getProxy(); refreshProtocol.refreshCheckUserPassword(); .. println(); } ; }

最後,我們在namenode啟動(初始化完成)時自動載入一次使用者名和密碼的映射表。

具體位置在NameNode類的void initialize(Configuration conf) throws IOException方法的最後

Namenode 對client做身份驗證

Namenode 接收到使用者請求的時候都調用getRemoteUser()方法將使用者的資訊組裝成UserGroupInformation實例。 這時候我們就很自然的把請求發起者的使用者名,密碼以及源IP提取出來,做使用者身份驗證。 使用者驗證的邏輯很簡單,將使用者名,密碼,IP在啟動時載入的映射表中查找對比,符合條件的予以通過,不然就攔截請求並拋出錯誤。

0x04 上線的一些工作

為了做到新增的使用者安全功能平滑上線,我們做了下面幾個額外的功能

使用者驗證的全域開關

防止新功能的可能出現的bug, 一鍵開關可以迅速關閉新功能,做到快速回滾。

使用者白名單

使用者群的數量很多,同一時間切換上線是不可能的。 我們將使用者放入白名單中,分批配置/測試分配的帳號和密碼,一步一個腳印的實現所有帳號的安全監管

0x05 上線過程

1. 重新編譯打包hadoop-common和hadoop-hdfs 工程

2. 替換namenode 和datanode 上的相應jar包,並滾動重啟。 因為預設是關閉安全功能的,所以新版本的jar包和舊版本的jar是相互相容的。

3. 在各節點,各專案中配置和使用者名和密碼,通過命令將使用者名和密碼的映射表載入至namenode

4. 一鍵開啟安全配置

目前,Hadoop安全已成功上線,升級過程中沒有服務中斷或降級,做到業務零感知。 運行幾個月下來也很平穩,性能良好。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.