FreeBSD 上使用Kerberos 5認證

- 中國WEB開發者網絡 (http://www.webasp.net)
-- 技術教程 (http://www.webasp.net/article/)
--- FreeBSD 上使用Kerberos 5認證 (http://www.webasp.net/article/18/17073.htm)
-- 作者:未知
-- 發佈日期: 2005-03-18
第一部分 Kerberos 協議介紹

1.Kerberos 協議簡介


在希臘神話中,Kerberos是守護地獄之門的三頭狗。在計算機世界裡,美國麻省理工學院(MIT)把他們開發的這一網絡認證系統命名為Kerberos。 Kerberos認證協議是由美國麻省理工學院(MIT)在80年代首先提出並實現的,是該校Athena計劃的一部分。因為Kerberos是一個三方認證協議,根據稱為密匙分配中心(KDC)的第三方服務中心來驗證網絡中計算機相互的身份,並建立密匙以保證計算機間安全連接。Kerberos協議基本上是可行的並且有效的。KDC有兩個部分組成:認證服務器AS和票據授權服務器TGS。Kerberos是一種網絡認證協議,允許一台計算機通過交換加密消息在整個非安全網絡上與另一台計算機互相證明身份。一旦身份得到驗證,Kerberos協議將會給這兩台計算機提供密匙,以進行安全通訊對話。Kerberos協議可以認證試圖等錄上網用戶的身份,並通過使用密匙密碼為用戶間的通信加密。總的來說,Kerberos 是一種基於私鑰加密算法的,需要可信任的第三方作為認證服務器的網絡認證系統。它允許在網絡上通訊的實體互相證明彼此的身份,並且能夠阻止旁聽和重放等手段的攻擊。不僅如此,它還能夠提供對通訊數據保密性和完整性的保護。

Kerberos從提出到今天,共經歷了五個版本的發展。其中版本1到版本3主要由該校內部使用。當它發展到版本4的時候,已經取得了在MIT校園外的廣泛認同和應用。由於版本4的傳播,人們逐漸發現了它的一些局限性和缺點(例如適用網絡環境有限, 加密過程存在冗余等等).MIT充分吸收了這些意見,對版本4進行了修改和擴充,形成了今天非常完善的版本5。現在可以MIT提供的Kerberos V5的最新實現是版本krb5 1.3.3,本文中提到的實現都是以它為依據的。




2.Kerberos協議術語解釋




Principal:在Kerberos中,Principal是參加認證的基本實體。一般來說有兩種,一種用來表示Kerberos數據庫中的用戶,另一種用來代表某一特定主機,也就是說Principal是用來表示客戶端和服務端身份的實體, Principal的格式採用ASN.1標準,即Abstract Syntax Notation One,來準確定義),Principal是由三個部分組成:名字(name),實例(instance),REALM(域)。比如一個標準的Kerberos的用戶是:name/instance@REALM 。

Name:第一部分。在代表客戶方的情況,它是一個用戶名;在代表主機的情況,它是寫成host。

Instance:第二部分。對name的進一步描述,例如name所在的主機名或name的類型等,可省略。它與第一部分之間用『 / 』分隔,但是作為主機的描述時寫成host/Instance。

Realm:第三部分。是Kerberos在管理上的劃分,在 KDC中所負責的一個域數據庫稱作為Realm。這個數據庫中存放有該網絡範圍內的所有Principal和它們的密鑰,數據庫的內容被Kerberos的認證服務器AS和票據授權服務器TGS所使用。Realm通常是永遠是大寫的字符,並且在大多數Kerberos系統的配置中,一般Realm和該網絡環境的DNS域是一致的。與第二部分之間用『@』分隔,缺省為本地的Realm。

比如,Principal 「 cnhawk/hawk.the9.com@THE9.COM 」 表示Realm 「 THE9.COM 」中主機hawk.the9.com上的用戶cnhawk ,而Principal 「 host/hawk.the9.com @THE9.COM 」 則通常用來表示Realm 「 THE9.COM」中主機hawk.the9.com。




Credential: Ticket和與它相聯繫的會話密鑰合在一起稱為Credential。之所以有這個概念是因為它們是客戶端在向服務器證明自己的身份時必需的兩樣東西.在一個Ticket的生存期內客戶端會將這兩樣東西以Credential為單位保存在一個Cache文件中。




Ticket: 一個Ticket是一個用於安全的傳遞用戶身份所需要的信息的集合。它不僅包含該用戶的身份,而且包含其它一些相關的信息。一般來說,它主要包括客戶方Principal,目的服務方Principal,客戶方IP地址,時間戳(分發該Ticket的時間),該Ticket的生存期,以及會話密鑰等內容。它的格式亦用ASN.1來準確定義。




Authenticator: 在客戶端向服務端進行認證時,伴隨Ticket一起發送的另外一個部分,它的作用是證明發送Ticket 的用戶就是擁有Ticket的用戶,即防止重放攻擊。它的主要內容是一個時間戳(客戶端發送Ticket的時間),在rfc1510中有它的完整的ASN.1定義。




AS(Authentication Server): 為用戶分發TGT(Ticket Granting Ticket)的服務器。




TGT(Ticket Granting Ticket): 用戶向TGS(Ticket Granting Server)證明自己身份的Ticket.




TGS(Ticket Granting Server): 為用戶分發到最終目的Ticket的服務器,用戶使用這個Ticket向自己要求提供服務的服務器證明自己的身份。在實現上,AS和TGS實際上是由同一程序完成的,因為它們的實現機制並沒有太大的差別,只是在加密所發出的Ticket時所使用的密鑰不同(AS使用用戶的密鑰,而TGS使用會話密鑰)。




KDC(Key Distribution Center):密鑰發放中心,通常將AS和TGS統稱為KDC,有時也把AS 單獨稱為KDC。




3.認證過程




1) Client → KDC:用戶cnhawk向密鑰分配中心(KDC)申請TGT;

2) KDC → Client:通過KDC的用戶密碼認證,cnhawk得到KDC發放的TGT;

3) Client → KDC:申請取得用戶cnhawk所需要的host/s;

4) KDC → Client:KDC根據用戶cnhawk提供的TGT,KDC向cnhawk發放host/s;

5) Client → Server:用戶cnhawk向Server提供cnhawk,TGT和host/s ;Server根據主機的上保存的host/s和用戶cnhawk的信息來驗證cnhawk的登陸申請。

6) Server → Client:Server確認,發送信息給Client允許cnhawk登陸Server。




4.一個應用實例




為了更清楚的說明Kerberos 5認證協議,實際應用中的例子(具體例子可以在我們後邊的實際應用中看到):假設某一局域網A,它的DNS域為the9.com;Realm為THE9.COM;Kerberos的數據庫,AS以及TGS服務器都在主機test1.the9.com上。A中主機test2.the9.com上的用戶cnhawk對應的Principal為cnhawk/test2.the9.com@THE9.COM;A中的另一台主機test3.the9.com上的telnet服務器對應的Principal為host/test3.the9.com@THE9.COM。Rlogin的客戶端程序telnet和服務端程序telnetd都是支持Kerberos的,即都支持Kerberos認證協議。cnhawk想用telnet遠程登錄到A中的另一台主機test3.the9.com上這時cnhawk所要完成的步驟是:




1 運行kinit程序。kinit程序的作用是向AS申請TGT,並將獲得的TGT和會話密鑰放在保存Credential的文件中。為此,cnhawk在命令行上鍵入:




% kinit cnhawk/test1.the9.com



kinit程序在收到AS發回的消息後,就提示cnhawk輸入password:




% kinit cnhawk/test1.the9.com
cnhawk/test1.the9.com@THE9.COM's Password:


在cnhawk正確的輸入password後,kinit程序將這個password用約定的算法轉化為cnhawk的密鑰,並用這個密鑰解密從TGS發回的消息,從而獲得下一步使用的Credential。到此,kinit程序結束。由此可見,cnhawk的password並沒有在網上傳輸,在網上傳輸的只是由cnhawk的密鑰加密後的東西。


2 運行telnet的客戶端程序telnet,為此cnhawk在命令行上鍵入:




test1# telnet -a -l cnhawk test3.the9.com
telnet程序首先在保存Credential的文件中尋找未過期的TGT,並把它交給TGS,從而獲得訪問test3.the9.com上rlogin服務的Ticket。接下來,它把這個Ticket和Authenticator一起發送給test3.the9.com的服務器程序telnetd。telnetd在驗證了cnhawk的身份後,就搜索本地cnhawk主目錄下的文件「.k5login」,在「.k5login」文件中放有允許用rlogin遠程登錄到cnhawk帳戶下的Principal。在找到了cnhawk/test1.the9.com@THE9.COM之後,telnetd就申請一個虛擬終端,並fork一個shell,這時在test1.the9.com的終端上就會顯示:


test1# telnet -a -l cnhawk test3.the9.com

Trying test3.the9.com...

Connected to test3.the9.com.

Escape character is '^]'.

[ Trying mutual KERBEROS5 (host/test3.the9.com@THE9.COM)... ]

[ Kerberos V5 accepts you as `` cnhawk/test1.the9.com@THE9.COM'' ]




FreeBSD/i386 (test3.the9.com) (ttyp1)

%id

uid=1001(cnhawk) gid=0(wheel) groups=0(wheel)







第二部分 Kerberos 5安裝和應用

1.系統安裝


需要安裝兩台FreeBSD 5.2.1的系統,一台FreeBSD 4.9 三個系統我是用虛擬機上安裝的。

測試機A

操作系統:FreeBSD test1.the9.com 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #0: Mon Feb 23 20:45:55 GMT 2004 root@wv1u.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC i386

IP地址:192.168.0.2

機器名:test1.the9.com

測試機B

操作系統:FreeBSD test2.the9.com 4.9-RELEASE FreeBSD 4.9-RELEASE #0: Mon Oct 27 17:51:09 GMT 2003 root@freebsd-stable.sentex.ca:/usr/obj/usr/src/sys/GENERIC i386

IP地址:192.168.0.3

機器名:test2.the9.com

測試機C :

操作系統:FreeBSD test3.the9.com 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #0: Mon Feb 23 20:45:55 GMT 2004 root@wv1u.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC i386

IP地址:192.168.0.4

機器名:test3.the9.com




2.Kerberos 5軟件安裝和配置




Kerberos 5直接在ports中安裝就好了,最新版本為krb5-1.3.1_1。

在測試機A上安裝



Test1# cd /usr/ports/security/krb5/

Test1# make && make install




測試機B上安裝FreeBSD 4.9 在安裝的時候就選擇krb5

在B上安裝DNS


Test2# cd /usr/ports/dns/bind9

Test2# make && make install




在測試機C上安裝


Test3# cd /usr/ports/security/krb5/

Test3# make && make install




我們的選擇測試機A為KDC服務器,測試機B為客戶端。

好我們現在登陸測試機A,在/etc/rc.conf裡添加上以下兩條


kerberos5_server_enable="YES"

kadmind5_server_enable="YES"




這樣服務器下次重新啟動以後就可以直接啟動kerberos5服務了,然後創建/etc/krb5.conf,加上以下的內容;


[libdefaults]

default_realm = THE9.COM

[realms]

THE9.COM = {

kdc = test1.the9.com

admin_server = test1.the9.com

default_domain = the9.com

}

[domain_realm]

.the9.com = THE9.COM

[logging]

default = FILE:/var/log/krb5libs.log

kdc = FILE:/var/log/krb5kdc.log

admin_server = FILE:/var/log/kadmind.log




因為Kerberos需要互相解析域名,設置DNS,能夠互相解析地址。




登陸測試機B,

將測試機A上的/etc/krb5.conf拷貝到測試機B和測試機C上;




3.Kerberos 5的調試和部署




同時reboot掉兩個系統,機器啟動完成以後需要同步兩台服務器的時間,時間對Kerberos 來說非常重要,Kerberos默認允許的時間偏移量很小,如果兩台服務器的時間差超過了Kerberos 允許值,就無法從KDC服務器上取得票據。我寫了腳本定時去時間服務器上來同步時間。時間完成以後開始在測試機A上操作;



Test1# kstash

Master key: hawk

Verifying password - Master key: hawk




Test1# kadmin -l

kadmin> init THE9.COM //添加默認的域名應該和krb5.conf裡保持一致

Realm max ticket life [unlimited]:

kadmin> add cnhawk/test1.the9.com //直接輸入用戶名/後面說明這個是哪個主機的用戶,登陸時候使用cnhawk/test1.the9.com@THE9.CON

Max ticket life [unlimited]:

Max renewable life [unlimited]:

Attributes []:

Password: hawk

Verifying password - Password: hawk

kadmin> exit

hawk#





用戶添加完成以後進行本地測試。


hawk# kinit cnhawk/test1.the9.com@THE9.COM

cnhawk/test1.the9.com@THE9.COM's Password:

hawk# klist -f

Credentials cache: FILE:/tmp/krb5cc_0

Principal: cnhawk/test1.the9.com@THE9.COM




Issued Expires Flags Principal

Jun 7 17:12:21 Jun 8 03:12:21 I krbtgt/THE9.COM@THE9.COM





我們可以看到本地已經拿到票據了。

下面添加測試機B的域名地址信息,就是允許測試機B能登陸測試機A。 特別注意Kerberos必須使用域名來訪問機器。如果使用IP添加主機會出現一些意外的問題。


test1# kadmin -l

kadmin> add --random-key host/test1.the9.com //說明添加的是主機不是用戶

Max ticket life [1 day]:

Max renewable life [1 week]:

Principal expiration time [never]:

Password expiration time [never]:

Attributes []:

kadmin> ext host/test1.the9.com

kadmin> ext --keytab=/tmp/the9.keytab host/test1.the9.com




這樣完成以後就好了,基本配置已經結束了,可以使用。




調試




我們開始使用Kerberos的認證部署網絡服務,注意Kerberos通過修改用戶主目錄下的.klogin和.k5login文件,將你允許登陸的用戶Principal添加在文件裡就好了。



test1# cat .k5login

# $FreeBSD: src/etc/root/dot.k5login,v 1.1 2003/04/30 20:58:49 markm Exp $

#

# user1/root@YOUR.REALM.WHEREVER

# user2/root@YOUR.REALM.WHEREVER

cnhawk/test1.the9.com@THE9.COM




這樣就可以了

使用Kerberos認證的telnet

修改/etc/inetd.conf 添加


telnet stream tcp nowait root /usr/libexec/telnetd telnetd -a user


然後開啟


test2# inetd


然後從test1登陸test2


test1# kinit cnhawk/test1.the9.com //先取得票據

cnhawk/test1.the9.com@THE9.COM's Password:

test1# klist –f //看看是不是取得

Credentials cache: FILE:/tmp/krb5cc_0

Principal: cnhawk/test1.the9.com@THE9.COM




Issued Expires Flags Principal

Jun 11 16:21:36 Jun 12 02:21:36 I krbtgt/THE9.COM@THE9.COM

//可以了

test1# telnet -a -l the9 192.168.0.3 //開始登陸

Trying 192.168.0.3...

Connected to test2.the9.com.

Escape character is '^]'.

[ Trying mutual KERBEROS5 (host/test2.the9.com@THE9.COM)... ]

[ Kerberos V5 accepts you as `` cnhawk/test1.the9.com@THE9.COM'' ]




FreeBSD/i386 (test2.the9.com) (ttyp1)

//登陸歡迎詞

%id

uid=1001(the9) gid=0(wheel) groups=0(wheel)

% //好了成功了





使用Kerberos認證的ssh

修改測試A,B,C的sshd 配置文件。


# Kerberos options

KerberosAuthentication yes

KerberosOrLocalPasswd yes




然後重啟sshd


Test2#kill –HUP 80


開始從test1登陸到test2,因為只有ssh1支持Kerberos,所以使用ssh1連接同時開啟debug信息。


test1# ssh -1v the9@test2.the9.com

OpenSSH_3.6.1p1 FreeBSD-20030924, SSH protocols 1.5/2.0, OpenSSL 0x0090703f

debug1: Reading configuration data /etc/ssh/ssh_config

debug1: Rhosts Authentication disabled, originating port will not be trusted.

debug1: Connecting to test2.the9.com [192.168.0.3] port 22.

debug1: Connection established.

debug1: identity file /root/.ssh/identity type -1

debug1: Remote protocol version 1.99, remote software version OpenSSH_3.5p1 FreeBSD-20030924

debug1: match: OpenSSH_3.5p1 FreeBSD-20030924 pat OpenSSH*

debug1: Local version string SSH-1.5-OpenSSH_3.6.1p1 FreeBSD-20030924

debug1: Waiting for server public key.

debug1: Received server public key (768 bits) and host key (1024 bits).

debug1: Host 'test2.the9.com' is known and matches the RSA1 host key.

debug1: Found key in /root/.ssh/known_hosts:3

debug1: Encryption type: 3des

debug1: Sent encrypted session key.

debug1: Installing crc compensation attack detector.

debug1: Received encrypted confirmation.

debug1: Trying Kerberos v5 authentication.

debug1: Kerberos v5 authentication accepted.

debug1: Requesting pty.

debug1: Requesting shell.

debug1: Entering interactive session.

Last login: Fri Jun 11 16:31:14 2004 from test1.the9.com

Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994

The Regents of the University of California. All rights reserved.




FreeBSD 4.9-RELEASE (GENERIC) #0: Mon Oct 27 17:51:09 GMT 2003




FreeBSD/i386 (test2.the9.com) (ttyp1)

//登陸歡迎詞

%id

uid=1001(the9) gid=0(wheel) groups=0(wheel)

% //好了成功了





測試已經完成了。可以使用Kerberos了。




ftp 服務



%kinit cnhawk/test1.the9.com

Cnhawk/test1.the9.com @THE9.COM's Password:

%klist -f

Credentials cache: FILE:/tmp/krb5cc_1001

Principal: cnhawk/test1.the9.com@THE9.COM




Issued Expires Flags Principal

Jun 11 18:49:56 Jun 12 04:49:56 I krbtgt/THE9.COM@THE9.COM

%/usr/local/bin/ftp -v hawk.the9.com

Connected to hawk.the9.com.

220 hawk.the9.com FTP server (Version 5.60) ready.

334 Using authentication type GSSAPI; ADAT must follow

GSSAPI accepted as authentication type

GSSAPI authentication succeeded

Name (hawk.the9.com:cnhawk):

232 GSSAPI user cnhawk@THE9.COM is authorized as cnhawk

Remote system type is UNIX.

Using binary mode to transfer files.

ftp>





好了FTP也可以接受登陸




總結

Kerberos使用中需要注意一些地方,例如,時間一定要保證同步,因為Kerberos靠時間戳來保持同步,時間允許的飄溢量非常小。所以必須保證時間的準確。

cnhawk# kinit cnhawk/test1.the9.com@THE9.COM
cnhawk/test1.the9.com@THE9.COM's Password:
kinit: krb5_get_init_creds: time skew (314) larger than max (300)
cnhawk# ntpdate time.the9.com
7 Jun 16:59:49 ntpdate[623]: step time server 61.129.93.5 offset 211.348035 sec
cnhawk# kinit cnhawk/test1.the9.com @THE9.COM
cnhawk/test1.the9.com@THE9.COM's Password:


而且很多時候在登陸前要查看票據是不是過期了。

hawk# klist
Credentials cache: FILE:/tmp/krb5cc_0
Principal: cnhawk/test1.the9.com@THE9.COM


Issued Expires Principal

Jun 7 17:19:25 >>>Expired<<< krbtgt/THE9.COM@THE9.COM

Jun 7 17:20:23 >>>Expired<<< host/cnhawk.the9.com@THE9.COM





同時要注意認證時候不只是認證用戶信息,還有主機信息,要保證這兩個信息都在KDC中心數據庫上存儲。這樣才能保證用戶取得票據以後能順利登陸服務器。



webasp.net