淺析Kerberos原理,及其應用和管理


   文章作者:luxianghao

   文章來源:http://www.cnblogs.com/luxianghao/p/5269739.html  轉載請注明,謝謝合作。

   免責聲明:文章內容僅代表個人觀點,如有不當,歡迎指正。

   --- 

一,引言

  Kerberos簡單來說就是一個用於安全認證第三方協議,它采用了傳統的共享密鑰的方式,實現了在網絡環境不一定保證安全的環境下,client和server之間的通信,適用於client/server模型,由MIT開發和實現。

  Kerberos的神秘之處在於,它並不要求通信雙方所在的網絡環境是安全的,即使通信過程中數據被截取或者篡改依然不會影響它的正常工作,它提供的認證是雙向的,不僅能保證Server不被錯誤的Client使用,同時也能保證Client不使用錯誤的Server。同時Kerberos又嚴重依賴於時間,時間戳也是Kerberos用來保證通信安全的重要手段,這個一般通過通信雙方同時訪問同一個時間服務器來實現。Kerberos也能達到單點登錄的效果,即當Client通過了Kerberos server的認證后,便可以訪問多個Real Server。

 

二,Kerberos原理淺析

  在實際的應有場景中通常有三個角色,即需要訪問服務的Client,提供服務的Application Server,以及提供安全認證的第三方Kerberos服務器KDC(Key Distribution Center)。它們彼此之間的認證、通信的數據流如下圖所示。

      

  仔細研究過上圖之后,你可能會發現你能看明白的東西實在有限,而想要把Kerberos原理弄明白實在不是一件容易的事,不過可以慶幸的是Kerberos是用傳統的共享密鑰的方式實現的,這個概念對大家來說並不陌生,同時Kerberos認證還加了時間戳,有效時間,信息對比等伎倆,所以花時間細細讀下來你依然能看明白,如果此時你就迫不及待的想研究的話你可以戳這里這里或者這里。現在,我們來討論下Kerberos的認證的一個部分,我認為只要這個部分理解了,其他的都可以遞推出來。如下圖:

       

Client master key: KDC中存儲的Client的密鑰

Server master key: KDC中存儲的Server的密鑰

Sclient-Server:Client與Server之間的會話密鑰

Client Info:記錄了Client本身的Ip等基本信息

首先 Client詢問KDC,我想訪問某個Server,然后KDC會將會話密鑰Sclient-Server用Client master key加密后傳送給Client;與此同時,KDC也會將會話密鑰Sclient-Server連同Client的基本信息打包用Server master key加密也發給Client,並經Client轉發給Server,至此Client與KDC的交互完成。

然后,Client用自己的master key解密KDC傳過來的第一個包,解密后獲得會話密鑰Sclient-Server,並用這個密鑰加密自己的的信息和時間戳打包后傳送給Server,此時Client開始和Server交互,如下圖:                                    

      

Server會收到兩個數據包,一個用會話密鑰加密,一個用自己的master key加密,Server先用自己的master key解密獲取會話密鑰和一份關於Client的信息,然后Server拿到解密后獲取到的會話密鑰再解開另外一個數據包,獲得另一份關於Client的信息和時間戳,至此Client和Server的交互完成。

下面我們解釋下這樣傳輸數據的原因,為什么傳遞這些數據

1,上面有個數據包是KDC經Client轉發給Server的,為什么不直接發給Server?

因為Server可能給多個Client提供服務,這樣Server需要維護一個Client和會話密鑰的對應表,這對Server是一個負擔。

此外,因為網絡傳輸的不確定性可能Client和Server並不能都及時獲取到會話密鑰,假如有一方獲取失敗,那么Client就不能訪問Server

2,為什么要發兩份關於Client的信息給Server?

通過這兩份數據的對比,Server就能判斷出是不是對的Client在訪問服務。

3,Client是如何判斷自己在訪問對的Server呢?

因為Client給Server的一個數據包是用Server的master key來加密的所以只有對的Server才能解密。

4,為什么要用會話密鑰

通信方的master key是長期有效的,如果在網絡上傳輸,一旦被截取,理論上來說只要有足夠的時間是可以破解的,所以我們才用臨時的會話密鑰來通信,一段時間后會話密鑰會過期,同時時間戳也防止了,惡意用戶重復使用同一個數據包。

5,為什么要用時間戳?

如果Client向Server傳送的數據包被其他的Client截取,然后自己拿來向Server請求服務這,這樣就會出問題,那么引入時間戳后,Server收到請求后將從解密后的數據包中獲得的時間戳和當前時間對比,一旦超過一定范圍將直接拒絕請求;所以,正如前面所說,Kerberos高度依賴時間同步服務。

事實上這個並不是Kerberos認證的整個過程,KDC實際上由AS和TGS兩部分組成,你可以將TGS視作一個Server,然后還沿用上面所說的步驟來分析,這樣就可以基本上梳理出Client訪問Server的一個完整的過程了。

這些東西可能依然難於理解,你可以借助Kerberos經典會話中的場景來理解,請戳這里或者這里

 

三,Kerberos應用

1,安裝Kerberos,搭建Kerberos環境,用yum安裝下列包即可

  krb5-devel.x86_64 
  krb5-libs.x86_64 
  krb5-workstation.x86_64

  krb5-server.x86_64 (僅server端需安裝)

如果你想了解詳細的安裝步驟以及配置,請戳這里

這里我們僅貼出配置krb5.conf&kdc.conf中的主要部分

 /etc/krb5.conf 中包含了realm的信息,里邊設置了server的地址,從而讓Client能夠找到Server,示例如下

[libdefaults]
    default_realm = ATHENA.MIT.EDU

[realms]
    ATHENA.MIT.EDU = {
        kdc = kerberos.mit.edu
        admin_server = kerberos.mit.edu
    }

/var/kerberos/krb5kdc/kdc.conf中主要保存了server端的配置,包括server端口,數據庫存放地址,票據有效期等,示例如下:

[kdcdefaults]
    kdc_ports = 88,750

[realms]
    ATHENA.MIT.EDU = {
        kadmind_port = 749
        max_life = 12h 0m 0s
        max_renewable_life = 7d 0h 0m 0s
        database_name = /var/krb5kdc/principal
        acl_file = /var/krb5kdc/kadm5.acl
    }

2, 名詞解釋

KDC:即Key Distribution Center, 密鑰分發中心,負責頒發憑證
Kinit:Kerberos認證命令,可以使用密碼或者Keytab。
Realm:Kerberos的一個管理域,同一個域中的所有實體共享同一個數據庫
Principal:Kerberos主體,即我們通常所說的Kerberos賬號(name@realm) ,可以為某個服務或者某個用戶所使用
Keytab:以文件的形式呈現,存儲了一個或多個Principal的長期的key,用途和密碼類似,用於kerberos認證登錄;其存在的意義在於讓用戶不需要明文的存儲密碼,和程序交互時不需要人為交互來輸入密碼。

3,簡單使用

在安裝好Kerberos和對Kerberos有一個簡單的認識之后,你就可以試用一下了,最基本的命令就是kinit,是Client用來從KDC獲取票據的,示例如下:

a,使用密碼: kinit name@realm 然后根據提示輸入密碼即可

b,使用keytab: kinit -kt /path/to/keytab name@realm

kinit成功之后你獲取的票據就會緩存到本地,可以用klist查看,實例如下:

Ticket cache: FILE:/tmp/krb5cc_0
Default principal: h_test@XIAOMI.HADOOP

Valid starting Expires Service principal
03/13/16 17:08:42 03/14/16 17:08:42 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU
renew until 03/11/26 17:08:42

從中也可以看到過期時間。

如果你要銷毀當前獲取的票據,用kdestroy即可。

當然在kinit之前,server端首先要有你的賬號,這就需要管理員使用addprinc命令在Kerberos數據庫中添加,更多詳情請戳這里

4,Kerbeos在Hadoop上應用

在Hadoop的早期版本(1.0.0)之前是沒有安全認證機制的,集群默認自己的節點都是安全的,這樣就導致了惡意用戶的輕易入侵,修改集群數據,修改任務狀態,提交任務等問題。

1.0.0后的版本加入Kerberos認證后,部署集群時需要事先將密鑰放在要部署的節點上,這樣集群內的節點都是通過認證的節點,只有通過認證的節點才能被正常使用,同樣,通過認證的Client才能使用服務。

如果要結合上面所說的原理,那么將上面說的Server換成Hadoop集群中的Namenode,Datanode即可。

 

四,Kerberos賬號管理

Kerberos本身的數據庫中不能查看密碼的,也沒有保存賬號使用人等信息,所有的信息都需要以命令行的形式獲取,管理起來極不方便,因此我們就開發了一套基於Django web框架的Kerberos賬號管理系統(Kerberos Account Management System,簡稱KAS),以此來提高管理員的工作效率,讓管理員更有效、更有條理的管理Kerberos賬號,KAS的基本組件如下:

權限管理模塊:設定了用戶,用戶組等角色;admin,read等權限類型;並將Kerberos賬號視作一種資源類型;這樣就有了某個角色,擁有某種資源的某種權限的一種通用架構,所以,這個模塊適用於各種資源管理系統。

工具管理模塊:里邊包含了KAS需要的各種工具,例如KAS和Kerberos server交互的工具,郵件發送工具等。

賬號申請模塊:為了減少溝通成本,我們設計了用戶提交申請,管理員審批的賬戶申請流程,在審批階段用戶和管理員可以對申請賬號做出評論,並可以視情況對申請賬號做出重新編輯,撤銷申請等操作,一旦有人提交了申請,做出了評論,或者其他操作系統會發郵件通知管理員和用戶,以便減少賬號申請時間。

賬號管理模塊:對於通過審批的賬號,用戶可以查看密碼,導出賬號keytab,查看賬號owner等,對賬號有admin權限的賬戶還可以將賬號授權給他人使用,以此來減小管理員的工作量。

API模塊:由於有一些特殊人員因為工作的需要,希望查看或者使用owner為其他人的賬號,所以我們設計了API模塊;當有人需要使用API接口時,需要向管理員申請將自己設為超級用戶,同時超級用戶需要維護一個自己的機器列表,只有在此機器列表包含的Host上才能使用API接口,此外超級用戶還需要到系統中查看自己的auth_token,用於在使用API接口時做校驗。

Replicate模塊:Web端的增刪改查等操作只是修改了MySQL數據庫,此時我們需要Replicate模塊將MySQL中的修改實時同步到Kerberos自己的數據庫中。

機房間同步模塊:當多個機房都需要使用Kerberos認證的時候,我們就需要機房間同步模塊將主Server上的修改同步到其他機房中來保證數據的一致性。

備份模塊:用於備份MySQL中和Kerberos Server中的數據以防數據丟失或者其他意外發生。

KAS的整體架構圖如下:

 

服務的安全以及高可用:

對於Web Server我們采用了Keepalived vip漂移的方式來保證服務的高可用性,同一時刻只有一台Server工作,寫MySQL數據庫。

主Server上的Replicate模塊會將MySQL中的修改實時同步到Kerberos Server中,又通過Rsync加密、增量傳輸的方式把主Server中的Kerberos數據庫的更改同步到其他的Kerberos Server的數據庫中(包括同機房的和不同機房的)。

通常一個機房中的Kerberos Server有兩個,我們采用LVS或者Keepalived的方式保證服務的高可用。

Web Server,Replicate模塊等的進程我們用God的守護,以確保服務在異常停止后能自動拉起。

此外,由於Kerbeos是比較基礎的服務,又比較敏感,所以我們還做了端口監控,機器級別的安全加固等。

下面簡單列一下KAS開發前后狀態的對比,如下:

到目前為止系統已經上線近一年,期間運行狀態良好,沒有出現過異常宕掉的情況,很好的提升了工作效率,節約了管理員的時間。

 

五,后記

至此,我們講述了一套完整的Kerberos服務使用及管理的方案,由於本人水平有限,其中難免出現一些錯誤,還請諒解,歡迎批評指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM