Kerberos原理和基礎小結

  此篇文章僅作Kerberos的基本原理和基本使用作說明,本人對Kerberos瞭解有限,也是經過大量英文文檔中翻譯過來,html

  加上本身對Kerberos的理解所寫,本人英文太菜,看文檔看的頭昏眼花如有寫的不通順的地方,請作參考實驗部分,經過node

實驗部分,可以讓你對Kerberos有比較直觀的認識,因爲各方面緣由,不能加過多圖片,請自行實驗看效果.linux

  但願看客記住一句話: 快就是慢,慢就是快!!算法

      ---------馬幫弟子:zcf數據庫

 

=================================【這部分Kerberos原理,是最新總結,僅作參考】=====================================ubuntu

 

 Kerberos基本概念:
  1. Kerberos中有三種角色:
    服務器, 客戶端
    KDC(認證服務器)
      客戶端和服務器要信任KDC
      而且KDC要存儲它們每一個人的私有密碼所生成的Hash密鑰.這些hashkey被存儲在account database(帳號數據庫)中。

  2. KDC爲了便於查詢它們每一個人的Hash密鑰, 要求他們必須有一個惟一的名字,稱爲principal.

  3. 安全個體(principal)
    定義:
      1. 凡是能夠與帳戶和口令聯繫在一塊兒的任何事物均可以被認爲是安全個體;
      2. 每一個安全個體都有一個可被認證的身份;
      3. 在認證的過程當中,正在被證實的是參與各方的安全個體的身份。
    對於以上定義我也理解困難.vim

      
      /etc/krb5.keytab中存儲的一類條目就是一個pricipal(安全主體),可粗略這樣認爲.
      一類條目: 是指nfs/rnode22.zczf.com@ZCZF.COM這個安全主體它的密碼(Long-term key)通過多種
          Hash加密分別算法計算出了一個Hash密鑰,由於Hash算法的特色就是不可逆!即不能經過密鑰還原出
          密碼,Kerberos對數據加密時,使用的這些密鑰,而不是密碼,但密碼和密鑰具備同等效力,由於
          密鑰不可逆,能解密用密鑰加密的數據的人,必定是有真實密碼的人!
      krb5.keytab: 當你把nfs/rnode22.zczf.com這個安全主體從Account database中導出到一個文件時,
            存儲這個安全主體的文件就是keytab,你能夠將它命名爲其它,但由於系統中大部分藉助
            於kerberos認證的服務程序默認都會到/etc/下找krb5.keytab,甚至不少都是寫死在
            配置文件中,除非你很是瞭解這些服務,不然不建議命名成其它!
      Account Database: 它是KDC上的存儲安全主體的數據庫,簡單說就是認證帳號的數據庫,只不過這些帳號
            不一樣於常見的用戶名密碼,它裏面存儲的安全主體的命名格式: [服務名]/徹底合格域名@Realm
            服務名:如上面nfs, ssh等,也能夠是host,即主機帳號, 徹底合格域名即DNS名,如:www.a.com
            rnode22.zczf.com 這都是. Realm是KDC的域.就相似於a.com域同樣.
            在這個帳號數據庫中,nfs/rnode22.zczf.com@ZCZF.COM是一個獨立的條目,該條目對應多種
            加密算法計算生成的密鑰, 通常host,nfs,,...這些主機帳號建議使用隨機密碼,固然也可手動輸入密碼,
            而用戶帳號類的安全主體,要使用手動輸入密碼, 以便本地驗證用戶身份.
            經過自動生成密碼 或 手動輸入密碼,最終根據默認生成Hash key的算法列表,依次生成Hash key.

    4. Long-term key , Short-term key ,Session Key
      Long-term key: 即你本身的密碼,你的密碼可能幾年,甚至更久都不會變,在網絡世界中,這種密碼是不安全的,
            由於沒有任何加密算法是100%安全的,即 你用你的密碼加密的數據,在網絡上傳輸的話,只要
            黑客捕獲足夠多的數據包,進行計算,密碼是能夠被計算出現的,這只是時間問題.所以在網絡
            環境中不建議使用這種Long-term key.
      Short-term key:其實就是Session key, 即短時間密碼,僅在指定時間範圍內有效,這樣即使被破解,此密碼也早已失效.
            它是Kerberos加密通訊使用最多的密鑰.


   5. TGT: Ticket組成:【僅作參考】
      緩存

 



Kerberos的基本認證過程:
安全

  要看下面的認證過程,必須先了解上面提到的基本概念.
  下面的說明是經過這條命令開始, 此命令是讓NFS藉助於Kerberos作身份驗證.
  注意:下面說明並不必定徹底正確,但能夠幫助你更快速的理解Kerberos內部複雜的認證邏輯.

    mount -t nfs -o v4.2,sec=krb5p server.group8.example.com:/protected /mnt/nfssec
    #當執行此命令後,個人理解:
      下圖爲Kerbors服務端日誌信息輸出:
        
        注意: 此圖是後來截的,system1就是NFS Server, server是Kerberos KDC服務器.
        從Kerberos日誌中能夠看到:
        客戶端第一次去訪問nfs server時,客戶端實際和Kerberos通訊了兩次.
        個人理解以下:
          1.Client首先要與kerberos服務取得聯繫,得到與Kerberos通訊的初始隨機密鑰,可是Kerberos
            要知道你找我作什麼事? 是讓我幫你生成訪問其它服務器的TGT?仍是獲取密碼驗證?仍是
            要與我創建通訊?等 因此 Client首次與Kerberos通訊時,Client將本身的Principal明文放在
            與Kerberos通訊的包中,並將本身的需求+預認證信息使用本身的principal對應的密鑰加密,
            而後發給Kerberos,kerberos收到後,它使用明文的principal找到數據庫中對應的密鑰,而後
            嘗試解密,由於一個principal對應多個加密算法計算的隨機密鑰,個人理解是這樣,(每次通訊
            隨機使用其中一個加密算法生成的密鑰,對需求信息作加密,可增大破解的難度)kerberos會依次
            嘗試這些密鑰,若成功解密,則繼續,不然返回錯誤. 當Kerberos解密成功後,它看到裏面的信息,
            你要與我創建通訊,因而kerberos就知道,我應該使用krbtgt這個principal對應的密鑰來對Client
            的預認證信息作加密,生成TGT, 而且生成你和我通訊使用的隨機密碼,並使用你的prinicpal中
            隨機的一個密鑰加密,最終將TGT和加密後的隨機密碼發給Client.

          Client本身的Principal: Cp
          Client本身的Principal對應的密鑰: Ck
          Client----[(Cp) (Ck{預認證數據})]----------->Kerberos

         Kerberos的principal對應的密鑰:Kk
         Kerberos---[(Kk{TGT}) (Ck{KC-RandomKey})]------->Client

          說明:
            隨機密碼: 即Session key.
            上面的過程實際就是Kerberos中的第一個子協議, Authentication Service Exchange認證交換服務。服務器

            Client給kerberos發送到就是AS_REQ(認證服務請求),而Kerberos迴應Client的就是AS_REP。

        上面描述過程以下圖:

          

        第一次通訊成功完成.
        第二次Client須要訪問system1上的nfs服務,因而使用第一次獲取的TGT 加
        使用本身和kerberos之間的隨機密鑰將本身的需求加密,發給Kerberos,kerberos收到後,
        它會先嚐試使用本身的Principal對應的密鑰解密TGT,以便獲取與Client通訊的隨機密碼.
        【注意: Kerberos協議中,爲了不使用kerberos協議的服務軟件,自行維護隨機密碼列表,
        所以它在實現時,將隨機密碼放到TGT中,TGT中包含了客戶端的信息和隨機密碼,
        這樣服務軟件只要知道, 我用個人principal中的密鑰嘗試解密客戶端提供的TGT,
        若能解密,就可肯定這個是KDC頒發給Client的,而後使用其中我和Client之間專用的
        隨機密碼,就能解密需求部分.這樣就避免了爲每一個客戶端都要緩存和它通訊時,使用的隨機密碼了.】
        當使用本身的Principal嘗試解密TGT,解密成功後,kerberos就能夠獲取於客戶端通訊的隨機密碼,
        接着Client的需求信息解密,知道Client想訪問Sytem1 這臺 NFS服務器,因而,kerberos
        使用Client指定的nfs的主機名,去查詢數據庫,若找到對應的principal,則使用該principal
        對應的密鑰,並生成Client和NFS之間通訊的隨機密碼,而後將C_N_random_key和Client的信息
        使用NFS主機對於的principal的密鑰加密,生成TGT,接着使用Kerberos和Client之間的隨機密鑰
        將C_N_random_key加密,最終一併發給Client.

        過程以下:
          Client---[(Kk{TGT}) (Kck{Client的需求})]------------------------->Kerberos

          NFS Server的principal對應的密鑰: Ks
          Kerberos---[(Ks{TGT}) (Kck{Client-NFS-Random_Key})]------->Client

        上面描述的過程就是Kerberos的第二個子協議: TGS(Ticket Granting Service)Exchange
        TGS_REQ: Client給Kerberos發請求. TGS_REP: Kerberos給Client迴應.

        最後,以下圖描述的同樣,Client使用 經過NFS的principal對應的密鑰加密的TGT+本身和NFS
        之間通訊使用的隨機密碼加密的認證請求信息發給NFS, NFS使用/etc/krb5.keytab(默認使用此keytab)
        查出本身prinicipal對應的密鑰,並嘗試解密TGT,若成功解密,將獲取到Client和本身通訊的隨機密碼,
        並使用該隨機密碼解密認證請求,首先檢查時間戳是否在合理區間,通常爲5分鐘以內,若時間戳合理,則
        最後對比認證請求中的信息與TGT中的信息是否一致,若一致則認證經過,容許你訪問我共享的資源.
        注意:
          第三個子協議Client/Server Exchange是支持雙向認證的, 它的雙向認證以下:
          Server從Authenticator(即Client的需求)提取Timestamp,使用Session Key(即C_N_random_key)
          進行加密,並將其發送給Client用於Client驗證Server的身份。

        上面描述大概以下圖:
        下圖描述的就是TGS Exchange 和第三個子協議【Client/Server Exchange】
          


        上面三個子協議彷佛完美的解決的了認證問題.
        但事實上問題尚未解決,由於Client和Server之間通訊可能須要很長時間,甚至一直。
        Client只有與Server通訊,就必須提供 Server的principal對於的密鑰加密的TGT,由於TGT中
        包含了Client和Server通訊使用的Session Key(即隨機密碼),因此這是很是不安全的,
        由於principal對於的密鑰就至關於密碼,只要時間足夠,也不是不可能破解.
        爲了解決這個問題,kerberos又引入了第四個子協議: User2User
        過程以下:

        Client本身的Principal: Cp
        Client本身的Principal對應的密鑰: Ck
        Client----[(Cp) (Ck{預認證數據})]--------------------------------------->Kerberos

        Kerberos的principal對應的密鑰:Kk
        Kerberos---[(Kk{TGT}) (Ck{Kerberos-Client-Random-Key})]------->Client

        #上面交互後,Client獲得了KDC的principal密鑰加密的TGT
        接着Client須要去Server端獲取Server與KDC之間的TGT,以便今後TGT中獲取,
        Server與KDC之間通訊使用的隨機密碼(Session-key).

        Client---[(Kk{TGT}) (Kck{Client的需求})]------------------------->Kerberos

        Server的principal對應的密鑰: Ks
        Kerberos---[(Ks{TGT}) (Kck{Client-Server-Random_Key})]------->Client

        Kcs: 即Server和Client之間的隨機密鑰
        Client---[(Ks{TGT}) (Kcs{我須要你和KDC之間的TGT})]--------------->Server

        Server---[Kcs{ (Kk{TGT}) }]---------------------------------------------->Client

        #當得到Server和KDC之間的TGT後,Client將本身與KDC之間的TGT,本身的需求信息,
        經過Client_KDC_random_key加密後,一併發給KDC, KDC收到後,會先解密與Client
        之間的TGT,獲取Client_KDC_random_key, 解密需求信息,而後對比其中的信息與TGT
        中Client的信息是否匹配, 若匹配,則繼續使用本身的principal對於的密鑰解密與Server
        之間的TGT,獲取KDC_Server_random_key,接着使用K_S_random_Key對客戶端信息
        及Client_Server_random_key一塊兒加密,生成TGT,返回給Client.

        Kck[] : 這表示中括號裏面的內容是Client和KDC之間使用的TGT.
        Ksk[]: 這表示中括號裏面的內容是Server與KDC之間使用的TGT
        Kck{} : 這表示花括號中的內容是使用Client和KDC之間的隨機密鑰加密的數據.
        Client--[Kck[(Kk{TGT})] Ksk[(Kk{TGT})] Kck{預認證信息}]------------------------>Kerberos

      #當Kerberos收到Client與本身的TGT,Server與本身的TGT後,會先解密本身的Client
      之間的TGT,獲取本身與Client之間通訊的隨機密鑰, 接着解密預認證信息,驗證Client的身份,
      當Client身份驗證經過後, KDC纔會繼續解密本身與Server之間的TGT,獲取本身與Server之間
      的隨機密鑰,並使用該隨機密鑰將Client的信息 + Server與Client之間通訊的隨機密鑰 一塊兒加密
      生成新的TGT,並將該TGT發給Client.

        Ksk: 是Server與KDC之間的隨機密鑰
        Client---[Ksk{TGT} Kcs{本身的需求}]--------------------------------->Server

      #接着Client就可使用該TGT,加上本身和Server之間的隨機密鑰加密後的需求,發給Server.
      Server收到到,使用KDC和本身之間的隨機密鑰解密TGT,獲取其中的隨機密鑰,並解密Client的需求,
      接着從需求中獲取時間戳,客戶端信息與TGT中的信息作比對,若匹配,則驗證經過,容許Client
      訪問個人資源.

        Server---[Kcs{你是合法用戶,能夠訪問個人資源}]---------------------->Client

        Client----[Ksk{TGT} Kcs{請求具體的資源}]---------------------------->Server

        Server---[Kcs{資源數據}]------------------------------------------------>Client

  這裏有一篇寫Kerberos內部認證原理的文章:
    http://www.cnblogs.com/artech/archive/2007/07/05/807492.html
  下面是redhat官方對Kerberos的說明:
    https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/configuring_a_kerberos_5_client


最後,在告訴你一個不幸的消息,這些原理僅僅只是Kerberos的工做機制,但在具體實現中,可能存在
差別,我在RHEL7.0上測試,相同的配置卻會出現認證經過 和 認證失敗這種結果,並且認證失敗後,
幾乎很難排錯。結果我發現重啓幾回後,居然神奇的好了,什麼也沒有改?這是怎麼回事?

NFS與Kerberos結合對我來講,仍是有些頭疼,但願能有更好解決方案的文章出現。

在RHEL7.0上測試時,nfs-secure是客戶端必須開機啓動的服務,客戶端在進行krb認證時,
是有該服務協助完成的.並且該服務實際是rpc-gssd.service的軟鏈接。
而nfs-secure-server不知道爲什麼,在服務端應該能夠啓動,可是我不管如何都不能啓動它.
nfs-secure-server是rpc-svcgssd.service的軟鏈接.

我始終沒有搞明白,nfs-secure 和 nfs-secure-server到底哪一個其做用?可以協助NFS實現與Kerberos交互?
爲什麼nfs-secure-server對應的rpc-svcgssd啓動不了?

/etc/gssproxy/gssproxy.conf   #此配置文件中的配置對Kerberos認證起什麼做用?
              爲什麼它定義的keytab緩存目錄中什麼東西都沒有?並且老是報錯
gssproxy[925]: (OID: { 1 2 840 113554 1 2 2 }) Unspecified GSS failure. Minor code may provide more information, No credentials cache found

 這些問題都有待繼續深刻學習Kerberos,但願高手路過,給予指點一二。

 

 

 

=================================================【最近發現下文中存在諸多錯誤,僅作參考】===================================================

kerberos協議原理:

  Kerberos基礎
    Kerberos依賴於單密鑰加密技術;
    咱們能夠把對口令進行散列計算,以便產生單密鑰加密算法所需的密鑰。
    核心思想:
      天下有一個祕密,只有你和我知道,若是我能向你證實我知道這個祕密,我就是我。

  KDC:票證頒發中心
        單密鑰加密技術【又叫:對稱加密技術】
  原理:密鑰加密算法要求雙方共享同一個密鑰。密鑰就是密碼的散列結果(散列可使56或128位的),
    數據是被密鑰加密的,解密也是要經過密碼散列獲得密鑰,在用密鑰解密數據。
    三要素:密鑰、算法和數據(要加密的數據)


  基本認證過程:
    1. Kerberos中有三種角色:
      CA(認證服務器), 服務器, 客戶端, 客戶端和服務器要信任CA, 而且CA要存儲它們每一個人的私有密碼。
      2. CA爲了便於查詢它們每一個人的密碼, 要求他們必須有一個惟一的名字,稱爲principal.
        3. 安全個體(principal)
      定義:
      1. 凡是能夠與帳戶和口令聯繫在一塊兒的任何事物均可以被認爲是安全個體;
      2. 每一個安全個體都有一個可被認證的身份;
      3. 在認證的過程當中,正在被證實的是參與各方的安全個體的身份。

    4. 認證過程:
    假如客戶端A, 要訪問服務器B, 過程以下:
    首先: A將本身和B的Pricipal發給CA, CA就知道A要訪問B, 而後, 查詢本身的
      密碼數據庫,獲取A 和 B對應的密碼.
      A---[A_Pricipal, B_Pricipal]----->CA

    接着: CA生成了一個認證因子(相似於證書), 其中包含時間戳,我CA的信息,
      A的信息(A的IP,A的主機名,等等), 而後生成一個隨機密碼(RandomKey),
      並使用A的密碼,將 [認證因子 + RandomKey] 加密成"Encryption Client".
      接着使用B的密碼, 將[RandomKey] 加密成 "Encryption Server".
      CA--[EC, ES]--------------------->A

     而後: A收到了EC 和 ES, A使用本身的密碼將EC解密, 得到了認證因子+RandomKey.
      A使用Randomkey 對 [認證因子] 加密
      A---[ 加密的認證因子 + ES]-------------->B

   最後: B收到了來自A的訪問請求, 而後 使用本身的密碼將ES解密, 獲取RandomKey.
    而後使用RandomKey 解密 加密的認證因子, 獲取認證信息, B讀取認證信息,
    知道這是我信任的CA,接着比對訪問者提供的信息與CA提供的認證信息是否匹配,
    匹配則認證經過, 容許訪問.
      B-----------[A須要的數據]----------->A

  認證因子: Ticket組成:【僅作參考】
    


  Kerberos的主配置文件【krb5.conf】:
    從版本1.14開始,可經過KRB5_CONFIG變量來指定krb5.conf的位置
    其中目錄名可包含: 字母、數字字符、破折號或下劃線

    foo = bar *    #'*':表示foo的最終值是bar, 第二個foo的值,將永不生效.
    foo = baz

    #這必須定義在配置文件首部,用於包含其它配置文件,必須是絕對路徑.
    # 文件名: 可包含字母數字、破折號或下劃線
      include FILENAME
      includedir DIRNAME    #必須以".conf"結尾.

    #加載模塊的方式:
    #模塊必須是絕對路徑
      module MODULEPATH:RESIDUAL

  主要段:
    [libdefaults] Kerberos V5庫使用的設置
    [realms] 特定於realm的聯繫信息和設置
    [domain_realm] 將服務器主機名映射到Kerberos領域


  如下具體配置參數說明,可參考:
    rpm -ql krb5-workstation krb5-server |grep pdf

      

  [libdefaults]
    default_realm = ZCZF.COM    #標識客戶機的默認Kerberos域; 將其值設置爲Kerberos Realm(領域).
                   若無設置此值,那麼在調用kinit(1)等程序時,必須使用每一個Kerberos principal(主體)指定一個realm(域)。
    forwardable = true        #true:在KDC容許的狀況下,初始票證在缺省狀況下是可轉發的。默認值爲false。
    ticket_lifetime = 24h      #設置ticket最大有效期
    renew_lifetime = 1d      #設置默認ticket是否可更新其有效期. 0:不能夠.
    clockskew = 1d        #設置ticket(票據)的最大過時時間, 若ticket中標記的過時時間小於它, 則在clockskew的
                  #有效期內, 這個過時的ticket依然有效.
    rdns = false          #true:使用反向解析和正向解析來規範化主機名.false:不使用DNS規範化主機名.
                  #但dns_canonicalize_hostname=True,默認爲true,依然會要求主機名必須經過DNS能解析爲FQDN.
    dns_lookup_realm = false    #在將主機名映射爲Default Realm時, 不經過DNS獲取Kerberos的Realm(領域)名稱.
    default_ccache_name = KEYRING:persistent:%{uid}     

         #指定默認憑據緩存位置及緩存名, KEYRING:是存儲到內核的不可交換內存的密鑰環上.
         並以當前有效用戶(euser)的UID命名. 【詳情查看下文: 緩存類型】
         若不指定,默認使用: FILE:/tmp/krb5cc_%{uid}

    非必要參數,他們都有默認值.
      err_fmt             #定義錯誤日誌格式; %M: 日誌消息, %C:錯誤代碼.
      allow_weak_crypto = false   #禁止弱密碼,默認值. 默認將不容許使用單向DES加密算法.
                    默認容許使用的加密列表:default_tgs_enctypes,default_tkt_enctypes
                    設置容許使用的加密算法列表:permitted_enctypes
      default_client_keytab_name    #指定用於獲取客戶端憑據的默認keytab文件名; 默認文件是FILE:/var/kerberos/krb5/user/%{euid}/client.keytab。
      default_keytab_name         #指定應用程序服務器(如sshd)使用的默認keytab名稱; 默認是FILE:/etc/krb5.keytab

      dns_canonicalize_hostname=True    #默認, 主機名必須能被DNS解析爲徹底合格域名.
      rdns=ture                 #使用反向解析和正向解析來規範化主機名.
      dns_lookup_kdc            #從DNS的SRV記錄中查詢KDC是誰.
      dns_uri_lookup =true          #默認: 若krb5.conf中未指定KDC或其餘服務器, 是否使用DNS URI來
                        查詢KDC,若DNS中沒有KDC的URI記錄, 則使用SRV記錄中的定義的KDC.
      k5login_authoritative        #true(默認): 必須在本地用戶的k5login文件中列出主體,以便授予登陸訪問權限(若是存在.k5login(5)文件)。
                      false: 即便存在k5login文件但沒有列出主體,仍然能夠經過其餘機制授予主體登陸訪問權。
      k5login_directory      #設置Kerberos查詢k5login文件的路徑. 默認找~/.k5login.
      kdc_timesync=1      #默認, CA迴應客戶端的ticket中,若時間戳與本地系統時間有差距,則kerberos客戶端
                  在訪問服務器時,會自動使用該時差,調整發送數據包中的時間戳,但不修改本地系統時間.

      realm_try_domains =[-1|0|1|..]    #設置-1:不轉換.
                      0:FQDN(server.a.com)將a.com轉換爲Realm名,
                      1:僅將com轉換爲Real名. 依次類推.


  [realms]
    admin_server=[IP|Hostname]     #設置主KDC服務器是誰, 建議必須指定, 若不指定它將默認根據[libdefaults] dns_lookup_kdc
                      的值來決定是否向DNS查詢KDC, 但自動查詢KDC存在缺陷,不建議使用.
      kdc = [IP|Hostname]          #用於指明當前KDC服務器的地址.
    auth_to_local_names          #本小節容許您設置從主體名稱到本地用戶名稱的顯式映射。標記是映射名,值是對應的本地用戶名。
    default_domain            #將Kerberos4的principals轉換爲Kerberos5的principals,如:rcmd.hostname => host/hostname.domain.
    http_anchors=[FILE:OpenSSL-Style-CA.pem |DIR:/path/*.pem |ENV:X509_PROXY_CA]
        # 當經過HTTPS代理訪問KDCs和kpasswd服務器時,可使用此標記指定CA證書的位置,
          應該信任CA證書爲代理服務器頒發證書。若是未指定,則使用系統範圍的缺省CA證書集。

    kdc= [ [Hostname |IP][:Port] | [IPv6][:Port] ]    #設置本realm中運行的KDC主機的IP或主機名. 若爲IPv6+端口,IPv6要用中括號括起來.
    master_kdc                 #若realm中有主KDC,從KDC,的環境中,客戶端修改了密碼,從KDC尚未同步,
                          致使認證失敗,這時若設置主KDC,客戶端將直接向主KDC認證.
    kpasswd_server        #指向執行全部密碼更改的服務器。若是沒有這樣的條目,將嘗試admin_server主機上的端口464。
    auth_to_local        #用於定義將主體名映射爲本地用戶名的映射規則.【這部分不是很懂】

  示例:
    [realms]
    TEST.COM = {
      kdc = kerberos.test.com
      admin_server = kerberos.test.com
      auth_to_local = RULE:[2:$1](johndoe)s/^. * $/guest/
      auth_to_local = RULE:[2:$1;$2](^. * ;admin$)s/;admin$//
      auth_to_local = RULE:[2:$2](^. * ;root)s/^. * $/root/
      auto_to_local = DEFAULT
      }
    注:
      此標記容許您設置將主體名稱映射到本地用戶名的通常規則。若是對正在翻譯的主體名稱沒有顯式映射,
    則將使用它。可能的值是主體名稱將用做本地用戶名。若是主體有多個組件或不在默認域中,則此規則
    不適用,轉換將失敗。
    auth_to_local 表達式的格式:
      [n:string](regexp)s/pattern/replacement/g
      注:
        n:  爲整數,指明目標主體應該有幾部分組成。
        string:   是引用後面(regexp).. 正則匹配到的內容. 's///g'這是查詢替換的語法,g:全局替換.
            若是主體是johndoe/admin,那麼[2:$2$1foo]將生成字符串adminjohndoefoo)。
            若是這個字符串匹配regexp,那麼將在該字符串上運行s//[g]替換命令。
            可選的g將致使對字符串的替換是全局的,而不是隻替換字符串中的第一個匹配項。
            上面三個示例說明: 將致使任何沒有root或admin的主體做爲第二個使用默認規則進行翻譯的組件。
            帶有第二個admin組件的主體將成爲它的第一個組件。根將用做具備根的第二個組件的任何主體的本地名稱。
            這兩條規則的例外是任何主體johndoe/*,它老是獲取本地名稱guest。【仍是不懂如何使用!】

  [domain_realm]
    #部分提供了從域名或主機名到Kerberos realm name的轉換。注:主機名和域名應該用小寫字母。
    crash.mit.edu = TEST.ATHENA.MIT.EDU
    .dev.mit.edu = TEST.ATHENA.MIT.EDU
    mit.edu = ATHENA.MIT.EDU
      #在將域名映射爲Kerberos的Realm名時,越精確越優先匹配,此例中若前兩個都沒有匹配,則屬於mit.edu域的全部
      主機名都將被映射爲ATHENA.MIT.EDU. 若主機名也不匹配mit.edu,則根據[libdefaults] realm_try_domains
      的設置值,來嘗試將徹底合格域名的主機名,中的域名部分轉換爲Kerberos Realm名.
    realm_try_domains=[-1|0|1|..] # -1:不轉換. 0:FQDN(server.a.com)將a.com轉換爲Realm名, 1:將com轉換爲Real名.
                    依次類推.


  Kerberos Ticket(票證) 緩存類型和密鑰文件(keytab)
    ccache type 是定義具體的keytab密鑰文件以什麼方式緩存在Kerberos客戶端, 它支持緩存在進程內存中,
    或緩存在磁盤上,表現爲具體的文件,也支持使用KCM這類緩存密鑰文件的服務器上.
    而keytab部分主要說明, 它的組成及內部格式.

  ccache type:
    ticket緩存,是爲了不客戶端屢次訪問Web或Mail服務時,每次都向KDC發送驗證信息,獲取ticket,
  從而提升客戶端的訪問體驗. 但緩存密鑰會帶來必定的風險, 由於緩存的密鑰將容許,登陸用戶直接
  登陸受權主機,而無需密碼. 因此須要謹慎使用.
    klist -A 可查看緩存信息.
    它輸出的信息包含:服務端principal名,客戶端prinicipal名,生存期信息和標誌,及ticket自己等.
    ticket的緩存類型有七類:
      1.KEYRING:僅linux可用,它使用內核KEYRING支持將認證數據存儲在不可交換的內核內存中,只有當前用戶才能訪問它。
        它支持:
        • KEYRING:name
        • KEYRING:process:name - process keyring
        • KEYRING:thread:name - thread keyring
        • KEYRING:session:name - session keyring
        • KEYRING:user:name - user keyring
        • KEYRING:persistent:uidnumber     #此類型必須內核支持,不然它將默認使用user keyring.
      2.DIR: 在多Kerberos realm或多KDC環境下比較經常使用,它用於指定一個目錄,來統一緩存這些ticket.
      3.FILE: 默認值.緩存單個ticket.
      4.MEMORY:若ticket僅被一個進程所使用,可以使用內存來緩存ticket,這樣更安全,並且當進程退出時,
            ticket將被銷燬.
      5. MSLSA和API: 僅適用於Windows
      6.KCM: 使用KCM服務器來緩存ticket,但Kerberos5目前還未實現KCM,若要使用有兩種途徑:
          1.使用Heimdel提供的KCM.

          2.必須是OS X系統,它實現了一個自帶的KCM.

  keytab(key table):
    它如其名,它一般是一個標準文件,文件中每行存儲一個principal name 對應的密鑰版本號、加密類型和加密密鑰自己,及時間戳組成.
   它主要用於容許服務器應用程序接受來自客戶機的身份驗證,但也可用於爲客戶機應用程序獲取初始憑據。

    圖片未上傳,請自行使用 klist  -k  KeytabFile   -teK  查看.
    它的格式:
      type:value
      type: 有三種值: 【注: 這部說明,和ccache不知道有何區別.】
      FILE:表示一個標準文件,其值必須爲絕對路徑的文件名.
      MEMORY:表示存儲在當前進程內存中的臨時keytab.
      SRVTAB:表示不支持Kerberos 4 SRVTAB格式的文件

    klist -k #可查看keytab.
    kadmin:可用它們從KDC數據庫中提取密鑰.
    ktadd :能夠建立或附加Keytabs
    ktutil(1)和k5srvutil(1)命令可操縱Keytabs

  服務器端默認keytab:
    若是應用程序沒有請求特定的keytab,則服務器應用程序將使用缺省keytab。默認keytab的名稱由如下內容決定,按優先級遞減順序排列:
    1. KRB5_KTNAME:使用此環境變量指定的keytab
    2. 使用配置文件中default_keytab_name所指定的keytab
    3. 按照代碼中缺省keytab查找 FILE:/etc/krb5.keytab。


  客戶端默認Keytab查找順序:
    1.The KRB5_CLIENT_KTNAME environment variable.
    2. The default_client_keytab_name profile variable in libdefaults.
    3. 按照代碼中缺省keytab查找FILE:/var/kerberos/krb5/user/%{euid}/client.keytab


kdc.conf:

  此配置文件是krb5.conf的補充,它們可合併在一塊兒.此配置文件是給krb5kdc,kadmind守護進程及kdb5_util程序使用的配置文件.
該文件默認位置: /var/kerberos/krb5kdc, KRB5_KDC_PROFILE:此環境變量可用於指定自定義的kdc.conf文件的位置.
另注: 全部對kdc.conf的修改,都須要重啓KDC服務,方可生效.

它包含如下部分:
  [kdcdefaults] KDC行爲的默認值
  [realms] 特定於realm的數據庫配置和設置
  [dbdefaults]數據庫默認設置
  [dbmodules] Per-database settings
  [logging] 控制Kerberos守護進程執行日誌記錄的方式

此配置文件主要配置:
  [kdcdefaults] 和 [realms],kdcdefaults是提供kdc默認值的,即 realms中沒有提供的參數值,
  將從該定義中獲取該參數值.


[realms]:
  acl_file      #訪問控制列表文件的位置,kadmind使用該文件肯定容許哪些主體以及
            Kerberos數據庫上的哪些權限。
  database_module:    #默認值是域名。若無[dbmodules]段,則默認值將用於全部數據庫參數。
  database_name:       #當前realm的Kerberos數據庫的位置。默認值是/var/kerberos/krb5kdc/principal.
            【注: 此參數,已標記爲廢棄】
  default_principal_expiration      #指定在此realm中建立的principals默認過時時間。默認爲0:即從不過時
  default_principal_flags:       #指定在此realm中建立principal時的默認屬性.
                  可指定多個默認屬性字段,每一個字段用逗號隔開; +: 表示啓用, -:禁用.
                  默認啓用的屬性: postdateable, forwardable, tgt-based, renewable,
                    proxiable, dup-skey,allow-tickets, 和service
         preauth:若是在客戶端主體上啓用了此標誌,則須要該主體在接收任何票據以前對KDC進行預認證。
            在服務主體上,啓用此標誌意味着該主體的服務票證將只頒發給具備已設置預驗證位的TGT的客戶端。

  allow-tickets    #啓用給認證客戶端生成ticket,不啓用,意味着客戶端將沒法認證.
  dup-skey      #啓用此標誌容許主體爲另外一個用戶獲取會話密鑰,從而容許對該主體進行用戶對用戶的身份驗證。

  restrict_anonymous_to_tgt=false    #false:容許匿名principal對服務principal的票證請求.
                    true:拒絕匿名訪問,不容許對服務進行匿名身份驗證.
  kadmind_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #可指定多個,用逗號隔開.
  kadmind_port=[Port]          #默認kadmind守護進程的監聽的端口爲749,若設置了kadmind_listen,則該參數
                    設置的端口將覆蓋此參數的值.
  kdc_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #指定krb5kdc守護進程的UDP監聽地址和/或端口
  kdc_ports :          #krb5kdc守護進程監聽UDP請求的端口,默認端口爲88
  kdc_tcp_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #指定krb5kdc守護進程的TCP監聽地址和/或端口
                        若要禁用TCP,可將該值設置爲kdc_tcp_listen=""。
  kdc_tcp_ports:       #krb5kdc守護進程監聽TCP請求的端口,默認端口爲88
  kpasswd_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #指定kadmind的kpasswd守護進程監聽的地址和端口,默認464.
  kpasswd_port       #設置kpasswd的監聽端口
  max_life           #指定票證在此域(realm)中可能有效的最大時間段。默認值是24小時。
  max_renewable_life:       #指定有效票證在此領域中能夠更新的最長時間。默認值爲0:不可更新。
  no_host_referral        #列出要阻止得到基於主機的引用處理的服務,即便客戶機將服務器主體標記爲基於主機的,
                或者服務也列在host_based_services中。no_host_reference =*將徹底禁用引用處理。
  des_crc_session_supported=true    #true:提供對弱加密方式des-cbc-crc的支持,但kbr5.conf[libdefaults]中若
                    定義了allow_weak_crypto=false,即不容許弱加密,則此參數無效.
  key_stash_file           # 指定主鍵存儲的位置(經過kdb5_util stash)。
                    默認/var/kerberos/krb5kdc/.k5.REALM,其中領域是Kerberos領域。
   supported_enctypes    #指定此域中主體的默認key/salt組合。經過kadmin建立的任何主體都將具備這些類型的key。
            這個標籤的默認值是:
              aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal
              des3-cbc-sha1:normal arcfour-hmac-md5:normal。


kadm5.acl:
    Kerberos kadmind守護進程使用訪問控制列表(ACL)文件管理Kerberos數據庫的訪問權限。
  對於影響主體(principal)的操做,ACL文件還控制哪些主體(principals)能夠操做哪些其餘主體。
  若修改了該ACL文件,必須重啓kadmind,才能使配置生效.

語法格式:
  #: 註釋行

  #ACL文件中的行順序很重要。第一個匹配條目將控制目標主體上的參與者主體的訪問。
  principal permissions [target_principal [restrictions] ]
  注:
    principal: 指定要控制權限的主體名,可以使用'*'作通配符
    permissions: 設置主體可執行 和 不可執行的操做.該值可由如下多個字符組成.
          如下字母,小寫爲容許操做, 大寫爲不容許操做.
          a 容許添加主體或策略
          c 容許更改主體的密碼
          d 容許刪除主體或策略
          e 容許提取主鍵
            注:該特權容許用戶從數據庫中提取密鑰,必須很是當心地處理,以免泄露重要密鑰,
              好比kadmin/*或krbtgt/*主體的密鑰。
          i 容許查詢主體或策略
          l 容許列出全部主體或策略
          m 容許修改主體或策略
          p 容許傳播主體數據庫(用於增量數據庫傳播)
             s 容許爲主體顯式設置鍵
          x|* admcilsp的縮寫。全部特權(但不包含e)
        注:
          lockdown_keys主體屬性可用於防止從特定主體提取密鑰,而無論授予的特權是什麼。

      target_principal: [可選],指定可應用權限的主體,主體名可以使用通配符'*',【不懂和principal的區別】
      restrictions: [可選]
          {+|-}flagname #flagname強制指定值。容許的標誌與kdc.conf中的default_principal_flags變量的標誌相同。
            -clearpolicy #強制策略爲空
          -policy Pol #強制策略爲指定的Pol.
          -{expire, pwexpire, maxlife, maxrenewlife} Time #(getdate字符串)關聯值將強制使用MIN(時間,請求值)。


  ACL文件配置示例:
    #TEST.EDU這個realm(領域)的全部主體(principal)都將具備管理特權.
    */admin@TEST.EDU     *
    joeadmin@TEST.EDU       ADMCIL
    joeadmin/*@TEST.EDU    il          */root@TEST.EDU
    以上三條結合起來看:
      joeadmin用戶,擁有管理admin實例joeadmin/admin@TEST.EDU的全部權限
      但他對null實例joeadmin@TEST.EDU徹底沒有權限(第2行)
      他對root,非admin和 非null實例(例如extra或dbadmin)具備查詢任何具備實例主體的權限(匹配第3行)。

    */root@TEST.EDU       ci      *1@TEST.EDU
          #TEST.EDU中的任何root主體均可以查詢或更改其null實例的密碼,
          但不能查詢或更改其餘任何null實例的密碼。
          (這裏,*1表示反向引用"*/root@TEST.EDU"中'*'所匹配到的內容。)
    */root@ATHENA.MIT.EDU      l     *
          #TEST.EDU中的任何根主體均可以生成數據庫中的主體列表和數據庫中的策略列表。
          這一行與第4行是分開的,由於list權限只能全局授予,而不能授予特定的目標主體。
    sms@ATHENA.MIT.EDU       x      * -maxlife 9h -postdateabl
          #服務管理系統主體sms@TEST_EDU擁有全部權限,可是它建立或修改的任何主體
          都不能得到可更新的ticket(票據)或生命週期超過9小時的ticket。

      注: 這部分我理解不深,但願有更深刻了解的大牛,分享共同窗習



Kerberos數據庫管理:

    kerberos DB中存儲了realm(領域)中全部Kerberos Principal(Kbr主體),他們的密碼,及他們的其餘管理信息.
  Kerberos5 目前使用的是嵌入式高性能數據庫 berkeley DB 1.8版本的.
  該數據庫讀性能很強,但寫通常,大小僅300k左右. 目前已被Oracle收購.

  KbrDB可被三個工具操做:
    管理員:   kdb5_util :來總體管理Kerberos數據庫.
        kadmin: 用來修改數據庫中的具體條目.
    用戶: kpasswd: 來修改本身的密碼.

        kadmin.local : 這是網絡管理Kerberos數據庫的工具,它受到上面提到的ACL文件的訪問控制.


  kdb5_util:
    kdb5_util提供了建立、刪除、加載或轉儲Kerberos數據庫的方法。它還包含滾轉數據庫主鍵的命令,
    以及保存密鑰的副本,以便kadmind和krb5kdc守護進程可使用數據庫而不須要手工輸入密碼.

  kadmin:
    kadmin提供Kerberos主體、密碼策略和服務密鑰表(keytabs)的維護。
    它一般扮演網絡客戶機,使用Kerberos身份驗證與kadmind通訊,來遠程維護數據庫.
  kadmin.local:
    它可直接訪問本地文件系統上的Kerberos數據庫(或經過LDAP),要批量操做數據庫,必須使用kadmin.local。

  建立kerberos數據庫:
    kdb5_util [-r realm] [-d dbname] [-k mkeytype] [-M mkeyname]
    [-kv mkeyVNO] [-sf stashfilename] [-m] command [command_options]
    公共選項說明:
      -r RealmName      #指定Kerberos數據庫的領域名.
      -d DBName      #指定存儲主體(principal)數據庫的名稱;
                  默認狀況下,數據庫是kdc.conf中列出的數據庫,密碼策略數據庫和鎖文件也從這個值派生。
      -k MasterKeyType    #指定DB中主鍵的鍵類型。默認值由kdc.conf中的master_key_type給出。
      -kv MKVerions     #指定數據庫中主鍵的版本號;默認值是1。注意,0是不容許的。
      -M MKName      #數據庫中主鍵的主體名稱。若未指定,則使用kdc.conf中master_key_name的值。
      -sf 隱藏文件名     #若須要建立數據庫的隱藏文件,可以使用此選項設置該隱藏文件名.
      -m            #要求密碼必需從鍵盤輸入
      -P Password      #指定Master DB的數據庫密碼.


    kdb5_util create [-s]    #-s:建立數據庫的隱藏文件,若數據庫存在,則會建立失敗.
                隱藏文件容許KDC向數據庫實用程序(如kadmind、krb5kdc和kdb5_util)進行身份驗證。
        destroy [-f] #-f:不提示用戶,直接刪除數據庫.
        示例:
        建立Kerberos數據庫:
        [root@ldap krb5kdc]# kdb5_util create -s -P zhang75656
        Loading random data
          Initializing database '/var/kerberos/krb5kdc/principal' for realm 'ZCF.COM',
          master key name 'K/M@ZCF.COM'
        
          .k5.ZCF.COM:

            就是建立的數據庫, 建立的隱藏文件.


  管理Kerberos數據庫的兩種方式:
    Kerberos服務器上,本地管理:
    kadmin.local:
      lock      #僅鎖定數據庫(使用時要特別當心!)
      unlock    #Release exclusive database lock
      purgekeys   #從主體中清除之前保留的舊密鑰
      get_strings, getstrs      #在主體上顯示字符串屬性

  遠程管理kerberos的數據庫:
    kadmin -r RealmName [ -p 安全主體名 |-k [-t keytab] | -c ] -s KerberosServer[IP|Hostname]
    注:
      -p : 指定Kerberos數據庫中以存在,而且在kadm5.acl 中爲其配置了足夠權限的安全主體(可理解爲用戶名).
      -k : 若不指定-t Keytab ,則默認使用 /etc/krb5.keytab.中包含的第一個可認證安全主體去鏈接登陸kerberos.
      -c: 使用緩存中的密鑰 或 緩存中的keytab密鑰來登陸kerberos.


另外在官方說明文檔中,還有不少高級部分並未深刻學習.
如: 密碼策略, 數據庫管理等.

 

實驗部分:


  1. 經過Kerberos 協議實現無密碼SSH登陸
  2. 經過Kerberos 協議實現安全的NFS共享



  實驗環境:
      hostname: kerberos.zcf.com
      KerberosServer【192.168.10.21】
        NTPServer
        DNSServer
          |
      ------------------------------------------------
      |                 |
    Hosname:server.zcf.com      Hostname:client.zcf.com
    SSHServer               Client【192.168.10.22】
    NFSServer
    【192.168.10.113】

    注意:
      DNS已經配置好了主機名解析, 若無DNS,必須在/etc/hosts中添加解析記錄.
      NTP服務器也是配置好的, 而且使用ntpdata都強制同步了時間.


KerberosServer:
  1. 安裝Kerberos
    yum install krb5-devel krb5-server krb5-workstation pam_krb5

  2. 修改krb5.conf 和 kdc.conf

    vim /etc/krb5.conf
      # Configuration snippets may be placed in this directory as well
      includedir /etc/krb5.conf.d/

    [logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

    [libdefaults]
    default_realm = ZCF.COM
    dns_lookup_realm = false
    ticket_lifetime = 24h
    renew_lifetime = 1d
    forwardable = true
    rdns = false
    clockskew = 1d
    # default_realm = EXAMPLE.COM
    default_ccache_name = KEYRING:persistent:%{uid}

    [realms]
    ZCF.COM = {
      kdc = kerberos.zcf.com
      admin_server = kerberos.zcf.com
      auth_to_local = RULE:[2:$1](user1)s/^.*$/root/
    }

    [domain_realm]
    .zcf.com = ZCF.COM
    zcf.com = ZCF.COM

  

  vim /var/kerberos/krb5kdc/kdc.conf
    [kdcdefaults]
    kdc_ports = 88
    kdc_tcp_ports = 88

    [realms]
    ZCF.COM = {
      acl_file = /var/kerberos/krb5kdc/kadm5.acl
      dict_file = /usr/share/dict/words
      admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
      max_life = 10h 0m 0s
      max_renewable_life = 7d 0h 0m 0s
      #master_key_name = 'K/M@ZCF.COM'
      supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
      #database_name = /var/kerberos/krb5kdc/principal
    }


  3. 建立Kerberos數據庫
    kdb5_util create -s -P 123456789
      Loading random data
      Initializing database '/var/kerberos/krb5kdc/principal' for realm 'ZCF.COM',
          master key name 'K/M@ZCF.COM'      #建立krb5的數據庫


  4. 建立安全主體(可簡單理解爲 建立用戶)
    注:
    Principal 是由三個部分組成:
    名字(name),實例(instance),REALM(域)。
    好比一個標準的 Kerberos 的用戶是:name/instance@REALM

    kadmin.local
      ?        #列出支持的命令列表
      addprinc     #回車查看幫助

      addprinc zcf
      addprinc user1
      addprinc admin    #建立用戶
      listprincs          #查看
      quit            #退出

  5. 配置網絡訪問Kerberos數據庫的權限
    vim /var/kerberos/krb5kdc/kadm5.acl

      #*/admin@ZCF.COM *   #禁用默認全部admin實例下的安全名具備徹底權限.
      user1@ZCF.COM i         #定義安全主體user1僅可查詢.
      admin@ZCF.COM lae    #定義安全主體admin,可網絡登陸,並具備列出,添加,導出權限.

  6. 啓動Kerberos服務
    systemctl start krb5kdc kadmin
    systemctl status krb5kdc kadmin

  7. 防火牆配置
    firewall-cmd --permanent --add-service=kerberos --add-service=kadmin
    firewall-cmd --reload

  Kerberos實現SSH登陸
    1. SSHServer配置:
      vim /etc/ssh/ssh_config
        GSSAPIAuthentication yes
        GSSAPIDelegateCredentials yes
        GSSAPIKeyExchange yes
        GSSAPITrustDNS yes

    2. 重啓SSHD服務
      systemctl restart sshd

    3. 配置系統支持Kerberos認證登陸
    3.1 安裝kerberos客戶端工具
      yum install krb5-libs krb5-workstation pam_krb5 authconfig

    3.2 從Kerberos服務器上覆制配置文件
      scp kerberos.zcf.com:/etc/krb5.conf /etc/krb5.conf

    3.3 導入主機憑據(Host Credential)
      kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
          #輸入admin這個安全主體的密碼登陸成功後:
      addprinc -randkey host/server.zcf.com      #建立主機憑據,使用自動隨機密碼.
      ktadd -k /etc/krb5.keytab host/server.zcf.com    #導出主機憑據到/etc/krb5.keytab文件中.
          注: admin必須有權限導出,前面已受權了.

    3.4 查看導出的密鑰文件.
      klist -k /etc/krb5.keytab -teK

    3.5 配置系統使用kerberos協議認證
      authconfig --enablekrb5 --krb5kdc=kerberos.zczf.com --krb5realm=ZCZF.COM --update

    4. 配置客戶端鏈接SSH登陸時, 使用指定的安全主體
      vim ~/.k5login
        zcf@ZCF.COM #注: zcf這個安全主體在上文已經添加到kerberos數據庫中.


客戶端配置:
  1. 安裝kerberos支持軟件
    yum install krb5-libs krb5-workstation pam_krb5
      注:
      ubuntu 須要安裝: krb5-user

  2. 修改kerberos主配置文件,可直接從kerberos上覆制
    scp kerberos.zcf.com:/etc/krb5.conf /etc/krb5.conf

  3. 建立並導出主機密鑰
    kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
      addprinc -randkey   host/client.zcf.com
      ktadd -k    /etc/krb5.keytab    host/client.zcf.com

  4. 查看導出密鑰
    klist -k /etc/krb5.keytab -teK

  5. 獲取SSH Server端指定容許的安全主體密鑰,並使用該安全主體作驗證.
    kinit zcf         #輸入密碼後,獲取成功
    klist -l      #查看已經緩存的安全主體zcf的密鑰信息.
      注:
      獲取zcf安全主體的密鑰信息的過程,大體可理解以下:
      #客戶端使用直接的主機憑據中的密鑰對本身的認證信息作加密,
      #而後在附加上主機憑據名,發給KDC.
  可簡單理解:
    主機憑據: host/client.zcf.com: 憑據密鑰: Kc
    注意: 主機憑據名,在發給KDC前,它通常組合格式爲:
      名字: host 實例名: hostname 域名:KDC的Realm
        在測試中,我本身的理解:
      這個主機憑據是從keytab中獲取的, 但keytab中可能有多個
    憑據,到底使用那個? 不一樣軟件搜索Principal(主體)名是不一樣的,
    以下面要說的NFS,它的搜索方式是 host/主機名@realm,
    或nfs/主機名@realm,等...它定義了多個.
    #Kerberos接收到請求後,經過明文:host/client.zczf.com憑據名.
    找到該憑據對應的密鑰, 使用該密鑰對預認證信息解密.

      Client--[憑據名{預認證信息}Kc]---------------->Kerberos(KDC)

    #KDC檢查客戶端的預認證信息,知道該客戶端是合法客戶端,
      接着給該客戶端生成Ticket(TGT:票據),並使用本身的密鑰(Kk)對該Ticket,
      加密,而後使用客戶端的密鑰(Kc), 對客戶端和KDC之間通訊的隨機密鑰加密.

      KDC--[{TGT}Kk {randkey}Kc]------------------>Client

    #客戶端獲取TGT和隨機密鑰後, 接着將 獲取安全主體zcf密鑰的請求 使用隨機密鑰
    加密,並附加TGT認證信息,發給KDC; Kck:KDC和Client直接的隨機密鑰

      Client---[{TGT}Kk {zcf密鑰是什麼}Kck]---------->KDC

   #KDC收到請求後,使用本身的密鑰解密TGT,知道是Client發來的信息,找到與Client
    之間的隨機密鑰,解密請求信息. 獲知Client須要zcf的密鑰,而後,從數據庫中獲取
    zcf的密鑰, 並使用Kck加密,返回給Client.

      KDC--[{zcf的密鑰}Kck]---------------------------->Client

  6. 測試登陸SSH Server
    ssh root@server.zcf.com
      注:
      關於SSH是如何無密碼登陸成功的,我還不是很是理解內部細節.
      個人理解:
        Client 和 SSHServer之間可經過主機憑據得到互相認證.
        過程大體以下:
        Client---[{TGT}Kk {我要和SSHServer通訊}Kck]---------->KDC

          Ks: SSHServer的密鑰
        KDC--[{TGT}Ks {C和S之間的randkey}Kck]--------------->Client

          Kcs: Client和SSHServer之間的隨機密鑰
        Client--[{TGT}Ks {個人認證信息}Kcs]-------------------->SSHServer

    通過上面的過程,SSHServer認證Client成功,可是SSHServer認證成功,
  並不能讓Client登陸,由於,系統必需要求登陸的人,有賬號信息,而上面
  在認證過程當中,並無涉及任何root賬號的密碼信息,所以,沒法向系統
  提供root的密碼,完成系統登陸,所以爲了能完成系統登陸, 我猜測,
  才須要這個中間賬號 zcf ,Client可能在認證經過後,會向SSHServer
  提交zcf這個安全主體,SSHServer再向系統提交該安全主體,由於系統已經啓用了
  Kerberos認證,所以,系統會向Kerberos發起認證,若zcf這個賬號成功認證,
  系統就會容許這次無密碼登陸.


Kerberos+NFS提供安全的網絡共享服務:

  1. 安裝NFS服務器軟件和kerberos支持軟件
    yum install nfs-utils krb5-workstation pam_krb5

  2. 配置NFS導出共享目錄,並啓用kerberos驗證
    mkdir -pv /data/nfs{1,2}

    vim /etc/exports
      /data/nfs1 192.168.10.0/24(rw,sync,sec=krb5p)
      /data/nfs2 192.168.10.0/24(ro,sync)
      注:
      man exports
        sec: sys(默認不加密方式)
        krb5(僅用於身份驗證)
        krb5i(完整性保護)
        krb5p(隱私保護)

  3. 配置NFS使用最新版本.
    vim /etc/sysconfig/nfs
      RPCNFSDARGS="--nfs-version 4.2"

  4. 配置Kerberos相關信息
    4.1 複製Kerberos上的主配置文件krb5.conf到本地.
      scp kerberos.zczf.com:/etc/krb5.conf /etc/krb5.conf

    4.2 添加並導入主機密鑰
      kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
      addprinc -randkey nfs/server.zcf.com
      ktadd -k /etc/krb5.keytab nfs/server.zcf.com
      注:
        其實SSH節配置時,已經建立主機憑據,這裏其實可不建立.
        由於默認NFS從keytab中搜索主機憑據的順序是:
        <HOSTNAME>$@<REALM>
        root/<hostname>@<REALM>
        nfs/<hostname>@<REALM>
        host/<hostname>@<REALM>
        root/<anyname>@<REALM>
        nfs/<anyname>@<REALM>
        host/<anyname>@<REALM>
        只有找到第一個包含的主機憑據,就不在查詢了.

    4.3 驗證導出的密鑰
      klist -k /etc/krb5.keytab -teK

  5. 啓動NFS服務
      systemctl start nfs nfs-secure
      systemctl status nfs nfs-secure

  6. 配置防火牆
    firewall-cmd --permanent --add-service=nfs
    firewall-cmd --reload

  7. SELinux
    NFS服務導出的共享目錄不須要添加SELinux的標籤. 因此不建議給NFS共享添加寫權限.
    從NFSv4.2後exports中多一個security_label,此選項彷佛可設置SELinux標籤。
    翻譯:
      經過設置此選項,使用NFSv4.2或更高版本的客戶機將可以設置和檢索安全標籤(如SELinux使用的那些標籤)。
      只有當全部客戶端使用一致的安全策略時,這纔會有效。注意,早期內核不支持這個導出選項,
      默認狀況下啓用了安全標籤。

      NFS是不支持用戶名密碼這種方式的身份認證的.
      但可經過kerberos這種共享密碼認證協議作驗證.


NFS客戶端配置:
  1. 安裝軟件
    yum install nfs-utils krb5-workstation pam_krb5

  2. 配置Kerberos相關信息
    2.1 複製Kerberos上的主配置文件krb5.conf到本地.
      scp kerberos.zcf.com:/etc/krb5.conf /etc/krb5.conf

    2.2 添加並導入主機密鑰
      kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
      addprinc -randkey nfs/server.zcf.com
      ktadd -k /etc/krb5.keytab nfs/server.zcf.com

    2.3 驗證導出的密鑰
      klist -k /etc/krb5.keytab -teK

  3. 建立掛載點
    mkdir -pv /mnt/nfs{1,2}

  4. 啓動NFS支持Kerberos的rpc.gssd服務.
    systemctl start nfs-secure
    systemctl status nfs-secure

  5. 測試掛載
    5.1 先測試NFS服務是否可正常提供服務
      mount server.zcf.com:/data/nfs2 /mnt/nfs2

    5.2 若上面成功,說明,NFSServer是正常工做的.
      mount -t nfs -o v4.2,sec=krb5p server.zcf.com:/data/nfs1 /mnt/nfs1

    5.3 最後添加/etc/fstab,實現開機自動掛載
      vim /etc/fstab
        server.zcf.com:/data/nfs1 /mnt/nfs1 nfs defaults,rw,v4.2,sec=krb5p 0 0

  另注:
    其實不用每次都使用 kadmin 遠程登陸kerberos,來操做數據庫, 能夠直接在kerberos服務器
    直接將密鑰導出來,scp到每一個客戶端上便可.

遇到的錯誤:
參考文章:
https://blog.csdn.net/weixin_42442164/article/details/82110859
https://blog.csdn.net/weixin_33832340/article/details/86931220 NFS客戶端錯誤: Apr 6 07:27:26 rnode6 rpc.gssd[14301]: ERROR: failed to parse nfs/clnt1e/info Apr 6 07:27:36 rnode6 rpc.gssd[14301]: ERROR: unable to resolve 192.168.10.113 to hostname: Name or service not known 解決: 在DNS上添加對PTR zone.讓DNS支持對192.168.10.113的反向解析 Kerberos錯誤: Apr 06 09:34:47 ldap.zczf.com krb5kdc[5701](info): TGS_REQ (4 etypes {18 17 16 23}) 192.168.10.22: LOOKING_UP_SERVER: authtime 0, nfs/client.zczf.com@ZCZF.COM for nfs/server.zczf.com@ZCZF.COM, Server not found in Kerberos database 解決: 提示沒有找到nfs/server.zczf.com@ZCZF.COM的主體記錄, 就是由於以前作實驗時,沒有搞清楚安全主體的構成. 因此添加錯誤了.只須要在添加一個 nfs/server.zczf.com的安全主體便可.

相關文章
相關標籤/搜索