一、背景說明
最早聽說KDC和Kerberos應該是大三的《應用密碼學》,當時感覺這套對稱密鑰分發機制比非對稱密鑰的PKI分發機制要好理解。但幾年下來由於現實中使用SSL的場景比較比(主要是https)接觸得也就比較多所以對PKI的認識反倒超過了KDC。
Kerberos的接觸印象中只有某運營商大數據平台一主機要ssh到其他主機時需要先kinit申請票據一把,具體原理不是很清楚,也沒有深入探究。這幾天一是比較有空二是感覺以后用得上所以來探究一番,本文可以認為是本鏈接文檔的一次實現。
另外,首先要明確Kerberos是KDC思想的一個具體實現,正如當下的數字簽名證書是PKI思想的一個具體實現一樣;只是他們都實現得都比較好,以至於與各自的思想基本成為同義詞。
二、Kerberos+SSH安裝配置
2.1 安裝配置Kerberos
2.1.1 前置操作
將當前用戶設置成sudo免密碼。編緝/etc/sudoers文件追加以下內容(ls是我當前用戶,操作時請改成自己的):
ls ALL=(ALL) NOPASSWD: ALL
將后續要使用的域名/主機名指向本地。編緝/etc/hosts寫入以下內容(192.168.220.143是我電腦當前的IP,改成自己的;最后的ls-virtual-machine是我電腦當前的主機名,改成自己的;另外如果/etc/hosts存在有將主機名解析到127.0.0.1的條目,則應將其刪除)
127.0.0.1 localhost 192.168.220.143 monarch.example.com monarch krb1.example.com krb1 ls-virtual-machine
2.1.2 安裝Kerberos服務
sudo apt install krb5-admin-server krb5-kdc -y
安裝krb5-admin-server時要確認幾個問題(不同操作系統用Kerberos形式可能有些許差別,但意思都差不多),如下輸入直接回車即可。
指定默認領域,使用EXAMPLE.COM:
Default Kerberos version 5 realm? EXAMPLE.COM
默認領域使用的Kerberos服務器,使用krb1.example.com(前邊2.1我們已將krb1.example.com也指向本地)
Kerberos servers for your realm: krb1.example.com
默認領域使用的管理服務器,一樣使用krb1.example.com:
Administrative server for your Kerberos realm: krb1.example.com
2.1.3 初始化配置
使用以下命令初始化前邊配置的EXAMPLE.COM領域對應的數據庫,並設置該領域的密碼:
sudo krb5_newrealm
編緝/etc/krb5.conf,定位到[domain_realm]節區,追回以下內容:
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
繼續編緝/etc/krb5.conf,在文件末尾追加以下內容,設置其日志文件目錄:
[logging]
kdc = FILE:/var/log/kerberos/krb5kdc.log admin_server = FILE:/var/log/kerberos/kadmin.log default = FILE:/var/log/kerberos/krb5lib.log
由於/var/log/kerberos目錄是不存在的,所以我們還要把這日志目錄和文件創建出來:
sudo mkdir /var/log/kerberos sudo touch /var/log/kerberos/{krb5kdc,kadmin,krb5lib}.log sudo chmod -R 750 /var/log/kerberos
最后為使以上配置生效,我們需要重啟服務:
sudo invoke-rc.d krb5-admin-server restart sudo invoke-rc.d krb5-kdc restart
2.1.4 創建策略集
策略集就是規則的集合,我們這里創建admin/host/service/user四個策略集(minlength是策略集的密碼長度,minclasses是密碼的元素種類),過程如下:
ls@ls-virtual-machine:~$ sudo kadmin.local Authenticating as principal root/admin@EXAMPLE.COM with password. kadmin.local: add_policy -minlength 8 -minclasses 3 admin kadmin.local: add_policy -minlength 8 -minclasses 4 host kadmin.local: add_policy -minlength 8 -minclasses 4 service kadmin.local: add_policy -minlength 8 -minclasses 2 user kadmin.local: kadmin.local: quit
2.1.5 在規則集下創建具體賬號
其中的user表示隸屬user策略集,ls是用戶名(ls是我當前用戶名,改成自己的);設置的密碼一定要記住,因為該賬號要獲取票據時要使用該密碼:
ls@ls-virtual-machine:~$ sudo kadmin.local Authenticating as principal root/admin@EXAMPLE.COM with password. kadmin.local: addprinc -policy user ls Enter password for principal "ls@EXAMPLE.COM": Re-enter password for principal "ls@EXAMPLE.COM": Principal "ls@EXAMPLE.COM" created. kadmin.local: kadmin.local: quit
2.2 ssh集成Kerberos
經過以上步驟,我們已經安裝好了Kerberos,現在來演示如何使用kerberos完成ssh認證和登錄。
2.2.1 安裝ssh
sudo apt install openssh-server openssh-client
2.2.2 配置ssh支持Kerberos認證
編緝/etc/ssh/sshd_config,啟用以下項(其中最后的“UsePAM yes”一般已啟用):
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
GSSAPIKeyExchange yes
UsePAM yes
重啟ssh使配置生效:
sudo invoke-rc.d ssh restart
2.2.3 創建ssh登錄相關規則
service仍然是我們前面添加的service策略集;host是telnet/rsh/ssh等服務在kerberos中的統稱,monarch.example.com是規則適用的主機名:
ls@ls-virtual-machine:~$ sudo kadmin.local Authenticating as principal root/admin@EXAMPLE.COM with password. kadmin.local: addprinc -policy service -randkey host/monarch.example.com Principal "host/monarch.example.com@EXAMPLE.COM" created. kadmin.local: ktadd -k /etc/krb5.keytab -norandkey host/monarch.example.com Entry for principal host/monarch.example.com with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/monarch.example.com with kvno 1, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/monarch.example.com with kvno 1, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/monarch.example.com with kvno 1, encryption type des-cbc-crc added to keytab WRFILE:/etc/krb5.keytab. kadmin.local: kadmin.local: quit
2.2.4 獲取用戶票據
ls是我當前的用戶名,改成自己的;獲取票據的密碼是2.5中創建規則時設的密碼(klist -f用於查看當前存在的票據):
ls@ls-virtual-machine:~$ kinit ls Password for ls@EXAMPLE.COM: ls@ls-virtual-machine:~$ ls@ls-virtual-machine:~$ klist -f Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: ls@EXAMPLE.COM Valid starting Expires Service principal 2019-08-06T15:56:52 2019-08-07T01:56:52 krbtgt/EXAMPLE.COM@EXAMPLE.COM renew until 2019-08-07T15:54:39, Flags: FPRIA
2.2.5 登錄測試
使用使用獲取票據的用戶(ls)及可通過票據登錄的主機(monarch.example.com),如下不需要密碼即可直接登錄:
三、原理分析
因為有不少概念自己也不太確定,理解可能有偏差甚至錯誤,所以在閱讀時需要自行斟酌。
3.1 KDC原理
角色:密鑰分發中心KDC、用戶A、用戶B。KDC保存有與用戶A、用戶B通信的對稱密鑰,用戶A、用戶B保存有與KDC通信的對稱密鑰。
期望操作:用戶A想和用戶B進行通信。
實現過程:用戶A向KDC,使用Ka-kdc加密,發送想與用戶B通信的請求。
KDC接收到請求后,使用Ka-kdc解密,生成Ka-b,並將其使用Ka-kdc加密發送給A、使用Kb-kdc加密發送給B。
A和B接收到后,分別使用Ka-kdc和Kb-kdc解密出Ka-b。
A使用Ka-b向B發送加密消息。
說明:可以看到,在此模式中KDC需要存儲與所有用戶通信的Key,而所有用戶只需要存儲與KDC通信的Key,用戶與用戶之間的Key是動態生成和分發的。
3.2 Kerberos過程
角色:認證服務器AS、票據認可服務器TGS、服務器端DS、客戶端A;前兩者相當於KDC,前三者是Kerberos所指的三個服務器。前三者存放有相互通信所用的對稱密鑰,客戶端A不存放任何對稱密鑰。
期望操作:客戶端A想和服務器端DS進行通信。
實現過程:客戶端A向AS,以明文形式,索取訪問TGS的票據。
AS收到請求后,驗證A發來的用戶名密碼,如果正確則生成Ka-tgs,並將其使用借助密碼生成的Ka-as加密發送給A、使用Kas-tgs加密發送給TGS。
A收到后根據也根據密碼生成Ka-as解密,TGS也使用Kas-tgs解密。
A使用得到的Ka-tgs,加密,向TGS請求與B進行通信。
TGS接收到請求后,使用Ka-tgs解密,根據其意向,生成Ka-b,並將其分別使用Ka-tgs加密發送給A、使用Kb-tgs加密發送給B。
A和B接收到后,分別使用Ka-tgs和Kb-tgs解密出Ka-b。
A使用Ka-b向B發送加密消息。
說明:Kerberos將KDC拆分為AS和TGS兩個服務,這樣的好處是,Ka-tgs是有有效期的不再像前邊Ka-kdc一樣長期有效,當Ka-tgs過期之后用戶可以通過輸入密碼獲取新的Ka-tgs。
3.3 SSH中的Kerberos過程
角色對應:Kerberos啟了哪些進程/服務還沒有分析哪個是AS哪個是TGS就先不懂,SSH服務端相當於DS,SSH客戶端相當於客戶端A。
操作對應:2.1.5的創建賬號,就是在AS數據庫中導入賬號信息。
2.2.4中kinit ls,就是向AS申請訪問TGS的票據。
2.2.5中登錄時,SSH客戶端才向TGS請求訪問SSH服務端。
3.4 KDC與PKI的優劣分析
從最終效果上看,KDC和PKI都完成了對稱密鑰的分發,即效果是一樣的。
從前置條件上看,首先KDC在仍意環境中都需要一個專門的服務(器),其次其要存儲的用戶數據(用戶名、密碼或對稱密鑰)會隨用戶的增長而增長,最后由於用戶和KDC之間使用的是對稱密鑰所以非否性可能會有問題。
總的而言,感覺KDC適用於內部網絡服務之間的通信,PKI適用於外部網絡客戶端與服務器之間的通信。
參考:
http://techpubs.spinlocksolutions.com/dklar/kerberos.html#krb-install