Kerberos
1.简介
Kerberos简单来说就是一个用于安全认证第三方协议,它采用了传统的共享密钥的方式,实现了在网络环境不一定保证安全的环境下,client和server之间的通信,适用于client/server模型,由MIT开发和实现。
Kerberos的神秘之处在于,它并不要求通信双方所在的网络环境是安全的,即使通信过程中数据被截取或者篡改依然不会影响它的正常工作,它提供的认证是双向的,不仅能保证Server不被错误的Client使用,同时也能保证Client不使用错误的Server。同时Kerberos又严重依赖于时间,时间戳也是Kerberos用来保证通信安全的重要手段,这个一般通过通信双方同时访问同一个时间服务器来实现。Kerberos也能达到单点登录的效果,即当Client通过了Kerberos server的认证后,便可以访问多个Real Server。
2.原理浅析
在实际的应有场景中通常有三个角色,即需要访问服务的Client,提供服务的Application Server,以及提供安全认证的第三方Kerberos服务器KDC(Key Distribution Center)。它们彼此之间的认证、通信的数据流如下图所示。
仔细研究过上图之后,你可能会发现你能看明白的东西实在有限,而想要把Kerberos原理弄明白实在不是一件容易的事,不过可以庆幸的是Kerberos是用传统的共享密钥的方式实现的,这个概念对大家来说并不陌生,同时Kerberos认证还加了时间戳,有效时间,信息对比等伎俩,所以花时间细细读下来你依然能看明白,如果此时你就迫不及待的想研究的话你可以戳这里,这里,或者这里。现在,我们来讨论下Kerberos的认证的一个部分,我认为只要这个部分理解了,其他的都可以递推出来。如下图:
Client master key: KDC中存储的Client的密钥
Server master key: KDC中存储的Server的密钥
Sclient-Server:Client与Server之间的会话密钥
Client Info:记录了Client本身的Ip等基本信息
首先 Client询问KDC,我想访问某个Server,然后KDC会将会话密钥Sclient-Server用Client master key加密后传送给Client;与此同时,KDC也会将会话密钥Sclient-Server连同Client的基本信息打包用Server master key加密也发给Client,并经Client转发给Server,至此Client与KDC的交互完成。
然后,Client用自己的master key解密KDC传过来的第一个包,解密后获得会话密钥Sclient-Server,并用这个密钥加密自己的的信息和时间戳打包后传送给Server,此时Client开始和Server交互,如下图:
Server会收到两个数据包,一个用会话密钥加密,一个用自己的master key加密,Server先用自己的master key解密获取会话密钥和一份关于Client的信息,然后Server拿到解密后获取到的会话密钥再解开另外一个数据包,获得另一份关于Client的信息和时间戳,至此Client和Server的交互完成。
下面我们解释下这样传输数据的原因,为什么传递这些数据
1,上面有个数据包是KDC经Client转发给Server的,为什么不直接发给Server?
因为Server可能给多个Client提供服务,这样Server需要维护一个Client和会话密钥的对应表,这对Server是一个负担。
此外,因为网络传输的不确定性可能Client和Server并不能都及时获取到会话密钥,假如有一方获取失败,那么Client就不能访问Server
2,为什么要发两份关于Client的信息给Server?
通过这两份数据的对比,Server就能判断出是不是对的Client在访问服务。
3,Client是如何判断自己在访问对的Server呢?
因为Client给Server的一个数据包是用Server的master key来加密的所以只有对的Server才能解密。
4,为什么要用会话密钥
通信方的master key是长期有效的,如果在网络上传输,一旦被截取,理论上来说只要有足够的时间是可以破解的,所以我们才用临时的会话密钥来通信,一段时间后会话密钥会过期,同时时间戳也防止了,恶意用户重复使用同一个数据包。
5,为什么要用时间戳?
如果Client向Server传送的数据包被其他的Client截取,然后自己拿来向Server请求服务这,这样就会出问题,那么引入时间戳后,Server收到请求后将从解密后的数据包中获得的时间戳和当前时间对比,一旦超过一定范围将直接拒绝请求;所以,正如前面所说,Kerberos高度依赖时间同步服务。
事实上这个并不是Kerberos认证的整个过程,KDC实际上由AS和TGS两部分组成,你可以将TGS视作一个Server,然后还沿用上面所说的步骤来分析,这样就可以基本上梳理出Client访问Server的一个完整的过程了。
3.SPNEGO 协议和 Kerberos 认证
3.1.Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO)
即简单且受保护的GSSAPI协商机制,是客户端-服务器软件用于协商安全技术选择的GSSAPI过程。当客户端想要向服务器认证身份,但是客户端和服务器都不知道对方支持什么认证协议。这时需要使用SPNEGO来选择双方都支持的GSSAPI ,以便接下来的认证过程以及后续安全信息传输的正常进行
Spnego模式是一种由微软提出的使用GSS-API接口的认证模式,它扩展了Kerberos协议,在了解Spnego协议之前必须先了解Kerberos协议,Kerberos协议主要解决身份认证及通信密钥协商问题,它大致的工作流程如下:
①客户端根据自己用户名向密钥分发中心KDC的身份认证服务AS请求TGS票证。
②AS生成一个TGS票证、查询对应用户的密码,然后通过用户密码将TGS票证加密,响应给客户端。
③客户端通过用户密码解密TGS票证,如果密码正确就能获取到TGS票证,然后用TGS票证去票证授予服务TGS请求服务票证。
④TGS将服务票证响应给客户端。
⑤客户端使用服务票证去访问某服务,服务验证服务票据是否合法。
⑥验证通过,开始通信。
在了解了Kerberos协议后,我们再来看看Spnego的认证过程是怎样的。由于spnego扩展自kerberos协议,认证的核心流程一样,只是在浏览器与web服务器之间的http通信过程中嵌入认证流程。如下图:
在所有步骤之前,首先当前客户使用的PC必须首先登录到AD域里面,然后再保证所使用的浏览器必须支持spnego
前提条件:1. 首先客户端机器要登录到Window域中。2. 使用的Browser要包含spnego机制
①客户端浏览器向web服务器发送http请求。
②服务器返回401状态码,响应头部加上 WWW-Authenticate:Negotiate。
③用户通过浏览器输入用户名向AS请求TGS票证。
④AS生成TGS票证,然后查询用户密码并用此密码加密TGS票证,返回浏览器。
⑤浏览器使用用户密码解密出TGS票证,并向TGS服务发起请求。
⑥TGS服务生成服务票证响应给浏览器。
⑦浏览器将服务票证封装到SPNEGO token中,并发送给web服务器。
⑧服务器解密出用户名及服务票证,将票证发往TGS服务验证。
⑨通过验证,开始通信。
3.2.Spnego认证有两种实现方式
-
使用username和password
-
使用kerberos
3.3.单个 Kerberos 域中的 SPNEGO Web 认证
SPNEGO Web 认证在单个 Kerberos 域中受支持。下图中显示了提问应答握手过程:
图 1. 单个 Kerberos 域中的 SPNEGO Web 认**证
在上图中,发生了下列事件:
-
首先,用户从工作站登录 Microsoft 域控制器 MYDOMAIN.EXAMPLE.COM。
-
然后,用户尝试访问 Web 应用程序。用户使用客户机浏览器请求受保护的 Web 资源,这会向 Liberty 服务器发送 HTTP GET 请求。
-
Liberty 服务器中的 SPNEGO 认证使用包含 Authenticate: Negotiate 状态的 HTTP 401 提问头应答客户机浏览器。
-
客户机浏览器会识别协商头,因为客户机浏览器配置为支持集成 Windows 认证。客户机针对主机名解析所请求的 URL。客户机使用主机名构成目标 Kerberos 服务主体名称 (SPN) HTTP/myLibertyMachine.example.com,以请求来自 Microsoft Kerberos KDC (TGS_REQ) 中的 Kerberos 凭单授予服务 (TGS) 的 Kerberos 服务凭单。然后,TGS 对客户机发出 Kerberos 服务凭单 (TGS_REP)。Kerberos 服务凭单(SPNEGO 令牌)对该服务(Liberty 服务器)证明用户的身份和许可权。
-
然后,通过使用执行先前步骤时在请求 HTTP 标头中获取的 SPNEGO 令牌,客户机浏览器可回应 Liberty 服务器的认证:协商提问。
-
Liberty 服务器中的 SPNEGO 认证查看带有 SPNEGO 令牌的 HTTP 标头,验证 SPNEGO 令牌,并获取用户的身份(主体)。
-
Liberty 服务器获取用户身份后,它会在其用户注册表中验证该用户并执行授权检查。
-
如果授予访问权,那么 Liberty 服务器会发送带有 HTTP 200 的响应。Liberty 服务器还会在响应中包含 LTPA cookie。此 LTPA cookie 用于后续请求。
*注:*支持 SPNEGO 的其他客户机(例如,Web Service、.NET 和 J2EE)不必遵循前面所显示的提问应答握手过程。这些客户机可获取用于目标服务器的授予凭单的凭单 (TGT) 和 Kerberos 服务凭单,创建 SPNEGO 令牌,将其插入到 HTTP 标头中,然后遵循用于创建 HTTP 请求的正常过程。
3.4.可信 Kerberos 域中的 SPNEGO Web 认证
SPNEGO Web 认证在可信 Kerberos 域中也受支持。下图中显示了提问应答握手过程:
图 2. 可信 Kerberos 域中的 SPNEGO Web 认**证
在上图中,发生了下列事件:
-
用户登录 Microsoft 域控制器 TRUSTEDREALM.ACME.COM。
-
在客户机浏览器中,用户发出针对在原始 Microsoft 域控制器 MYDOMAIN.EXAMPLE.COM 中的 Liberty 服务器上托管的受保护 Web 资源的请求。
-
Liberty 服务器使用包含 Authenticate: Negotiate 状态的 HTTP 401 提问头应答客户机浏览器。
-
客户机浏览器配置为支持集成 Windows 认证。客户机浏览器通过使用托管 Liberty 服务器应用程序的工作站的主机名来解析 URL。客户机浏览器使用主机名作为属性,以请求来自域TRUSTEDREALM.ACME.COM 的用于 MYDOMAIN.EXAMPLE.COM 的 Kerberos 跨域凭单 (TGS_REQ)。
-
客户机浏览器使用步骤 4 中的 Kerberos 跨域凭单请求来自域 MYDOMAIN.EXAMPLE.COM 的 Kerberos 服务凭单。Kerberos 服务凭单(SPNEGO 令牌)对该服务(Liberty 服务器)证明用户的身份和许可权。
-
然后,通过使用执行先前步骤时在请求 HTTP 标头中获取的 SPNEGO 令牌,客户机浏览器可回应 Liberty 服务器的认证:协商提问。
-
Liberty 服务器接收请求并检查带有 SPNEGO 令牌的 HTTP 标头。然后,它会抽取 Kerberos 服务凭单,验证该凭单,并获取用户的身份(主体)。
-
Liberty 服务器获取用户身份后,它会在其用户注册表中验证该用户并执行授权检查。
-
如果授予访问权,那么 Liberty 服务器会发送带有 HTTP 200 的响应。Liberty 服务器还会在响应中包含 LTPA cookie。此 LTPA cookie 用于后续请求。
*注:*不需要对 Liberty 服务器进行任何修改就可支持更多可信领域。SPNEGO 只需要必需 Active Directory 域之间的信任关系就可使用可信域。
在可信 Kerberos 域环境中,应注意必须在每个 Kerberos KDC 上完成 Kerberos 可信域设置。请参阅 Kerberos Administrator and User's Guide,以获取有关如何设置 Kerberos 可信域的更多信息。
4.安装配置
名称 | 服务器 | 版本 | IP |
---|---|---|---|
KDC服务端 | centos7 | 1.15.1-50.el7 | 192.168.174.132 |
Kerberos客户端 | centos7 | 1.15.1-50.el7 | 192.168.174.133 |
Kerberos Windows客户端 | window10 | kfw-4.1-amd64.msi | 192.168.174.1 |
FireFox | window10 | 84.0.2 | 192.168.174.1 |
4.1.KDC服务端安装及配置
1.确保环境可用
确保所有的clients与servers之间的时间同步以及DNS正确解析
注:本文档使用IP地址注册的方式
2.安装KDC服务
yum -y install krb5-server krb5-libs krb5-auth-dialog krb5-workstation openldap-clients
3.配置kdc.conf
默认放在 /var/kerberos/krb5kdc/kdc.conf。
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] EXAMPLE.COM = { #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal }
4.修改主配置/etc/krb5.conf
/etc/krb5.conf: 包含Kerberos的配置信息。例如,KDC的位置,Kerberos的admin的realms 等。需要所有使用的Kerberos的机器上的配置文件都同步,包括kerberos Server 和Kerberos Client 机器上。 配置示例:
# Configuration snippets may be placed in this directory as well includedir /etc/krb5.conf.d/ [logging] debug = true 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 pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt default_realm = EXAMPLE.COM default_ccache_name = KEYRING:persistent:%{uid} [realms] EXAMPLE.COM = { kdc = 192.168.174.132 admin_server = 192.168.174.132 default_domain = example.com } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM
5.创建/初始化Kerberos database
[root@sunjing123 ~]# /usr/sbin/kdb5_util create -s -r EXAMPLE.COM
当Kerberos database创建好后,可以看到目录 /var/kerberos/krb5kdc 下生成了几个文件
-rw-------. 1 root root 22 9月 30 21:21 kadm5.acl -rw-------. 1 root root 640 1月 7 17:43 kdc.conf -rw-------. 1 root root 20480 1月 8 21:59 principal -rw-------. 1 root root 8192 12月 31 13:45 principal.kadm5 -rw-------. 1 root root 0 12月 31 13:45 principal.kadm5.lock -rw-------. 1 root root 0 1月 8 21:59 principal.ok
6.添加database administrator
我们需要为Kerberos database添加administrative principals (即能够管理database的principals) —— 至少要添加1个principal来使得Kerberos的管理进程kadmind能够在网络上与程序kadmin进行通讯。 在maste KDC(vecs02583)上执行:
/usr/sbin/kadmin.local -q "addprinc admin/admin"
并为其设置密码.
kadmin.local 可以直接运行在master KDC上,而不需要首先通过Kerberos的认证,实际上它只需要对本 地文件的读写权限。
7.为database administrator设置ACL权限
在KDC上我们需要编辑acl文件来设置权限,该acl文件的默认路径是 /var/kerberos/krb5kdc/kadm5.acl(也可以在文件kdc.conf中修改)。Kerberos的kadmind daemon会使用该文件来管理对Kerberos database的访问权限。对于那些可能会对pincipal产生影响的操作,acl文件也能控制哪些principal能操作哪些其他pricipals。
我们现在为administrator设置权限:将文件/var/kerberos/krb5kdc/kadm5.acl的内容编辑为
/admin@EXAMPLE.COM 代表名称匹配/admin@EXAMPLE.COM都认为是admin,权限是* 。代表全部权限。
*/admin@EXAMPLE.COM *
8.在master KDC启动Kerberos daemons
[root@sunjing123 /]# service krb5kdc start [root@sunjing123 /]# service kadmin start
现在KDC已经在工作了。这两个daemons将会在后台运行,可以查看它们的日志文件(/var/log/krb5kdc.log 和 /var/log/kadmind.log)。 可以通过命令kinit来检查这两个daemons是否正常工作。
9.验证
使用kinit命令认证,输入正确的密码,显示如下,则表示成功
[root@sunjing132 /]# kinit admin/admin@EXAMPLE.COM Password for admin/admin@EXAMPLE.COM: [root@sunjing132 /]#
使用kadmin.local登录,输入listprincs,有正常的显示,表示服务器端安装成功。
[root@sunjing132 /]# kadmin.local Authenticating as principal admin/admin@EXAMPLE.COM with password. kadmin.local: listprincs K/M@EXAMPLE.COM admin/admin@EXAMPLE.COM kadmin/admin@EXAMPLE.COM kadmin.local:
4.2.Kerberos客户端安装及配置
1.安装kerberos客户端
yum install krb5-workstation krb5-libs krb5-auth-dialog
2.配置krb5.conf 配置这些主机上的/etc/krb5.conf,这个文件的内容与KDC中的文件保持一致即可。
# Configuration snippets may be placed in this directory as well includedir /etc/krb5.conf.d/ [logging] debug = true 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 pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt default_realm = EXAMPLE.COM default_ccache_name = KEYRING:persistent:%{uid} [realms] EXAMPLE.COM = { kdc = 192.168.174.132 admin_server = 192.168.174.132 default_domain = example.com } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM
3.验证
使用Kinit认证用户,输入正确的密码,显示如下,则表示成功
[root@sunjing133 ~]# kinit admin/admin@EXAMPLE.COM Password for admin/admin@EXAMPLE.COM: [root@sunjing133 ~]#
使用klist查询登录状态
[root@sunjing133 ~]# klist Ticket cache: KEYRING:persistent:0:0 Default principal: admin/admin@EXAMPLE.COM Valid starting Expires Service principal 2021-01-11T10:27:16 2021-01-12T10:27:16 krbtgt/EXAMPLE.COM@EXAMPLE.COM
4.3.Kerberos window客户端安装及配置
1.下载windows安装程序,直接默认安装
kfw-4.1-amd64.msi
2.配置krb5.conf,在windows下面文件名叫krb.ini
#C:\ProgramData\MIT\Kerberos5 # Configuration snippets may be placed in this directory as well #includedir /etc/krb5.conf.d/ [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 clockskew = 600 # pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt default_realm = EXAMPLE.COM # default_ccache_name = KEYRING:persistent:%{uid} [realms] EXAMPLE.COM = { kdc = 192.168.174.132 admin_server = 192.168.174.132 default_domain = example.com } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM
注:如果配置文件查找不正常,可以同步替换c:\winnt\或c:\windows\下的krb5.ini
3.验证
启动Kerberos的window客户端,点击Get Ticket,输入用户和密码,点击OK,无任何报错,且列表显示用户信息,则表示成功。
4.浏览器使用Kerberos (SPNEGO)
输入about.config
network.negotiate-auth.trusted-uris: http://192.168.174.133:5601
network.auth.use-sspi : false
重启firefox
5.注意点
设置环境变量:KRB5_TRACE = G:\elk\logs\trace_log.log 可以查看客户端kerberos请求相关日志
4.4.管理员命令操作
在服务端登录,使用kadmin.local
[root@sunjing132 /]# kadmin.local Authenticating as principal admin/admin@EXAMPLE.COM with password. kadmin.local:
1.增删改查账户
addprinc,delprinc,modprinc,listprincs命令。使用?可以列出所有的命令。
kadmin.local: addprinc test kadmin.local: delprinc test kadmin.local: listprincs
2.生成keystore
#-norandkey 密码不随机 ktadd -k /var/kerberos/sunjing/es.keytab -norandkey admin/admin@EXAMPLE.COM
4.5.用户命令操作
1.查看当前的认证用户
[root@sunjing133 ~]# klist Ticket cache: KEYRING:persistent:0:0 Default principal: admin/admin@EXAMPLE.COM Valid starting Expires Service principal 2021-01-11T10:27:16 2021-01-12T10:27:16 krbtgt/EXAMPLE.COM@EXAMPLE.COM [root@sunjing133 ~]#
2.认证用户
[root@sunjing133 ~]# kinit admin/admin@EXAMPLE.COM Password for admin/admin@EXAMPLE.COM: [root@sunjing133 ~]#
3.删除当前的认证的缓存
[root@sunjing133 ~]# kdestroy [root@sunjing133 ~]# klist klist: Credentials cache keyring 'persistent:0:0' not found
4.查看keytab
[root@sunjing133 ~]# klist -e -k -t /etc/elasticsearch/es24.keytab Keytab name: FILE:/etc/elasticsearch/es24.keytab KVNO Timestamp Principal ---- ------------------- ------------------------------------------------------ 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (aes256-cts-hmac-sha1-96) 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (aes128-cts-hmac-sha1-96) 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (des3-cbc-sha1) 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (arcfour-hmac) 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (camellia256-cts-cmac) 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (camellia128-cts-cmac) 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (des-hmac-sha1) 1 2021-01-07T19:57:07 HTTP/192.168.174.133@EXAMPLE.COM (des-cbc-md5)
4.6.参考资料
Windows下配置浏览器使用Kerberos (SPNEGO)_taisenki的博客-CSDN博客_chrome kerberos