Kerberos这一名词来源于希腊神话『三个头的狗--地狱之门守护者』,系统设计上采用C/S结构与DES加密技术,并且能够进行相互认证,即客户端和服务器端均可对对方进行身份认证。可以用于防止窃听、防止 replay 攻击、保护数据完整性等场合,是一种应用对称密钥体制进行密钥管理的系统。

Kerberos是一种网络认证协议,其设计目标是通过密钥系统为客户机/服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。在以上情况下,Kerberos 作为一种可信任的第三方认证服务,是通过传统的密码技术(如:共享密钥)执行认证服务的。

 

kerberos和ldap结合:

  • ldap存储用户信息,kerberos做身份认证

  • 两者可以独立工作,也可以将ldap作为kerberos的后端数据库。

 

1、 名称解释

kerberos由AS和TGS两个逻辑部分组成的一个受信任的第三方,术语称为KDC。KDC持有一个密钥数据库;每个网络实体,无论是客户还是服务器,共享一套只有他们自己和KDC知道的密钥。密钥的内容用于证明实体的身份。对于两个实体间的通信,KDC产生一个会话密钥,用来加密他们之间的交互信息。

 

  • KDC(Key Distribution Center),密钥分发中心,受信任的第三方,由AS和TGS两部分组成。

  • AS(Authentication Server),认证服务器,用于回复用户初始的认证请求,当用户没有被认证时,他必须输入密码或使用keytab。作为对认证请求的响应,AS分发一个特殊的ticket,被称为Ticket Granting Ticket,简称为TGT。TGT使用krbtgt/REALM@REALM这个principal的密钥来加密。如果用户的确是他所声称的身份,那用户就可以使用TGT来获取其它服务的ticket,而不是重新输入密码。

  • TGS(Ticket Granting Server),票据授权服务器,用于为拥有可用的TGT的客户端分发service ticket(访问它必须使用TGT),service ticket是用来确保访问服务的人的身份是真实的。

 

注意:

  • Kerberos 要求参与通信的主机的时钟同步。票据具有一定有效期,因此,如果主机的时钟与 Kerberos 服务器的时钟不同步,认证会失败。默认设置要求时钟的时间相差不超过2分钟。

 

1.1、 Realm

表示一个认证管理域,属于同一个域的用户使用同样的认证方案。注意,realm名字大小写敏感。

 

1.2、 principal

一个条目的名字,用来引用一个条目。一个Principal和一个特定realm的用户、主机、或者服务相关联。

 

用户:name[/instance]@realm 

  • name,指登陆用户名

  • instance,可选,指定用户角色,一个用户可能有不同角色,既是管理员(admin),也是一个普通用户(默认不指定就是)

  • realm,指定所在域

 

主机: host/hostname@realm

  • host,表示对一台主机的通用访问,如:telnet,ssh

  • hostname,提供这个服务的主机的FQDN,注意:FQDN需要能被DNS正反解析

  • realm,指定所在域

 

服务:service/hostname@realm

  • service,服务的名字,如:ftp,imap,

  • hostname,提供这个服务的主机的FQDN,注意:FQDN需要能被DNS正反解析

  • realm,指定所在域

 

例:

#没指明instance和realm,表示是普通用户角色和默认域

Tom

 

#同理

tom@EXAMPLE.COM

 

#tom以管理员身份登陆

tom/admin@EXAMPLE.COM

 

#指明在node1.example.com这台主机上的一个服务,叫ftp

ftp/node1.example.com@EXAMPLE.COM

 

1.3、 Ticket

Ticket由认证服务器分发,用于客户端提供给应用服务器表明自己真实身份的东西。会分别用用户和服务密钥加密,发给客户端。

 

ticket包含的信息:

  • 发出请求的用户的principal(通常就是用户名)

  • 想要访问的服务的principal

  • 客户端所在机器的IP地址。

  • 准备启用ticket的时间戳(日期+时间)

  • ticket的最大生存时间(通常10小时)

  • session key,将来用于用户和服务之间的会话加密

 

1.4、 密钥

使用hash算法,将明文密码后面加盐之后,进行hash,得到密钥。加盐是为了即使两个用户的密码一样,也会有不同的密钥。

 

1.5、 keytab

以文件的形式呈现,存储了一个或多个Principal的长期的key,用途和密码类似,用于kerberos认证登录;其存在的意义在于让用户不需要明文的存储密码,和程序交互时不需要人为交互来输入密码

 

2、 kerbors身份验证过程

使用Kerberos时,一个客户端需要经过三个步骤来获取服务:

  • 认证:客户端向认证服务器发送一条报文,并获取一个含时间戳的 Ticket-Granting Ticket(TGT)。

  • 授权:客户端使用TGT向TGS请求一个服务Ticket。

  • 服务请求:客户端向服务器出示服务Ticket,以证实自己的合法性。该服务器提供客户端所需服务。

 

2.1、 用户向KDC证明身份

  • 客户端用户使用自己的密钥,加密当前时间戳,然后将以下信息发送给AS:加密的时间戳+账号信息

  • AS收到请求,根据账号信息,先从数据库中查寻该用户是否存在,如果存在,查寻该用户的密码,并进行hash,得到用户密钥,解密时间戳。如果能解开,并且时间戳和本地时间相差在2分钟内,验证成功。

 

2.2、 KDC向用户证明身份

用户验证成功后,KDC也要向用户证明身份,理论上来说,KDC可以使用上面同样的方法来证明自己,但这样,KDC会非常忙碌,所以实际工作原理如下:

  • AS生成一个用于Client/TGS之间会话的seesion key,一式两份,一份加上时间戳用用户的密钥加密,另一份将和用户信息一起打包(ticket-granting-ticket,TGT),并用TGS的密钥进行加密,最后将两份数据都发送给客户端

  • 客户端收到后,使用自己的密钥,解密第二段数据,得到client/TGS session key和时间戳,如果时间戳和本地时间在两分钟以内,验证成功。

  • 客户端将client/TGS session key和TGT保存在本地(credentials cache),用于后面和TGS会话

 

2.3、 服务请求

  • 当用户需要访问一个network service时,客户端会利用TGS发送请求:1,TGT+服务ID;2,使用client/TGS session key加密的:用户信息+时间戳。

  • TGS收到请求后,先使用自己的密钥,解密TGT,得到client/TGS session key,解密得到用户信息和时间戳,验证通过。

  • TGS生成client/service session key,一式两份,一份使用用户的密钥加密,另一份将连同用户信息打包(ticket),并用服务的密钥加密,最后,将两个加密包全部都发送给用户

  • 用户收到后,先用自己的密钥解密,得到client/service session key

  • 用户向要访问的服务发送请求:使用client/service session key加密的当前用户信息+时间戳(authenticator)+使用NFS服务的密钥加密的ticket

  • 服务收到请求后,使用自己的密钥解密ticket,得到client/service session-key和用户信息,然后使用client/service session key解密authenticator(能解开,说明用户是经过KDC认证的),得到用户信息和时间戳,如果时间戳和服务器的时候相差在两分钟以内,并且用户信息一致,认证成功。

  • 客户端和服务之间使用client/service session key加解密传输

 

3、 安装kerberos

#安装kerberos

yum install -y krb5-server

 

4、 配置

4.1、 配置文件

vi /etc/krb5.conf

[logging]

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

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

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

 

[libdefaults]

dns_lookup_realm = false

ticket_lifetime = 24h

renew_lifetime = 7d

forwardable = true

rdns = false

default_realm = EXAMPLE.COM

default_ccache_name = KEYRING:persistent:%{uid}

 

[realms]

EXAMPLE.COM = {

kdc = kerberos.example.com

admin_server = kerberos.example.com

}

#注意,要能解析

 

[domain_realm]

.example.com = EXAMPLE.COM

example.com = EXAMPLE.COM

 

注意:不管服务端,还是客户端,都会用到/etc/krb5.conf

 

4.2、 补充文件

通常仅在KDC上使用的程序,如:krb5kdc、kadmin、kdb5_util,使用/var/kerberos/krb5kdc/kdc.conf文件补充krb5.conf,将两者合并到一个配置中。此处记录的关系也可以在krb5.conf中指定。

 

#没有特殊需求,只需要将realm改下即可

vi /var/kerberos/krb5kdc/kdc.conf

 

4.3、 配置访问控制

vi /var/kerberos/krb5kdc/kadm5.acl

#如果是管理员,可以做任何操作

*/admin@EXAMPLE.COM     *

 

访问控制列表控制符:

#同一个字母,小写表示允许,大写表示拒绝

  • a/A 允许/拒绝添加principals

  • d/D 允许/拒绝删除principals

  • m/M 允许/拒绝修改principals

  • c/C 允许/拒绝更改principals的密码

  • i/I 允许/拒绝对数据库查询操作

  • l/L 允许/拒绝列出principals

  • *    所有

 

例:

#root这个管理员,不能对其它管理员的信息进行操作

vi /var/kerberos/krb5kdc/kadm5.acl

root/admin@EXAMPLE.COM ADMCIL */admin@EXAMPLE.COM

 

5、 初始化kerberos

#创建kerberos的数据库,并设置一个master key,用来加密数据库。

#-s,表示将master key保存为文件,不用每次启服务时,需要输入密码

kdb5_util create -s -r EXAMPLE.COM

 

systemctl start kadmin

systemctl start krb5kdc

systemctl enable krb5kdc

systemctl enable kadmin

 

6、 创建principal

6.1、 管理工具

  • kadmin.local,服务器本地管理用

  • kadmin,远程管理用

 

管理principals子命令:

  • addprinc,增加

  • delprinc,删除

  • modprinc,修改

  • cpw,修改密码

 

定义密码策略:

  • addpol

  • delpol

  • modpol

  • getpol

  • listpols

 

导出keytab文件:

  • ktadd

 

6.2、 创建principal

kadmin.local

#查看帮助

?

 

#创建一个用户root,角色是admin,作为kerberos数据库管理员

#并创建密码

addprinc root/admin

 

#添加普通用户,并设置密码

addprinc demouser1

addprinc demouser2

 

#修改用户密码

cpw demouser1

 

#创建主机,即kerberos客户端主机

#-randkey,随机创建密码,因为主机的密码,我们不需要记忆

addprinc -randkey host/node1.example.com

addprinc -randkey host/node2.example.com

 

#创建一个service叫nfs,在node1.example.com这台主机上

addprinc -randkey nfs/node1.example.com

 

#查看

listprincs

 

6.3、 导出keytab

kadmin.local

#导出用户keytab

ktadd -k /tmp/demouser1.keytab demouser1

 

#导出主机keytab

ktadd -k /tmp/node1.keytab host/node1.example.com

ktadd -k /tmp/node2.keytab host/node2.example.com

 

#列出客户端

listprincs

 

#退出

quit

 

6.4、 拷贝给客户端

#拷贝krb5配置文件和host的keytab到客户端主机

scp /etc/krb5.conf root@node1:/etc/

scp /tmp/node1.keytab root@node1:/etc/krb5.keytab

 

注意:在客户端,keytab必须为:/etc/krb5.keytab

 

7、 客户端配置

kerberos有两种认证方式:

  • 直接通过kinit命令认证

  • 通过keytab文件认证

 

为连接到ldap和kerberos服务器,至少需要更新以下文件:

  • /etc/ldap.conf,关于ldap服务器及其设置的信息,注意和ldapadd等工具的配置文件不在同一路径

  • /etc/krb5.conf,关于kerberos基础架构的信息

  • /etc/sssd/sssd.conf,配置系统安全服务

  • /etc/nsswitch.conf,为系统指明应使用哪些用户信息和身份验证服务

  • /etc/pam.d/*,配置pam应如何处理各种服务的身份验证

  • /etc/openldap/cacerts,指定ca证书

 

这么多配置文件,很容易出错,所以建议使用工具,进行配置:

  • authconfig,命令行

  • authconfig-tui,文本图形

  • authconfig-gtk,图形

 

7.1、 装包

#pam_krb5,默认,kerberos会绕过pam,安装此包,就是让使用pam的应用程序可以使用kerberos进行身份验证

#krb5-workstation,kerberos的客户端小工具,可不装

#sssd,安全服务守护进程,负责检索和缓存用户信息和身份验证信息

yum install -y pam_krb5 krb5-workstation sssd

 

7.2、 配置文件(补充)

上面步骤中,已经将配置文件拷贝过来了

 

#因为配置文件里有includedir /etc/krb5.conf.d/,所以必须创建这个目录,否则下面的命令失败

#也可以将配置文件中的inludedir删掉

mkdir /etc/krb5.conf.d/

 

7.3、 导入keytab(补充)

上面步骤,已经将keytab拷贝过来了,这里仅作补充说明,不需要做

 

方法一:在服务端导出key,然后scp过来

 

方法二:使用kadmin工具远程连接到KDC,在客户端本地直接导出

kadmin

#添加票据到/etc/krb5.keytab文件

ktadd host/node1.example.com

 

#从文件删除票据

ktremove host/node1.example.com

 

方法三:从一个已存在的keytab文件读取

ktutil

#读取keytab

rkt /tmp/node1.keytab

 

#写到krb5.keytab中

wkt /etc/krb5.keytab

list

quit

 

7.4、 配置客户端

注意:配置之前,先确认上面步骤中,从服务端拷贝过来的两个文件:/etc/krb5.conf和/etc/krb5.keytab

 

authconfig-tui

3.png

4.png

5.png

 

7.5、 验证

客户端认证方式有两种:密码、keytab

 

密码方式:

#密码验证

kinit demouser1

 

#修改密码

kpassword demouser1

 

#查看

klist

 

#更新

kinit -R

 

#删除

kdestroy

 

keytab方式:

#在KDC,导出用户的keytab:

admin.local

ktadd -k /tmp/demouser1.keytab demouser1

 

#拷贝到客户端

scp /tmp/deouser1.keytab root@node1:/root/

 

#使用keytab验证

kinit -k -t user1.keytab user1

 

#查看keytab中的principal

#如果不指定keytab,默认查看/etc/krb5.keytab

klist -k demouser1.keytab

 

8、 配置ssh

GSSAPI:Generic Security Services Application Program Interface,GSSAPI 本身是一套 API,由 IETF 标准化。

其最主要也是著名的实现是基于Kerberos的。一般说到GSSAPI都暗指Kerberos实现。

GSSAPI是一套通用网络安全系统接口。该接口是对各种不同的客户端服务器安全机制的封装,以消除安全接口的不同,降低编程难度。

 

vi /etc/ssh/ssh_config

GSSAPIAuthentication yes

GSSAPIDelegateCredentials yes

 

vi /etc/ssh/sshd_config

GSSAPIAuthentication yes

GSSAPICleanupCredentials yes

 

systemctl reload sshd

 

9、 测试

#通过认证,获取票据

ssh demouser1@node1

 

#列出票据

klist

 

#修改密码

#使用passwd命令,pam会将请求转发给kdc

passwd

 

10、 配置nfs secure

10.1、 KDC

#创建principal

kadmin.local

#创建服务器和客户端的主机principal

addprinc -randkey host/server.example.com

addprinc -randkey host/client.example.com

 

#给nfs服务端和客户端创建principal

addprinc -randkey nfs/server.example.com

addprinc -randkey nfs/client.example.com

 

10.2、 nfs-server

yum install krb5-workstation

yum install nfs-utils

mkdir -p /protected/secret

 

vi /etc/exports

/protected 192.168.3.0/24(rw,sec=krb5p,no_root_squash)

 

vi /etc/sysconfig/nfs

RPCNFSDARGS="-V 4.2"

 

systemctl start nfs-server

systemctl enable nfs-server

 

kadmin

#默认会将两个principal,以追加的方式保存到本地的/etc/krb5.keytab

ktadd host/server.example.com

ktadd nfs/server.example.com

 

#从kerberos服务器拷贝配置文件

scp kerberos.example.com:/etc/krb5.conf /etc/

 

systemctl start nfs-secure-server

 

chown demouser1.demouser1 /protected/secret

 

10.3、 客户端

scp kerberos.example.com:/etc/krb5.conf /etc/

 

kadmin

ktadd host/client.example.com

ktadd nfs/client.example.com

 

systemctl restart nfs-secure

mkdir /mnt/nfssecure

showmout -e 192.168.3.31

 

mount -o sec=krb5p,v4.2 192.168.3.31:/protected /mnt/nfssecure/