Kerberos認證原理及基於Kerberos認證的NFS文件共享

Kerberos認證原理

簡介

kerberos是用於身份認證並且能夠提供雙向認證的協議,使用kerberos,客戶端只需要使用一個密碼就可以對Kerberos域內所有的伺服器進行訪問,每個伺服器也不需要單獨實現自己的認證系統,而是使用他們共信任的Kerberos Distribution Center(KDC)來進行認證服務,因此Kerberos系統中至少包含KDC、Client、Server這三個角色

client訪問server過程

早期的Kerberos基於3個sub-protocol,通過每個sub-protocol執行的方法來梳理Client訪問Server需要的認證流程

  • Long-term Key:長期保持不變的key,比如自己使用的密碼,被稱為Long-term Key。
  • Master Key:將Long-term Key通過哈希運算得到一個hash code,即Master Key。
  • Session Key:在一個session中有效的key

一、Authentication Service Exchange (AS Exchange)

先了解下相關術語:

  1. Authentication Service Request(KRB_AS_REQ):Client向KDC發送的請求,Client使用自己的Master Key對KRB_AS_REQ加密並發送到KDC的Authentication Service(AS),KRB_AS_REQ包含用於證明自己身份的資訊(Pre-authentication data)、Client info、TGS name
  2. Authentication Service(AS):KDC的一個服務,可以簡單理解為驗證Client是否是真的Client,如果是返回KRB_AS_REP
  3. Authentication Service Response(KRB_AS_REP):KDC應答Client的KRB_AS_REQ,KRB_AS_REP包括使用Client的Master Key加密過的Session Key(SKDC-Client)和KDC自己的Master Key加密的TGT
  4. Ticket Granting Ticket(TGT):TGT像是一張憑證,有了這張憑證Client就可以向KDC申請訪問Realm中所有Server,拿到訪問Server的票之後,就可以跟Server建立通訊,TGT包含SKDC-Client、Client info、TGT的到期時間

執行流程如下:

  1. Client向KDC發送KRB_AS_REQ
  2. AS收到KRB_AS_REQ從Database中取出Client的Master Key解密認證
  3. 認證通過後發送KRB_AS_REP到Client
  4. Client收到KRB_AS_REP,包含Client加密的Session Key(SKDC-Client),TGT,使用自己的Master Key解密即可得到SKDC-Client

流程圖如下:

二、Ticket Granting Service Exchange (TGS Exchange)

相關術語:

  1. TGS(Ticket Granting Service):KDC的一個服務,簡單理解為驗證TGT與Client的真實性,驗證通過後像Client返回KRB_TGS_REP
  2. Ticket Granting Service Request(KRB_TGS_REQ):客戶端向KDC發出訪問Server的請求,KRB_TGS_REQ中包含了TGT、證明TGT的擁有者就是Client自己的資訊(Authenticator)、Client info、Server info
  3. Authenticator:在Kerberos中,Authenticator是關於Client的一些資訊和當前的一個timestamp
  4. Ticket Granting Service Response(KRB_TGS_REP):TGS驗證通過後向Client發送的應答,KRB_TGS_REP中包括:
    • Client與Server的Session Key(SServer-Client),並將SServer-Client使用SKDC-Client加密
    • 使用Server的Master Key進行加密的Ticket(用來訪問Server的票),該Ticket中包含SServer-Client、Client info、Ticket的到期資訊

執行流程如下:

  1. 在AS Exchange中我們知道,Client此時擁有SKDC-Client(client與KDC的session key)與TGT,Client生成自己的Authenticator並使用SKDC-Client進行加密,與TGT一同發送到KDC,即KRB_TGS_REQ
  2. KDC接到KRB_TGC_REQ之後,使用KDC自己的Master Key對TGT進行解密(在AS Exchange提到KRB_AS_REP中的TGT是KDC的Master Key加密的)得到Client Info與SKDC-Client,然後使用這個SKDC-Client解密Authenticator獲得Client info,校驗兩個Client info,驗證通過則生成Client要訪問的server的Ticket給Client(此時Client拿到了訪問Server的票),即向Client發送KRB_TGS_REP
  3. Client收到KRB_TGS_REP後使用SKDC-Client解密得到Client與Server的session key(SServer-Client),此時Client就可以帶著SServer-Client與被Server的Master Key加密的Ticket與Server通訊了,無需再有KDC的介入

流程圖如下:

三、Client/Server Exchange (C/S Exchange)

相關術語:

  1. Application Service Request(KRB_AP_REQ):客戶端向伺服器發出請求,KRB_AP_REQ包括證明TGS的擁有者就是Client自己的資訊(Authenticator)、Ticket、用於表示Client是否需要雙向認證的Flag
  2. Mutual Authentication(雙向認證):Server可以對Client進行認證,Client同樣可以對Server進行認證,如果KRB_AP_REQ中包含需要對Server認證的Flag,Server則會提取Authenticator中的timestamp並使用SServer-Client加密後發回給Client,Client解密後對比timestamp相同則認證成功

執行流程:

  1. 在TGS Exchange中我們知道,Client此時擁有SServer-Client和使用Server的Master Key進行加密的Ticket,創建Authenticator並使用SServer-Client加密
  2. 向Server發送Ticket與Authenticator,即KRB_AP_REQ,如果需要進行雙向認證則添加Flag
  3. Server使用自己的Master Key解密Ticket,得到SServer-Client,通過SServer-Client解密Authenticator驗證Client,驗證成功則建立通訊,允許該Client訪問資源。如果KRB_AP_REQ中包含雙向認證Flag,Server還需再向Client證明自己的身份

流程圖如下:

傳統的Kerberos認證流程梳理完畢,目前使用較廣的增加了User2User這個sub-protocol,可以簡單理解為Server也需要獲得TGT,並且使用帶有過期時間的Short-term Key進行加密,因為傳統的Kerberos使用Server的Master Key加密傳輸數據,這樣的做法存在安全隱患

接下來配置Client訪問NFS Server,並通過Kerberos進行認證

配置基於Kerberos認證的NFS文件共享

Centos配置可參考://blog.csdn.net/weixin_42442164/article/details/82110859

ubuntu下配置與Centos配置略有不同,而且網路上幾乎沒有完整的教程,所以此次我們使用Ubuntu來踩坑

環境

系統: ubuntu-16.04-server-amd64.iso,主機名與地址配置

  1. hostname:gclient.ggg.com

    ipaddress:172.17.73.111

  2. hostname:gserver.ggg.com

    ipaddress:172.17.73.112

  3. hostname:gkerberos.ggg.com

    ipaddress:172.17.73.113

相關術語

  1. Realm:可以理解為Kerberos中的域,只有在Realm中的主機才可以使用該認證,約定使用大寫,如GGG.COM
  2. principal:任何需要Kerberos認證的主機都需要principal,例如nfs/gserver.ggg.com
  3. krb5.keytab:從KDC database中提取的含有Client或Server的Master Key的文件

Kerberos相關配置

一、配置hostname

Kerberos需要認證必須依賴於全稱域名(FQDN),我們設置域名為ggg.com,那麼FQDN為hostname.ggg.com,每個主機需要一個獨一無二的認證主體,因此設置不同的hostname,我們不引入DNS伺服器,直接將hostname文件配置為FQDN格式,以客戶端gclient為例進行配置,Server與KDC配置方法相同

  1. 配置hostname為gclient

    echo gclient.ggg.com > /etc/hostname
    hostname -F /etc/hostname
    hostname -f # 輸出hostname
    
  2. 配置hosts文件,使得客戶端可以識別Server與KDC的FQDN,Server與KDC同Client配置相同

    root@gclient:~# cat /etc/hosts
    127.0.0.1       localhost
    127.0.1.1       gclient
    172.17.73.111 gclient.ggg.com gclient
    172.17.73.112 gserver.ggg.com gserver
    172.17.73.113 gkerberos.ggg.com gkerberos
    
  3. ping FQDN測試三台主機互通

二、配置KDC

實驗環境可以先把防火牆關掉ufw disable,否則需要讓防火牆允許Kerberos服務通過

  1. 安裝相關組件 apt-get install krb5-kdc krb5-admin-server,安裝完成後會彈出Kerberos的配置介面,該配置介面也可以使用命令dpkg-reconfigure krb5-kdc來打開

    填寫Realm,Kerberos的Realm為大寫,我們使用GGG.COM

    設置Kerberos server,為我們的Kerberos主機名

    設置Administrative server,因為我們只有一台KDC伺服器,所以設置為這台Kerberos的主機名

  2. 創建Kerberos資料庫,裡面維護著認證系統中所有主機的密碼,krb5_newrealm按照提示設置密碼即可

  3. 為Kerberos添加一個管理員帳號,以管理認證系統中的principal

    root@gkerberos:~# kadmin.local
    Authenticating as principal root/[email protected] with password.
    kadmin.local:  addprinc nfs/[email protected]
    WARNING: no policy specified for nfs/[email protected]; defaulting to no policy
    Enter password for principal "nfs/[email protected]":
    Re-enter password for principal "nfs/[email protected]":
    Principal "nfs/[email protected]" created.
    

    接下來對nfs/[email protected]打開許可權,到目錄/etc/krb5kdc/kadm5.acl設置

    root@gkerberos:~# cat /etc/krb5kdc/kadm5.acl
    # This file Is the access control list for krb5 administration.
    # When this file is edited run /etc/init.d/krb5-admin-server restart to activate
    # One common way to set up Kerberos administration is to allow any principal
    # ending in /admin  is given full administrative rights.
    # To enable this, uncomment the following line:
     */[email protected] *
    
  4. 為Server與Client創建他們的principals

    root@gkerberos:~# kadmin.local
    Authenticating as principal root/[email protected] with password.
    kadmin.local:  addprinc nfs/[email protected]
    WARNING: no policy specified for nfs/[email protected]; defaulting to no policy
    Enter password for principal "nfs/[email protected]":
    Re-enter password for principal "nfs/[email protected]":
    Principal "nfs/[email protected]" created.
    kadmin.local:
    kadmin.local:
    kadmin.local:  addprinc nfs/[email protected]
    WARNING: no policy specified for nfs/[email protected]; defaulting to no policy
    Enter password for principal "nfs/[email protected]":
    Re-enter password for principal "nfs/[email protected]":
    Principal "nfs/[email protected]" created.
    kadmin.local:  q
    
  5. 添加日誌

    /etc/krb5.conf添加

    [logging]
        default = FILE:/var/log/krb5.log
    

    後期發現不打日誌,花了好多時間查到是一個BUG,修復方法是到/lib/systemd/system/krb5-kdc.service ,將ReadWriteDirectories這一行選項最後追加一個/var/log,即ReadWriteDirectories=-/var/tmp /tmp /var/lib/krb5kdc -/var/run /run /var/log,修改完成後使用systemctl daemon-reload命令重新載入

  6. 重啟服務 systemctl restart krb5-admin-server.service krb5-kdc.service

三、配置Server

  1. 安裝相關組件apt-get install krb5-user,在配置介面填寫的內容與Kerberos主機填寫內容相同,即Server、Client與Kerberos的krb5.conf是相同的

  2. 通過我們創建的管理員帳號登錄後獲取Server的krb5.keytab,如下

    root@gserver:~# kadmin -p nfs/[email protected]
    Authenticating as principal nfs/[email protected] with password.
    Password for nfs/[email protected]:
    kadmin:  ktadd -k /etc/krb5.keytab nfs/[email protected]
    Entry for principal nfs/[email protected] with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/[email protected] with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/[email protected] with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/[email protected] with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/etc/krb5.keytab.
    kadmin:  q
    
  3. 使用kinit申請TGT驗證認證配置是否成功,kinit執行完成後使用klist查看憑證已拿到

    root@gserver:~# kinit -kt /etc/krb5.keytab nfs/[email protected]
    root@gserver:~# klist
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: nfs/[email protected]
    
    Valid starting       Expires              Service principal
    08/12/2020 15:23:10  08/13/2020 01:23:10  krbtgt/[email protected]
            renew until 08/13/2020 15:23:00
    

如果這裡有問題請檢查hostname、hosts、krb5.conf、各個principal是否正確,krb5.keytab是否存在,還有最容易忽略的時間是否統一可以手動校準也可以使用NTP、Chrony等時間同步服務來做

四、配置Client

Client與Server的配置方法相同

  1. apt-get install krb5-user,在配置介面填寫的內容與Kerberos主機填寫內容相同

  2. 通過我們創建的管理員帳號登錄後獲取Client的krb5.keytab如下

    root@gclient:~# kadmin -p nfs/[email protected]
    Authenticating as principal nfs/[email protected] with password.
    Password for nfs/[email protected]:
    kadmin:  ktadd -k /etc/krb5.keytab nfs/[email protected]
    Entry for principal nfs/[email protected] with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/[email protected] with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/[email protected] with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/[email protected] with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/etc/krb5.keytab.
    kadmin:  q
    
  3. 使用kinit進行認證

    root@gclient:~# kinit -kt /etc/krb5.keytab nfs/gclient.ggg.com
    klist: Bad format in credentials cache
    root@gclient:~# klist
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: nfs/[email protected]
    
    Valid starting       Expires              Service principal
    08/12/2020 15:38:11  08/13/2020 01:38:11  krbtgt/[email protected]
            renew until 08/13/2020 15:38:11
    
    

至此Kerberos認證系統已經配置完成,接下來引入我們的具體應用NFS文件系統,同時使用kerberos進行驗證

引入NFS

一、配置NFS Server

  1. 安裝nfs server,apt-get install nfs-kernel-server

  2. 創建NFS掛載點mkdir /nfskrb5,並使用krb5安全認證,在/etc/exports中添加/nfskrb5 *(rw,sync,no_subtree_check,no_root_squash,sec=krb5)這一行

  3. 將創建的目錄放出

     root@gserver:~# exportfs -r
     root@gserver:~# exportfs -v
    /nfskrb5        <world>(rw,wdelay,no_root_squash,no_subtree_check,sec=krb5,rw,no_root_squash,no_all_squash)
    

二、配置客戶端

  1. 客戶端安裝相關組件apt-get install nfs-common

  2. 裝完所有服務之後介意重啟Client、Server、Kerberos這三台主機

  3. 使用Client進行掛載,使用mount -vvv 可以查看到掛載過程

    root@gclient:~# showmount -e gserver
    Export list for gserver:
    /nfskrb5 *
    root@gclient:~# mkdir /mnt/krb5
    root@gclient:~# mount -vvv gserver:/nfskrb5 /mnt/krb5/
    mount.nfs: timeout set for Wed Aug 12 17:52:26 2020
    mount.nfs: trying text-based options 'vers=4,addr=172.17.73.112,clientaddr=172.17.73.111'
    

    使用df -h查看發現掛載成功

    root@gclient:/mnt# df -h
    Filesystem                    Size  Used Avail Use% Mounted on
    udev                          2.0G     0  2.0G   0% /dev
    tmpfs                         396M  5.7M  390M   2% /run
    /dev/mapper/gclient--vg-root   45G  1.8G   41G   5% /
    tmpfs                         2.0G     0  2.0G   0% /dev/shm
    tmpfs                         5.0M     0  5.0M   0% /run/lock
    tmpfs                         2.0G     0  2.0G   0% /sys/fs/cgroup
    /dev/sda1                     472M  110M  338M  25% /boot
    tmpfs                         100K     0  100K   0% /run/lxcfs/controllers
    tmpfs                         396M     0  396M   0% /run/user/0
    gserver:/nfskrb5               35G  1.9G   32G   6% /mnt/krb5
    

至此基於Kerberos身份認證的NFS服務已搭建完成

總結

Kerberos認證比較複雜比較繞,所以介意先了解認證過程,然後理解下Realm、principal等配置相關的術語,再開始配置。

配置時需要注意一下幾點:

  • FQDN的設置是否正確,Kerberos是基於域名來做認證的
  • Kerberos對時間差很敏感,Kerberos伺服器、Client、Server之間要保持時間一樣,如果長時間使用介意配置時間同步的相關服務
  • 在添加principal的時候格式是否有誤,可在kadmin狀態下通過list_principals命令查看
  • 生成krb5.keytab的時候不要將Client與Server的搞混
  • 配置完成後記得重啟相關的服務,在最後如果掛載報錯可嘗試重啟主機

參考文檔
//help.ubuntu.com/community/NFSv4Howto
//help.ubuntu.com/community/Kerberos
//blog.csdn.net/wulantian/article/details/42418231
《ubuntu-server-guide》,通過百度網盤分享該文檔:
鏈接://pan.baidu.com/s/1vByL6xSP010wtB5vKRA-8Q
提取碼:tf9v

Tags: