1.背景 互聯網從來就不是一個安全的地方。很多時候我們過分依賴防火牆來解決安全的問題,不幸的是,防火牆是假設“壞人”是來自外部的,而真正具有破壞性的攻擊事件都是往往都是來自於內部的。 近幾年,在thehackernews等網站上總會時不時看到可以看到一些因為數據安全問題被大面積攻擊、勒索的事件。在H ...
1.背景
互聯網從來就不是一個安全的地方。很多時候我們過分依賴防火牆來解決安全的問題,不幸的是,防火牆是假設“壞人”是來自外部的,而真正具有破壞性的攻擊事件都是往往都是來自於內部的。
近幾年,在thehackernews等網站上總會時不時看到可以看到一些因為數據安全問題被大面積攻擊、勒索的事件。在Hadoop1.0.0之前,Hadoop並不提供對安全的支持,預設集群內所有角色都是可靠的。用戶訪問時不需要進行任何驗證,導致惡意用戶很容易就可以偽裝進入集群進行破壞。
要保證Hadoop集群的安全,至少要做到2個A:Authentication(認證),Authorization(授權)。常見的方案有:
Authentication:
MIT Kerberos, Azure AD, KerbyAuthorization:
Apache Sentry(Cloudera), Apache Ranger(Hortonworks)
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時,一個客戶端需要經過三個步驟來獲取服務:
認證
: 客戶端向認證伺服器發送一條報文,獲取一個包含時間戳的TGT。
授權
: 客戶端使用TGT向TGS請求指定Service的Ticket。服務請求
: 客戶端向指定的Service出示服務Ticket鑒權通訊。
Kerberos協議在網路通信協定中屬於顯示層。其通信流程簡單地說,用戶先用共用密鑰從某認證伺服器得到一個身份證明。隨後,用戶使用這個身份證明與SS通信,而不使用共用密鑰。
2.2 具體通信流程
①此流程使用了對稱加密; ②此流程發生在某一個Kerberos領域中; ③小寫字母c,d,e,g是客戶端發出的消息,大寫字母A,B,E,F,H是各個伺服器發回的消息。
首先,用戶使用客戶端上的程式進行登錄:
- 輸入用戶ID和密碼到客戶端(或使用keytab登錄)。
- 客戶端程式運行一個單向函數(大多數為Hash)把密碼轉換成密鑰,這個就是客戶端的“用戶密鑰”(user's secret key)。
2.2.1 客戶端認證(Kinit)
客戶端(Client)從認證伺服器(AS)獲取票據的票據(TGT)。
- Client向AS發送1條明文消息,申請基於該用戶所應享有的服務,例如“用戶Sunny想請求服務”(Sunny是用戶ID)。(註意:用戶不向AS發送“用戶密鑰”(user's secret key),也不發送密碼)該AS能夠從本地資料庫中查詢到該申請用戶的密碼,並通過相同途徑轉換成相同的“用戶密鑰”(user's secret key)。
- 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) 進行加密
- 一旦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)。
- 當client需要申請特定服務時,其向TGS發送以下2條消息:
- 【消息c】:即消息B的內容(TGS's secret key加密後的TGT),和想獲取的服務的服務ID(註意:不是用戶ID)
- 【消息d】:認證符(Authenticator)(Authenticator包括:用戶ID,時間戳),通過Client/TGS會話密鑰(Client/TGS Session Key)進行加密
- 收到消息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) 進行加密
- 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獲取服務。
- 當獲得“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) 進行加密
- 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) 進行加密
- Client通過Client/SS會話密鑰(Client/Server Session Key)解密消息H,得到新時間戳並驗證其是否正確。驗證通過的話則客戶端可以信賴伺服器,並向伺服器(SS)發送服務請求。
- 伺服器(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:
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方案使用Kerby替代MIT Kerberos服務,利用HAS插件式驗證方式建立一套人們習慣的賬戶密碼體系。
目前HAS在Apache Kerby項目has-project
分支開發中,未來會作為Kerbby的新feature出現在下一次release中。
Apache Kerby作為Apache Directory的一個子項目,目前關註度並不高,讓我們期待它在後續的發展吧。