基於Kerberos的大數據安全方案

1.背景

互聯網歷來就不是一個安全的地方。不少時候咱們過度依賴防火牆來解決安全的問題,不幸的是,防火牆是假設「壞人」是來自外部的,而真正具備破壞性的攻擊事件都是每每都是來自於內部的。數據庫

近幾年,在thehackernews等網站上總會時不時的看到能夠看到一些由於數據安全問題被大面積攻擊、勒索的事件。在Hadoop1.0.0以前,Hadoop並不提供對安全的支持,默認集羣內全部角色都是可靠的。用戶訪問時不須要進行任何驗證,++致使++惡意用戶很容易就能夠假裝進入集羣進行破壞。安全

不安全的Hadoop集羣

要保證Hadoop集羣的安全,至少要作到2個A:Authentication(認證),Authorization(受權)。常見的方案有:bash

  • Authentication: MIT Kerberos, Azure AD, Kerby
  • Authorization: Apache Sentry(Cloudera), Apache Ranger(Hortonworks)

Hadoop Cluster Secure

Hadoop集羣對Kerberos的支持

2012年1.0.0版本正式發佈後,Hadoop才增長了對Kerberos的支持, 使得集羣中的節點是可信任的。服務器

Kerberos能夠將認證的密鑰在集羣部署時事先放到可靠的節點上。集羣運行時,集羣內的節點使用密鑰獲得認證,認證經過後的節點才能提供服務。企圖冒充的節點因爲沒有事先獲得的密鑰信息,沒法與集羣內部的節點通訊。這樣就防止了惡意地使用或篡改Hadoop集羣的問題,確保了Hadoop集羣的可靠性、安全性。微信

2.Kerberos介紹

Kerberos是種網絡身份驗證協議,最初設計是用來保護雅典娜工程的網絡服務器。Kerberos這個名字源於希臘神話,是一隻三頭犬的名字,它旨在經過使用密鑰加密技術爲Client/Server序提供強身份驗證。能夠用於防止竊聽、防止重放攻擊、保護數據完整性等場合,是一種應用對稱密鑰體制進行密鑰管理的系統。Kerberos的擴展產品也使用公開密鑰加密方法進行認證。網絡

Kerberos目前最新版本是5,1~3版本只在MIT內部發行,由於使用DES加密,早期被美國出口管制局列爲軍需品禁止出口,直到瑞典皇家工學院實現了Kerberos版本4,KTH-KRB。後續也是這個團隊實現了版本5: Heimdal,目前常見的Kerberos5實現之一。架構

本文中討論的Kerberos5實現版本爲MIT Kerberos,MIT保持的大約半年左右一次的更新速度,目前最新版本是2018-11-01發佈的1.16.2版本。運維

2.1 名詞解釋

  • AS(Authentication Server):認證服務器
  • KDC(Key Distribution Center):密鑰分發中心
  • TGT(Ticket Granting Ticket):票據受權票據,票據的票據
  • TGS(Ticket Granting Server):票據受權服務器
  • SS(Service Server):特定服務提供端
  • Principal:被認證的個體
  • Ticket:票據,客戶端用來證實身份真實性。包含:用戶名,IP,時間戳,有效期,會話祕鑰。

使用Kerberos時,一個客戶端須要通過三個步驟來獲取服務:函數

  1. 認證: 客戶端向認證服務器發送一條報文,獲取一個包含時間戳的TGT。
  2. 受權: 客戶端使用TGT向TGS請求指定Service的Ticket。
  3. 服務請求: 客戶端向指定的Service出示服務Ticket鑑權通信。

Kerberos協議在網絡通訊協定中屬於顯示層。其通訊流程簡單地說,用戶先用共享密鑰從某認證服務器獲得一個身份證實。隨後,用戶使用這個身份證實與SS通訊,而不使用共享密鑰。工具

2.2 具體通訊流程

①此流程使用了對稱加密; ②此流程發生在某一個Kerberos領域中; ③小寫字母c,d,e,g是客戶端發出的消息,大寫字母A,B,E,F,H是各個服務器發回的消息。

首先,用戶使用客戶端上的程序進行登陸:

  1. 輸入用戶ID和密碼到客戶端(或使用keytab登陸)。
  2. 客戶端程序運行一個單向函數(大多數爲Hash)把密碼轉換成密鑰,這個就是客戶端的「用戶密鑰」(user's secret key)。
2.2.1 客戶端認證(Kinit)

客戶端(Client)從認證服務器(AS)獲取票據的票據(TGT)。

客戶端認證

  1. Client向AS發送1條明文消息,申請基於該用戶所應享有的服務,例如「用戶Sunny想請求服務」(Sunny是用戶ID)。(注意:用戶不向AS發送「用戶密鑰」(user's secret key),也不發送密碼)該AS可以從本地數據庫中查詢到該申請用戶的密碼,並經過相同途徑轉換成相同的「用戶密鑰」(user's secret key)。

  2. AS檢查該用戶ID是否在於本地數據庫中,若是用戶存在則返回2條消息:

    • 【消息A】:Client/TGS會話密鑰(Client/TGS Session Key)(該Session Key用在未來Client與TGS的通訊(會話)上),經過 用戶密鑰(user's secret key) 進行加密。
    • 【消息B】:票據受權票據(TGT)(TGT包括:消息A中的「Client/TGS會話密鑰」(Client/TGS Session Key),用戶ID,用戶網址,TGT有效期),經過TGS密鑰(TGS's secret key) 進行加密。
  3. 一旦Client收到消息A和消息B,Client首先嚐試用本身的「用戶密鑰」(user's secret key)解密消息A,若是用戶輸入的密碼與AS數據庫中的密碼不符,則不能成功解密消息A。輸入正確的密碼並經過隨之生成的"user's secret key"才能解密消息A,從而獲得「Client/TGS會話密鑰」(Client/TGS Session Key)。(注意:Client不能解密消息B,由於B是用TGS密鑰(TGS's secret key)加密的)。擁有了「Client/TGS會話密鑰」(Client/TGS Session Key),Client就足以經過TGS進行認證了。

2.2.2 服務受權

Client從TGS獲取票據(client-to-server ticket)。

服務受權

  1. 當client須要申請特定服務時,其向TGS發送如下2條消息:

    • 【消息c】:即消息B的內容(TGS's secret key加密後的TGT),和想獲取的服務的服務ID(注意:不是用戶ID)。
    • 【消息d】:認證符(Authenticator)(Authenticator包括:用戶ID,時間戳),經過**Client/TGS會話密鑰(Client/TGS Session Key)**進行加密。
  2. 收到消息c和消息d後,TGS首先檢查KDC數據庫中是否存在所需的服務,查找到以後,TGS用本身的「TGS密鑰」(TGS's secret key)解密消息c中的消息B(也就是TGT),從而獲得以前生成的「Client/TGS會話密鑰」(Client/TGS Session Key)。TGS再用這個Session Key解密消息d獲得包含用戶ID和時間戳的Authenticator,並對TGT和Authenticator進行驗證,驗證經過以後返回2條消息:

    • 【消息E】:client-server票據(client-to-server ticket)(該ticket包括:Client/SS會話密鑰 (Client/Server Session Key),用戶ID,用戶網址,有效期),經過提供該服務的服務器密鑰(service's secret key) 進行加密。
    • 【消息F】:Client/SS會話密鑰( Client/Server Session Key) (該Session Key用在未來Client與Server Service的通訊(會話)上),經過Client/TGS會話密鑰(Client/TGS Session Key) 進行加密。
  3. Client收到這些消息後,用「Client/TGS會話密鑰」(Client/TGS Session Key)解密消息F,獲得「Client/SS會話密鑰」(Client/Server Session Key)。(注意:Client不能解密消息E,由於E是用「服務器密鑰」(service's secret key)加密的)。

2.2.3 服務請求

Client從SS獲取服務。

  1. 當得到「Client/SS會話密鑰」(Client/Server Session Key)以後,Client就可以使用服務器提供的服務了。Client向指定服務器SS發出2條消息:

    • 【消息e】:即上一步中的消息E「client-server票據」(client-to-server ticket),經過服務器密鑰(service's secret key) 進行加密
    • 【消息g】:新的Authenticator(包括:用戶ID,時間戳),經過Client/SS會話密鑰(Client/Server Session Key) 進行加密
  2. SS用本身的密鑰(service's secret key)解密消息e從而獲得TGS提供的Client/SS會話密鑰(Client/Server Session Key)。再用這個會話密鑰解密消息g獲得Authenticator,(同TGS同樣)對Ticket和Authenticator進行驗證,驗證經過則返回1條消息(確認函:確證身份真實,樂於提供服務)。

    • 【消息H】:新時間戳(新時間戳是:Client發送的時間戳加1,v5已經取消這一作法),經過Client/SS會話密鑰(Client/Server Session Key) 進行加密。
  3. Client經過Client/SS會話密鑰(Client/Server Session Key)解密消息H,獲得新時間戳並驗證其是否正確。驗證經過的話則客戶端能夠信賴服務器,並向服務器(SS)發送服務請求。

  4. 服務器(SS)向客戶端提供相應的服務。

3.Kerberos HA架構

Kerberos支持兩種服務器在域內冗餘方式:Master/Slave(MIT和Heimdal)和Multimaster結構(Windows Active Directory)。在生產環境中部署Kerberos時,最好使用一主(Master)多從(Slave)的架構,以確保Kerberos服務的高可用性。

Kerberos中每一個KDC都包含數據庫的副本。主KDC包含域(Realm)數據庫的可寫副本,它以固定的時間間隔複製到從KDC中。全部數據庫更改(例如密碼更改)都在主KDC上進行,當主KDC不可用時,從KDC提供Kerberos票據給服務受權,但不提供數據庫管理。KDC須要一個Admin來進行平常的管理操做。

Kerberos的同步機制只複製主數據庫的內容,但不傳遞配置文件,如下文件必須手動複製到每一個Slave中:

- krb5.conf
- kdc.conf
- kadm5.acl
- master key stash file
複製代碼

3.1 HA方案

目前單機房HA方案使用的較多的是Keepalived + Rsync 。Keepalived能夠將多個無狀態的單點經過虛擬IP(如下稱爲VIP)漂移的方式搭建成一個高可用服務。

首先,在Master KDC中建立數據庫的dump文件(將當前的Kerberos和KADM5數據庫轉儲爲ASCII文件):

kdb5_util dump [-b7|-ov|-r13] [-verbose] [-mkey_convert] [-new_mkey_file mkey_file] [-rev] [-recurse] [filename [principals...]]
複製代碼

而後使用Rsync將目錄同步到Slave機器的對應目錄中, 再導入KDC中:

kdb5_util load [-b7|-ov|-r13] [-hash] [-verbose] [-update] filename [dbname]
複製代碼

Hadoop全部請求經過請求內網域名,解析到Keepalived綁定的VIP的方式來使用KDC:

Kerberos HA

4. 優化和展望

4.1 優化

(1)用戶(Principal)管理

若是團隊中已經有一套權限系統,要將現有的身份系統集成到Kerberos中會很困難。 隨着業務的飛速增加,服務器規模愈來愈大,Kerberos Principal手動操做會愈來愈頻繁,手動的增刪改查維護會很是痛苦。須要在Kerberos管理系統中規範Principal申請、維護、刪除、keytab生成流程。Principal申請和權限管理自動化。

(2)數據同步優化

Kerberos數據同步能夠將生成的數據記錄同步寫入到MySQL中,使用MySQL雙主同步方式。在跨機房環境中,KDC數據使用Rsync工具進行增量同步。以A核心機房做爲主機房,Rsync Server使用了Keepalived VIP的方式,當Kerberos主機宕機後,VIP漂移到另一臺主機器上,Rsync Client會以VIP所在的KDC主機器爲Rsync Server進行數據同步,以保證KDC數據同步的高可用性。

(3)運維

使用進程管理工具對Kerberos相關進程進行存活監控,當發現有進程異常退出時,郵件/微信/釘釘報警,主動再次拉起進程。

4.2 展望

部署過Kerberos的同窗都知道,在Hadoop集羣部署Kerberos實際是一項很是繁瑣的工做。Kerberos本質上是一種協議或安全通道,對於大多數用戶或普通用戶來講,是有必定學習曲線的,是否有更好的實現可以對普通用戶隱藏這些繁瑣的細節。

阿里和Intel合做項目Hadoop Authentication Service (HAS) 據稱目前已經應用到ApsaraDB for HBase2.0中:

HAS

HAS方案使用Kerby替代MIT Kerberos服務,利用HAS插件式驗證方式創建一套人們習慣的帳戶密碼體系。

目前HAS在Apache Kerby項目has-project分支開發中,將來會做爲Kerbby的新feature出如今下一次release中。

Apache Kerby做爲Apache Directory的一個子項目,目前關注度並不高,讓咱們期待它在後續的發展吧。

相關文章
相關標籤/搜索