16.9.Kerberos
Kerberos 是一种网络身份验证协议,最初由麻省理工学院(MIT)创建,旨在通过潜在的敌对网络安全地提供身份验证。Kerberos 协议使用强加密技术,使客户端和服务器能够证明其身份,而无需通过网络发送任何未加密的秘密。Kerberos 可以被描述为一种身份验证代理系统,也可以视为一种可信的第三方认证系统。在用户通过 Kerberos 进行身份验证后,他们的通信可以被加密,以确保隐私和数据完整性。
Kerberos 的唯一功能是提供对网络上用户和服务器的安全身份验证。它不提供授权或审计功能。建议将 Kerberos 与其他提供授权和审计服务的安全方法一起使用。
该协议的当前版本是第 5 版,描述于 RFC 4120 中。该协议有多个免费的实现,涵盖了广泛的操作系统。MIT 继续开发其 Kerberos 软件包。在美国,Kerberos 被作为加密产品广泛使用,并且历史上一直受到美国出口管制。在 FreeBSD 中,MITKerberos 作为 security/krb5 软件软件包和 Ports 可用。Heimdal Kerberos 实现是为了避免出口管制而在美国之外明确开发的。Heimdal Kerberos 发行版已包含在 FreeBSD 的基本安装中,另一个具有更多可配置选项的发行版可作为 security/heimdal 在 Ports 中使用。
在 Kerberos 中,用户和服务被称为“主体”(principals),它们包含在一个名为“领域”(realm)的管理分组中。一个典型的用户主体形式为 user@REALM
(领域通常使用大写字母)。
本节提供了如何使用 FreeBSD 中包含的 Heimdal 发行版设置 Kerberos 的指南。
为了演示 Kerberos 安装,命名空间将如下所示:
DNS 域(区域)将为
example.org
。Kerberos 领域将为
EXAMPLE.ORG
。
注意
在设置 Kerberos 时使用真实的域名,即使它仅在内部运行。这可以避免 DNS 问题并确保与其他 Kerberos 领域的互操作性
16.9.1. 设置 Heimdal KDC
密钥分发中心(KDC)是 Kerberos 提供的集中式身份验证服务,是系统中的“可信第三方”。它是发放 Kerberos 票证的计算机,客户端用它来进行服务器身份验证。由于 KDC 被所有其他计算机视为可信,因此它具有更高的安全性。应限制对 KDC 的直接访问。
虽然运行 KDC 需要的计算资源较少,但为了安全原因,建议使用仅作为 KDC 运行的专用机器。
首先,按如下方式安装 security/heimdal 软件包:
# pkg install heimdal
接下来,使用 sysrc
更新 /etc/rc.conf:
# sysrc kdc_enable=yes
# sysrc kadmind_enable=yes
接下来,按如下方式编辑 /etc/krb5.conf:
[libdefaults]
default_realm = EXAMPLE.ORG
[realms]
EXAMPLE.ORG = {
kdc = kerberos.example.org
admin_server = kerberos.example.org
}
[domain_realm]
.example.org = EXAMPLE.ORG
在这个例子中,KDC 将使用完全限定的主机名 kerberos.example.org
。KDC 的主机名必须在 DNS 中是可解析的。
Kerberos 还可以使用 DNS 来定位 KDC,而不是在 /etc/krb5.conf 中使用 [realms]
部分。对于拥有自己 DNS 服务器的大型组织,上面的示例可以简化为:
[libdefaults]
default_realm = EXAMPLE.ORG
[domain_realm]
.example.org = EXAMPLE.ORG
并在 example.org
区域文件中包含以下行:
_kerberos._udp IN SRV 01 00 88 kerberos.example.org.
_kerberos._tcp IN SRV 01 00 88 kerberos.example.org.
_kpasswd._udp IN SRV 01 00 464 kerberos.example.org.
_kerberos-adm._tcp IN SRV 01 00 749 kerberos.example.org.
_kerberos IN TXT EXAMPLE.ORG
注意
为了让客户端能够找到 Kerberos 服务,它们 必须 拥有完全配置的 /etc/krb5.conf,或者至少配置了 /etc/krb5.conf 和正确配置的 DNS 服务器。
接下来,创建包含所有主体(用户和主机)密钥的 Kerberos 数据库,这些密钥使用主密码进行加密。无需记住此密码,因为它将存储在 /var/heimdal/m-key 中;为了这个目的,使用一个 45 字符的随机密码是合理的。要创建主密钥,请运行 kstash
并输入密码:
# kstash
输出应类似于以下内容:
Master key: xxxxxxxxxxxxxxxxxxxxxxx
Verifying password - Master key: xxxxxxxxxxxxxxxxxxxxxxx
创建主密钥后,应初始化数据库。Kerberos 管理工具 kadmin(8) 可以在 KDC 上直接对数据库操作,而无需使用 kadmind(8) 网络服务,使用 kadmin -l
运行。这解决了在数据库创建之前尝试连接到数据库的问题。在 kadmin
提示符下,使用 init
创建领域的初始数据库:
# kadmin -l
kadmin> init EXAMPLE.ORG
Realm max ticket life [unlimited]:
最后,在 kadmin
中使用 add
创建第一个主体。暂时保留主体的默认选项,因为这些选项稍后可以通过 modify
修改。输入 ?
可以查看可用的选项。
kadmin> add tillman
输出应类似于以下内容:
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
Password: xxxxxxxx
Verifying password - Password: xxxxxxxx
接下来,通过运行以下命令启动 KDC 服务:
# service kdc start
# service kadmind start
虽然此时不会有 Kerberos 守护进程在运行,但可以通过获取刚刚创建的主体的票证来确认 KDC 是否正常工作:
% kinit tillman
输出应类似于以下内容:
tillman@EXAMPLE.ORG's Password:
使用 klist
确认是否成功获取票证:
% klist
输出应类似于以下内容:
Credentials cache: FILE:/tmp/krb5cc_1001
Principal: tillman@EXAMPLE.ORG
Issued Expires Principal
Aug 27 15:37:58 2013 Aug 28 01:37:58 2013 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
测试完成后,可以销毁临时票证:
% kdestroy
16.9.2. 配置服务器以使用 Kerberos
配置服务器以使用 Kerberos 身份验证的第一步是确保 /etc/krb5.conf 文件正确配置。可以直接使用 KDC 中的版本,也可以在新系统上重新生成该文件。
接下来,在服务器上创建 /etc/krb5.keytab 文件。这是将服务“Kerberize”的关键步骤——它对应于生成一个在服务与 KDC 之间共享的密钥。该密钥是加密密钥,存储在一个“keytab”文件中。keytab 包含服务器的主机密钥,允许服务器和 KDC 验证彼此的身份。必须以安全的方式将其传输到服务器,因为如果密钥公开,服务器的安全性将被破坏。通常,keytab 是在管理员的受信机器上使用 kadmin
生成的,然后通过安全的方式传输到服务器,例如使用 scp(1);如果与所需的安全策略一致,也可以直接在服务器上创建。非常重要的是,必须以安全的方式将 keytab 传输到服务器:如果密钥被其他方知道,该方可以冒充任何用户访问服务器!直接在服务器上使用 kadmin
很方便,因为 KDC 数据库中的主机主体条目也是通过 kadmin
创建的。
当然,kadmin
是一个 Kerberos 服务;需要 Kerberos 票证才能对网络服务进行身份验证,但为了确保运行 kadmin
的用户确实在场(并且他们的会话没有被劫持),kadmin
会提示输入密码以获取新票证。对 kadmin
服务进行身份验证的主体必须被允许使用 kadmin
接口,这在 /var/heimdal/kadmind.acl 中进行了指定。有关设计访问控制列表的详细信息,请参阅 info heimdal
中的“远程管理”部分。管理员也可以通过本地控制台或 ssh(1) 安全地连接到 KDC,并使用 kadmin -l
本地执行管理操作。
安装 /etc/krb5.conf 后,使用 add --random-key
在 kadmin
中添加服务器的主机主体到数据库,但这不会将主机主体密钥提取到 keytab 中。要生成 keytab,可以使用 ext
将服务器的主机主体密钥提取到其自己的 keytab 中:
# kadmin
输出应类似于以下内容:
kadmin> add --random-key host/myserver.example.org
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> ext_keytab host/myserver.example.org
kadmin> exit
请注意,ext_keytab
默认将提取的密钥存储在 /etc/krb5.keytab 中。当在正在进行 Kerberize 操作的服务器上运行时,这样做是可以的,但如果在其他地方提取 keytab,则应使用 --keytab <path/to/file>
参数:
# kadmin
输出应类似于以下内容:
kadmin> ext_keytab --keytab=/tmp/example.keytab host/myserver.example.org
kadmin> exit
然后,可以通过 scp(1) 或可移动媒体将 keytab 安全地复制到服务器。务必指定一个非默认的 keytab 名称,以避免将不必要的密钥插入到系统的 keytab 中。
此时,服务器可以使用其共享密钥(存储在 krb5.keytab 中)读取来自 KDC 的加密消息。它现在准备启用使用 Kerberos 的服务。最常见的此类服务之一是 sshd(8),它通过 GSS-API 支持 Kerberos。在 /etc/ssh/sshd_config 中,添加以下行:
GSSAPIAuthentication yes
更改此配置后,必须重启 sshd(8) 以使新配置生效:service sshd restart
。
16.9.3. 配置客户端以使用 Kerberos
与服务器一样,客户端也需要在 /etc/krb5.conf 中进行配置。可以将该文件复制到客户端(以安全方式)或根据需要重新输入。
通过使用 kinit
、klist
和 kdestroy
在客户端进行测试,以获取、显示并删除一个现有主体的票证。Kerberos 应用程序也应能够连接到启用 Kerberos 的服务器。如果这无法正常工作,但获取票证成功,则问题可能出在服务器,而非客户端或 KDC。对于 Kerberized 的 ssh(1),默认情况下 GSS-API 是禁用的,因此可以使用 ssh -o GSSAPIAuthentication=yes <hostname>
来进行测试。
在测试 Kerberized 应用程序时,可以尝试使用 tcpdump
等数据包嗅探工具,以确认没有敏感信息以明文形式传输。
各种 Kerberos 客户端应用程序可供使用。随着一个桥接机制的出现,使得使用 SASL 进行身份验证的应用程序也能使用 GSS-API 机制,许多客户端应用程序都可以使用 Kerberos 进行身份验证,从 Jabber 客户端到 IMAP 客户端。
在一个域内,用户的 Kerberos 主体通常会映射到本地用户账户。有时,需要允许没有匹配 Kerberos 主体的本地用户账户访问。例如,tillman@EXAMPLE.ORG
可能需要访问本地用户账户 webdevelopers
。其他主体也可能需要访问该本地账户。
.k5login 和 .k5users 文件可以放在用户的主目录中,用来解决这个问题。例如,如果以下的 .k5login 文件放在 webdevelopers
用户的主目录中,列出的两个主体将可以访问该账户,而无需共享密码:
tillman@example.org
jdoe@example.org
有关 .k5users 的更多信息,请参阅 ksu(1)。
16.9.4. MIT 和 Heimdal 的差异
MIT 和 Heimdal 实现之间的主要区别在于 kadmin
有一组不同的命令,并使用不同的协议。如果 KDC 是 MIT 版本的,则不能使用 Heimdal 版本的 kadmin
远程管理 KDC,反之亦然。
客户端应用程序在执行相同任务时,可能会使用略有不同的命令行选项。建议参考 http://web.mit.edu/Kerberos/www/ 中的说明。注意路径问题:MIT Port 默认安装到 /usr/local/,如果 PATH
列出系统目录在前,FreeBSD 系统应用程序将代替 MIT 版本运行。
当在 FreeBSD 上使用 MIT Kerberos 作为 KDC 时,请执行以下命令,将所需的配置添加到 /etc/rc.conf 中:
# sysrc kdc_program="/usr/local/sbin/krb5kdc"
# sysrc kadmind_program="/usr/local/sbin/kadmind"
# sysrc kdc_flags=""
# sysrc kdc_enable="YES"
# sysrc kadmind_enable="YES"
16.9.5. Kerberos 配置技巧、窍门与故障排除
在配置和故障排除 Kerberos 时,请牢记以下几点:
使用 Heimdal 或 MITKerberos 的 Port 时,确保
PATH
列表中的客户端应用程序版本优先于系统版本。如果领域中的所有计算机的时间设置不同步,身份验证可能会失败。“使用 NTP 进行时钟同步” 介绍了如何使用 NTP 同步时钟。
如果更改了主机名,则必须更改
host/
主体并更新 keytab。对于像 Apache 的 www/mod_auth_kerb 使用的HTTP/
主体等特殊 keytab 条目也适用此规则。领域中的所有主机必须能够在 DNS 中进行正向和反向解析,或者至少存在于 /etc/hosts 中。CNAME 记录可以使用,但 A 和 PTR 记录必须正确并已设置。无法解析主机时,错误信息并不直观:
Kerberos5 拒绝认证,因为读取请求失败:未找到密钥表条目
。一些作为客户端连接到 KDC 的操作系统未将
ksu
的权限设置为 setuidroot
。这意味着ksu
无法正常工作。这是权限问题,而不是 KDC 错误。使用 MITKerberos 时,要允许主体的票证生命周期超过默认的十小时生命周期,请在 kadmin(8) 提示符下使用
modify_principal
修改相关主体和krbtgt
主体的maxlife
。然后,主体可以使用kinit -l
请求具有更长生命周期的票证。在 KDC 上运行数据包嗅探器来辅助故障排除时,运行
kinit
从工作站启动,Ticket Granting Ticket (TGT) 会立即发送,甚至在输入密码之前。这是因为 Kerberos 服务器会自由地向任何未授权的请求发送 TGT。然而,每个 TGT 都会使用从用户密码派生的密钥加密。当用户输入密码时,密码并不会发送到 KDC,而是用于解密kinit
已经获取的 TGT。如果解密过程导致有效票证和有效时间戳,则说明用户拥有有效的 Kerberos 凭据。这些凭据包括用于建立与 Kerberos 服务器之间安全通信的会话密钥,以及实际的 TGT,该 TGT 使用 Kerberos 服务器自身的密钥加密。第二层加密允许 Kerberos 服务器验证每个 TGT 的真实性。主机主体可以有更长的票证生命周期。如果用户主体的生命周期为一周,但连接的主机的生命周期为九小时,则用户缓存将包含过期的主机主体,票证缓存将无法按预期工作。
设置 krb5.dict 以防止使用特定坏密码(如 kadmind(8) 中所述)时,请记住它仅适用于已分配密码策略的主体。krb5.dict 中使用的格式为每行一个字符串。创建指向 /usr/share/dict/words 的符号链接可能会有所帮助。
16.9.6. 缓解 Kerberos 限制
由于 Kerberos 是一种“全有或全无”的方法,网络上的每个启用的服务必须要么修改以与 Kerberos 一起工作,要么采取其他措施来防止网络攻击。这是为了防止用户凭证被窃取并被重新使用。一个例子是,当所有远程 shell 启用了 Kerberos,但非 Kerberized 的 POP3 邮件服务器仍以明文发送密码。
KDC 是单点故障。根据设计,KDC 必须像其主密码数据库一样安全。KDC 上不应该运行任何其他服务,并且应该物理上保持安全。危险性很高,因为 Kerberos 将所有密码加密存储,并使用相同的主密钥,而该密钥作为文件存储在 KDC 上。
被攻破的主密钥并不像人们想象的那么糟糕。主密钥仅用于加密 Kerberos 数据库,并作为随机数生成器的种子。只要对 KDC 的访问是安全的,攻击者无法利用主密钥做太多事情。
如果 KDC 无法访问,网络服务将无法使用,因为无法执行身份验证。可以通过设置一个主 KDC 和一个或多个从 KDC,以及通过小心实现使用 PAM 进行的备用身份验证来缓解这一问题。
Kerberos 允许用户、主机和服务彼此之间进行身份验证,但没有机制可以验证 KDC 对用户、主机或服务的身份。这意味着一个被篡改的 kinit
可能记录所有用户名和密码。像 security/tripwire 这样的文件系统完整性检查工具可以缓解这个问题。
16.9.7. 资源与进一步的信息
最后更新于
这有帮助吗?