kerberos用戶安全認證指南

原理介紹

kerberos主要是用來做網絡通信時候的身份認證,最主要的特點就是“複雜”。所以在入坑kerberos之前,最好先熟悉一下其原理。這裏推薦一些別人寫的文章內容來進行簡單彙總:

  1. 鏈接
    kerberos認證原理
    用對話場景來解釋kerbeors的設計過程

  2. 簡圖

     

    kerberos認證流程簡圖

幾個概念的補充

  1. principal
    認證的主體,簡單來說就是"用戶名"

  2. realm
    realm有點像編程語言中的namespace。在編程語言中,變量名只有在某個"namespace"裏纔有意義。同樣的,一個principal只有在某個realm下才有意義。
    所以realm可以看成是principal的一個"容器"或者"空間"。相對應的,principal的命名規則是"what_name_you_like@realm"。
    在kerberos, 大家都約定成俗用大寫來命名realm, 比如"EXAMPLE.COM"

  3. password
    某個用戶的密碼,對應於kerberos中的master_key。password可以存在一個keytab文件中。所以kerberos中需要使用密碼的場景都可以用一個keytab作爲輸入。

  4. credential
    credential是“證明某個人確定是他自己/某一種行爲的確可以發生”的憑據。在不同的使用場景下, credential的具體含義也略有不同:

    • 對於某個principal個體而言,他的credential就是他的password。
    • 在kerberos認證的環節中,credential就意味着各種各樣的ticket。

搭建一個KDC的環境

想要理解Kerberos,最好的方式是自己搭建一個KDC server。同時,這對於開發過程中進行測試也是非常有幫助的。

這裏用ubuntu 16.04爲例,簡單搭一個kdc server

安裝下載

 

apt-get install krb5-admin-server krb5-kdc krb5-user krb5-config

其中,這幾個軟件包的作用分別是:

  • krb5-admin-server: kdc管理員程序,可以讓使用者遠程管理kdc數據庫。
  • krb5-kdc:kdc主程序
  • krb5-user: kerberos的一些客戶端命令,用來獲取、查看、銷燬ticket等等。

配置

/etc/krb5.conf

 

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

[libdefaults]
 default_realm = EXAMPLE.COM
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 400
 renew_lifetime = 600
 forwardable = true
 udp_preference_limit = 1

[realms]
 EXAMPLE.COM = {
   kdc = 127.0.0.1:88
   admin_server = 127.0.0.1
 }

這個配置kdc,kerberos客戶端,以及調用kerberos api時都會使用到。
幾個重要的配置項目包括:

  • ticket_lifetime和renew_lifetime:指定了kdc授權ticket的過期時長,和允許更新現有ticket的時長。
  • realms的section:指定了kdc和admin_server的路徑

/etc/krb5kdc/kdc.conf

 

[kdcdefaults]
    kdc_ports = 750,88

[realms]
    EXAMPLE.COM = {
        database_name = /etc/krb5kdc/example/principal
        admin_keytab = FILE:/etc/krb5kdc/example/kadm5.keytab
        acl_file = /etc/krb5kdc/example/kadm5.acl
        key_stash_file = /etc/krb5kdc/example/stash
        kdc_ports = 750,88
        max_life = 10h 0m 0s
        max_renewable_life = 7d 0h 0m 0s
        master_key_type = des3-hmac-sha1
        supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3
        default_principal_flags = +preauth
    }

這是kdc的專屬配置,可以根據自己的需求修改下kdc數據庫的存放目錄。我都統一放/etc/krb5kdc/example目錄下了。對於這個目錄,自己需要提前建立好。

創建數據庫和principal

  1. 使用kdb5_util創建數據庫,從而可以存放principal相關的信息

 

kdb5_util create -r EXAMPLE.COM -s
  1. 使用kadmin.local來添加principal

 

root@weijiesun-kubuntu:/etc/krb5kdc# kadmin.local
Authenticating as principal root/[email protected] with password.
kadmin.local:  add_principal test-server/[email protected]
WARNING: no policy specified for test-server/[email protected]; defaulting to no policy
Enter password for principal "test-server/[email protected]":
Re-enter password for principal "test-server/[email protected]":
Principal "test-server/[email protected]" created.
kadmin.local:  add_principal test-client/[email protected]
WARNING: no policy specified for test-client/[email protected]; defaulting to no policy
Enter password for principal "test-client/[email protected]":
Re-enter password for principal "test-client/[email protected]":
Principal "test-client/[email protected]" created.
kadmin.local:  ktadd -k /etc/krb5.keytab test-server/[email protected]
Entry for principal test-server/[email protected] with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal test-server/[email protected] with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal test-server/[email protected] with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal test-server/[email protected] with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/etc/krb5.keytab.
kadmin.local:  ktadd -k /etc/krb5.keytab test-client/[email protected]
Entry for principal test-client/[email protected] with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal test-client/[email protected] with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal test-client/[email protected] with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal test-client/[email protected] with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/etc/krb5.keytab.
kadmin.local:  q
root@weijiesun-kubuntu:/etc/krb5kdc#

這裏,我們創建了兩個新的用戶:test-server/[email protected]和test-client/[email protected]。並且把他們的密鑰放到/etc/krb5.keytab這一keytab文件下。

  1. 啓動kdc

 

root@weijiesun-kubuntu:/etc/krb5kdc# service krb5-kdc start
 * Starting Kerberos KDC krb5kdc                                                                                                                                                       [ OK ]
root@weijiesun-kubuntu:/etc/krb5kdc# service krb5-admin-server start
 * Starting Kerberos administrative servers kadmind                                                                                                                                    [ OK ]

當然,對於不同發行版,這一步執行的命令可能會不太一樣。

  1. 用kinit驗證KDC是否啓動成功

 

kinit -k -t /etc/krb5.keytab test-client/[email protected]

kinit對應的是向kdc獲取TGT的步驟。它會向/etc/krb5.conf中指定的kdc server來發送請求。
如果TGT請求成功,你就可以用klist看到它。

 

weijiesun@weijiesun-kubuntu ~ $ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: test-client/[email protected]

Valid starting       Expires              Service principal
2018-08-17T13:50:25  2018-08-17T13:57:05  krbtgt/[email protected]
        renew until 2018-08-17T14:00:25

把kerberos認證流程嵌到項目中

在真正使用kerberos進行身份認證時,我們一般不直接使用kerberos的接口。而是會使用諸如GSSAPI或者SASL等更通用的一些標準接口。之所以這麼做,是因爲:

  • kerberos的接口更瑣碎
  • SASL和GSSAPI都是IETF標準,他們對身份認證這一行爲做了更宏觀的抽象。從而可以靈活的接入不同的認證方案。

GSSAPI

GSSAPI的其流程基本和kerberos類似。在現實應用中,你基本可以假設GSSAPI就是kerberos本身。在我們最常使用的kerberos實現MIT kerberos中,GSSAPI的接口也已經是一個內置項了。

比較推薦MIT官方給出的一個gssapi的sample,是學習kerberos完整認證過程一個非常好的例子。裏面也有詳細的文檔教大家如何使用:

MIT kerberos項目內置的gss-sample也可以拿來學習kerberos的認證過程:

SASL

SASL是一個更加通用的身份認證接口,其接口在設計上可以兼容很多主流的認證方案。很多項目在做身份認證的時候,也是採用的SASL接口和流程。

SASL本身也有很多的實現,我在做小米的Pegasus項目時,採用的是cyrus-sasl

想把sasl集成到項目中,並且使用gssapi作爲其中的認證方案,其實不是特別的容易。這裏給出一些要點:

  • 從設計上而言,SASL上是一個client/server之間進行認證的接口。對於向KDC獲取TGT這一行爲,SASL沒有預留接口。事實上,SASL在做第一步認證時,就假設用戶已經獲取到TGT了。所以這裏需要我們自己實現獲取TGT的代碼,也就是kinit的過程。
  • SASL的用戶名和kerberos的principal命名風格不是完全相同的。在kerberos的標準中,principal的命名方式爲name1/name2/name3/.../nameN@realm; 而在SASL中,用戶名的命名方式爲username/FQDN。因而,在使用SASL的時候,一定要把username和FQDN分開傳給sasl的認證接口,從而構造成kerberos的principal。
  • 認真學習cyrus-sasl的認證示例,並參考這篇文檔



作者:shengofbig
鏈接:https://www.jianshu.com/p/fc2d2dbd510b
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發佈了25 篇原創文章 · 獲贊 15 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章