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
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/