從kinit到kerberos安全機制

最近老在項目的shell腳本中看到kinit這個東西,完整的命令是html

kinit -k -t ./conf/kerberos.keytab sherlocky/admin@EXAMPLE.COMgit

查閱一番資料後瞭解到,之因此有這個命令,是因爲該shell腳本接下來會訪問Hadoop集羣,從上面拉取文件作一些處理任務,並將結果存到Hadoop集羣上,那麼該命令的做用就是進行身份驗證(Authentication),確保Hadoop集羣資源的安全。這裏就牽扯到kerberos協議,本文接下來將對此一一闡述。github

1、kinit命令

Kinit命令用於獲取和緩存principal(當前主體)初始的票據授予票據(TGT),此票據用於Kerberos系統進行身份安全驗證,實際上它是MIT在版權許可的條件下爲kerberos協議所研發的免費實現工具MIT Kerberos(當前最新版本爲krb5-1.15.1)的一部分,相關的配套命令還有klistkdestorykpasswdkrb5-config等等,基本用法以下:web

kinit [-V][-l lifetime] [-s start_time][-r renewable_life][-p | -P][-f | -F][-a][-A][-C][-E][-v][-R][-k [-t keytab_file]][-c cache_name][-n][-S service_name][-I input_ccache][-T armor_ccache][-X attribute[=value]][principal]算法

各選項具體含義都不作介紹了,可參考官網,較經常使用的方式就如前言所示,根據指定的事先生成的kerberos.keytab文件爲指定個體進行驗證。驗證經過後,就能夠像日常同樣進行Hadoop系列操做。那麼它是如何進行驗證的呢?其中的過程和原理又是怎樣的?下面要介紹的kerberos協議細節將會回答你的疑惑。shell

2、Kerberos協議

Kerberos(具體可參考RFC1510)是一種網絡身份驗證的協議(注意它只包括驗證環節,不負責受權,關於這二者後面會有介紹區分),用戶只需輸入一次身份驗證信息,就可憑藉此驗證得到的票據授予票據(ticket-granting ticket)訪問多個接入Kerberos的服務,即SSO(Single Sign On,單點登陸)。數據庫

1.基本概念

  • Principal:安全個體,具備惟一命名的客戶端或服務器。命名規則:主名稱+實例+領域,如本文開頭中的sherlocky/admin@EXAMPLE.COM
  • Ticket:票據,一條包含客戶端標識信息、會話密鑰和時間戳的記錄,客戶端用它來向目標服務器認證本身
  • Session key:會話密鑰,指兩個安全個體之間使用的臨時加密祕鑰,其時效性取決於單點登陸的會話時間長短
  • AS:認證服務器(Authentication Server),KDC的一部分。一般會維護一個包含安全個體及其祕鑰的數據庫,用於身份認證
  • SS:特定服務的提供端(Service Server)
  • TGS:許可證服務器(Ticket Granting Server),KDC的一部分,根據客戶端傳來的TGT發放訪問對應服務的票據
  • TGT:票據授予票據(Ticket Granting Ticket),包含客戶端ID、客戶端網絡地址、票據有效期以及client/TGS會話密鑰
  • KDC:Key分發中心(key distribution center),是一個提供票據(tickets)和臨時會話密鑰(session keys)的網絡服務。KDC服務做爲客戶端和服務器端信賴的第三方,爲其提供初始票據(initial ticket)服務和票據授予票據(ticket-granting ticket)服務,前半部分有時被稱爲AS,後半部分有時則被稱爲TGS。

關於概念的一點補充,博文Kerberos 服務的工做原理中對於TGT和Ticket給出了巧妙的比喻:TGT相似於護照,Ticket則是簽證,而訪問特定的服務則比如出遊某個國家。與護照同樣,TGT可標識你的身份並容許你得到多個Ticket(簽證),每一個Ticket對應一個特定的服務,TGT和Ticket一樣具備有效期,過時後就須要從新認證。緩存

2.認證過程

Kerberos的認證過程可細分爲三個階段:初始驗證、獲取服務票據和服務驗證。第一階段主要是客戶端向KDC中的AS發送用戶信息,以請求TGT,而後到第二階段,客戶端拿着以前得到的TGT向KDC中的TGS請求訪問某個服務的票據,最後階段拿到票據(Ticket)後再到該服務的提供端驗證身份,而後使用創建的加密通道與服務通訊。安全

2.1 初始驗證

此過程是客戶端向AS請求獲取TGT:服務器

  • 客戶端向AS發送自身用戶信息(如用戶ID),該動做一般發生在用戶初次登錄或使用kinit命令時
  • AS檢查本地數據庫是否存在該用戶,若存在則返回以下兩條信息:
    • 消息A:使用用戶密鑰加密的Client/TGS會話密鑰,咱們稱之爲SK1。其中用戶密鑰是經過對該用戶在數據庫中對應的密碼hash生成的
    • 消息B:使用TGS的密鑰加密的TGT(包含客戶端ID、客戶端網絡地址、票據有效期和SK1)
  • 當客戶端收到消息A和B時,它會嘗試用本地的用戶密鑰(由用戶輸入的密碼或kerberos.keytab文件中的密碼hash生成)對A進行解密,只有當本地用戶密鑰與AS中對應該用戶的密鑰匹配時才能解密成功。對A解密成功後,客戶端就能拿到SK1,才能與TGS進行後續的會話,這裏就至關於AS對客戶端的一次驗證,只有真正擁有正確用戶密鑰的客戶端纔能有機會與AS進行後續會話。而對於消息B,因爲它是由TGS的密鑰加密的,故沒法對其解密,也看不到其中的內容。

2.2 獲取服務票據

此過程則是客戶端向TGS請求獲取訪問對應服務的票據:

  • 當客戶端要訪問某個服務時,會向TGS發送以下兩條消息:

    • 消息C:消息B的內容(即加密後的TGT)和服務ID
    • 消息D:經過SK1加密的驗證器(Authenticator,包括用戶ID和時間戳)
  • TGS收到消息C和D後,首先檢查KDC數據庫中是否存在所需服務,若存在則用本身的TGS密鑰嘗試對C中的消息B進行解密,這裏也是客戶端對TGS的反向認證,只有真正擁有正確密鑰的TGS才能對B解密,解密成功後就能拿到其中的SK1,而後再用SK1解密消息D拿到包含用戶ID和時間戳的Authenticator,經過比較分別來自C和D的用戶ID,若是兩者匹配,則向客戶端返回以下兩條消息:

    • 消息E:經過SK1加密的Client/SS會話密鑰,該會話密鑰是KDC新生成的隨機密鑰,用於未來客戶端(Client)與服務端(SS)的通訊加密,咱們稱之爲SK2
    • 消息F:使用服務的密鑰加密的client-server票據(Ticket,包含用戶ID、用戶網絡地址、票據有效期和SK2),之因此要用服務的密鑰加密,是由於這個Ticket是給服務端看的,但又須要通過客戶端傳給服務端,且不能讓客戶端看到。那麼就會有人問,爲何KDC不直接把消息E發送給服務端呢,這樣豈不省事?問題就在於網絡時延,若分開發送,消息E和F就不能確保同時到達服務端,考慮一個極端狀況,KDC與服務以前的網絡臨時不通了,那麼這段時間服務端就沒法收到消息E,致使驗證失敗,而實際上該客戶端是有訪問權限的。經過公鑰加密這種方式巧妙地迴避了該問題
  • 客戶端收到消息後,嘗試用SK1解密消息E,獲得Client/SS會話密鑰SK2

2.3 服務驗證

此過程是客戶端與服務端相互驗證,並通訊

  • 客戶端向服務端發送以下兩條消息:

    • 消息G:即上一步中的消息F——client-server票據

    • 消息H:經過SK2加密的新的驗證器(Authenticator,包含用戶ID和時間戳)

  • 服務端收到消息後,嘗試用本身的密鑰解密消息G,這裏實際上也是客戶端對服務端的一次驗證,只有真正擁有正確密鑰的服務端才能正確解密,從而有機會拿到Ticket中的SK2,而後再用該SK2解密消息H,同TGS同樣,對分別來自Ticket和Authenticator中的用戶ID進行驗證,若是匹配成功則返回一條確認消息:

    • 消息I:經過SK2加密的新時間戳
  • 客戶端嘗試用SK2解密消息I,獲得新時間戳並驗證其正確性,驗證經過後,客戶端與服務端就達到了相互信任,後續的通訊都採用SK2加密,就比如創建了一條加密通道,兩者便可享受服務與被服務的樂趣了

3.前提(環境假設)

  • 共享密鑰:在協議工做前,客戶端與KDC,KDC與服務端都確保有了各自的共享密鑰。
  • 防Dos攻擊:Kerberos協議自己並無解決Dos攻擊(Denial of service,拒絕服務)防範問題,一般是由系統管理員和用戶本身去按期探測並解決這樣的攻擊。
  • 保障安全個體自身安全:參與到Kerberos協議中的安全個體必須確保其祕鑰的安全性,一旦祕鑰泄露或被攻擊者暴力破解,那麼攻擊者就能隨意地假裝安全個體,作一些不和諧的事情。
  • 不循環利用Principal的惟一標識:訪問控制的經常使用方式是經過訪問控制列表(access control lists,ACLs)來對特定的安全個體進行受權。若是列表中有條記錄對應的安全個體A早已被刪除,而A的惟一標識卻被後來新加的某個個體B再次利用,那麼B就會繼承以前A對應的權限,這是不安全的。避免這種風險的作法就是不復用Principal的惟一標識。
  • 時鐘同步:參與到協議中的主機必須有個時鐘相互之間進行「鬆散同步」,鬆散度是可配置的。爲何須要同步各主機的時間呢?實際上從Kerberos的認證過程能夠看到,任何人均可以向KDC請求任何服務的TGT,那攻擊者就有可能中途截獲正經常使用戶的請求包,而後離線解密,就能合法地拿到TGT。爲了防止這種重放攻擊,票據(Ticket)會包含時間戳信息,即具備必定的有效期,所以若是主機的時鐘與Kerberos服務器的時鐘不一樣步,則認證會失敗。在實踐中,一般用網絡時間協議(Network Time Protocol, NTP)軟件來同步時鐘。

4.侷限性

  • 單點風險:過分依賴於KDC服務,Kerberos協議運轉時須要KDC的持續響應,一旦KDC服務掛了,或者KDC數據庫被攻破,那麼Kerberos協議將沒法運轉
  • 安全個體自身的安全:Kerberos協議之因此能運行在非安全網絡之上,關鍵假設就是主機自身是安全的,一旦主機上的私鑰泄露,攻擊者將能輕易的假裝該個體實施攻擊

3、Kerberos應用

1.Hadoop安全機制

Apache Hadoop 最初設計時並無考慮安全問題,它不對用戶或服務進行驗證,任何人均可以向集羣提交代碼並獲得執行,使用Hadoop的組織只能把集羣隔離到專有網絡,確保只有通過受權的用戶才能訪問,但這也並不能解決Hadoop集羣內部的安全問題。爲了加強Hadoop的安全機制,從1.0.0版本之後,引入Kerberos認證機制,即用戶跟服務通訊以及各個服務之間通訊均用Kerberos認證,在用戶認證後任務執行、訪問服務、讀寫數據等均採用特定服務發起訪問token,讓需求方憑藉token訪問相應服務和數據。下面以Yarn中提交MR任務爲例:

A、用戶先向KDC請求TGT,作初始驗證

B、用戶經過TGT向KDC請求訪問服務的Ticket

C、客戶端經過ticket向服務認證本身,完成身份認證

D、完成身份認證後,客戶端向服務請求若干token供後續任務執行時認證使用

F、客戶端連同獲取的token一併提交任務,後續任務執行使用token與服務進行認證

4、其餘安全機制

1.OAuth認證

OAuth(Open Authorization,開放受權)用於第三方受權服務,現經常使用的第三方帳號登錄都是採用該機制。好比我用github帳號登錄LeetCode官網,LeetCode並不須要知道個人github帳號、密碼,它只須要將登錄請求轉給受權方(github),由它進行認證受權,而後把受權信息傳回LeetCode實現登錄。

2.LDAP

LDAP(Lightweight Directory Access Protocol,輕量級目錄訪問協議)是一種用於訪問目錄服務的業界標準方法,LDAP目錄以樹狀結構來存儲數據,針對讀取操做作了特定優化,比從專門爲OLTP優化的關係數據庫中讀取數據快一個量級。LDAP中的安全模型主要經過身份認證、安全通道和訪問控制來實現,它能夠把整個目錄、目錄的子樹、特定條目、條目屬性集火符合某過濾條件的條目做爲控制對象進行受權,也能夠把特定用戶、特定組或全部目錄用戶做爲受權主體進行受權,也能夠對特定位置(如IP或DNS名稱)進行受權。

3.SSL

SSL(Secure Sockets Layer,安全套接層)是目前普遍應用的加密通訊協議,其基本思路是採用公鑰加密法,即客戶端先向服務器端索要公鑰,而後用公鑰加密信息,服務端收到密文後用本身的私鑰解密。它的安全機制包含以下三點:

  • 鏈接的私密性:利用會話密鑰經過對稱加密算法(DES)對傳輸數據進行加密,並利用RSA對會話密鑰自己加密
  • 身份驗證:基於數字證書利用數字簽名方法進行身份驗證,SSL服務器和客戶端經過PKI(Public Key Infrastructure)提供的機制從CA獲取證書
  • 內容可靠:使用基於密鑰的MAC(Message Authentication Code,消息驗證碼)驗證消息的完整性,防竄改

本文同步更新到此處

做者:sherlockyb 連接:https://www.jianshu.com/p/2039fe8c62a1 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索