使用 Kerberos 5 的集中式身份验证,第一部分
分布式 UNIX/Linux 环境中的帐户管理如果手动完成可能会变得复杂和混乱。大型站点使用专用工具来处理此问题。在本文中,我将描述即使是小型安装,例如您家中的三台计算机网络,也可以如何利用相同的工具。
分布式环境中的问题是,如果发生帐户更改,则需要在每台计算机上单独更改密码和影子文件。帐户更改包括密码更改、帐户的添加/删除、帐户名更改(UID/GID 更改在任何情况下都是一个大问题)、计算机登录权限的添加/删除等等。我还将解释 Kerberos 分发如何解决分布式计算环境中的身份验证问题。在第二部分中,我将描述授权问题的解决方案。
计算机用户身份验证问题主要通过密码解决,尽管还有其他方法,包括智能卡和生物识别技术。这些密码以前存储在 /etc/passwd 中,但现在使用影子密码,它们驻留在 /etc/shadow 中。由于这些文件是计算机本地的,因此保持它们最新是一个大问题。发明了 NIS、NIS+ 和 LDAP 等目录服务来解决这个问题。然而,这些服务引入了一个新问题:它们通过网络工作并暴露密码,而密码的加密强度很弱。
Kerberos 实现的身份验证协议结合了作为网络服务的优势,并消除了计算机之间完全通信密码的需求。为此,Kerberos 要求您在安全服务器上运行两个守护进程。密钥分发中心 (KDC) 守护进程处理所有密码验证请求和 Kerberos 凭据(称为票据授予票据 (TGT))的生成。第二个守护进程 Kerberos 管理守护进程允许您远程添加、删除和修改帐户,而无需登录到运行 Kerberos 守护进程的计算机。它还处理来自用户的密码更改请求。使用 Kerberos,只有密码更改才需要通过网络传输强加密的密码。
Kerberos KDC 在验证用户身份的过程中向帐户授予临时凭据 TGT。通常,这些凭据的有效期为 10 或 24 小时。此有效期可以配置,并且不应超过 24 小时,以防 TGT 被盗;窃贼只能在剩余的 TGT 有效期内使用它。如果您仅将 Kerberos 用于身份验证(如本文所述),则凭据过期不会导致任何问题。但是,如果您正在使用 Kerberized 服务,则需要培训您的用户在其当前凭据过期后获取新凭据,即使他们仍然处于登录状态。
Kerberos 是在麻省理工学院发明的。最新版本是 Kerberos 5,其协议在 RFC 1510 中定义。如今,有两种 Kerberos 实现可免费获得(请参阅在线资源)。麻省理工学院的 Kerberos 5 包含在 Red Hat Linux 中,而 Heimdal 包含在 SuSE 和 Debian 的 Linux 发行版中。Kerberos 5 实现也包含在 Microsoft Windows(2000 及更高版本)、Sun 的 Solaris(SEAM、Solaris 2.6 及更高版本)和 Apple 的 Mac OS X 中。我在本文中通篇使用麻省理工学院的 Kerberos 发行版,因为它提供了简单的密码质量检查、密码老化和开箱即用的密码历史记录功能。
在您可以将身份验证切换到 Kerberos 之前,您必须满足两个先决条件。首先,要包含在 Kerberos 安装中的所有计算机上的时钟都需要与运行 KDC 的计算机的时钟同步。执行此操作的最简单方法是在所有计算机上使用网络时间协议 (NTP)。
第二个要求更难满足。所有帐户名、UID 和 GID 在您的所有计算机上都必须相同。这是必要的,因为这些帐户中的每一个都将成为一个新的独立的 Kerberos 帐户,称为主体。您必须遍历所有本地 /etc/passwd 文件并检查是否满足此要求。如果不是,您需要整合您的帐户。如果您想将 Windows 或 Mac OS X 客户端添加到您的 Kerberos 安装中,您还需要查看这些机器上的所有帐户。
如果您决定使用 Linux 发行版附带的 Kerberos 软件包,只需安装它即可。如果您想自己编译 Kerberos 发行版,请按照以下说明进行操作。
1) 从在线资源中列出的 URL 之一获取源代码。获取源软件包的 PGP 签名,并使用以下命令验证下载的源代码的完整性
% gpg --verify krb5-1.3.4.targz.asc
2) 使用以下命令解压缩源代码
% tar zxvf krb5-1.3.4.tar.gz
3) 更改到源代码目录
% cd krb5-1.3.4/src
4) 执行
% ./configure --help
这会告诉您是否需要为您的站点使用特殊的配置选项。/usr/local/ 是默认安装目录。如果您需要在另一个目录中使用此软件,请在下一步中使用 --prefix=/new/path/to/directory 标志。
5) 在几乎所有情况下,默认值都应该可以
% ./configure
6) 使用以下命令编译软件包
% make
我在 krb5-1.3.4/src/kadmin/testing/util 目录中的一个文件中遇到了问题,可以安全地忽略它。使用以下命令重新启动编译% make -i在这种情况下。
7) 使用以下命令检查是否一切都编译正确
% make check
8) 如果一切看起来都正常,请使用以下命令安装软件包
% sudo make install
永远不要以 root 用户身份编译代码。仅在必要时使用 root 权限,例如在这些安装步骤中。
9) 您现在已在 /usr/local/ 中安装了 MIT Krb5。需要手动创建一些额外的目录并设置其权限
% sudo mkdir -p /usr/local/var/krb5kdc % sudo chown root /usr/local/var/krb5kdc % sudo chmod 700 /usr/local/var/krb5kdc
如果您真的需要或想要编译自己的 PAM 模块,以下是获取 Red Hat 提供的模块的工作版本的步骤。获取源代码(请参阅资源)并使用以下命令解压缩
% tar zxf pam_krb5-1.3-rc7.tar.gz % cd pam_krb5-1.3-rc7
Kerberos realm 是一个管理域,它有自己的 Kerberos 数据库。每个 Kerberos realm 都有自己的一组 Kerberos 服务器。您的 realm 名称可以是任何名称,但它应该反映您在 DNS 世界中的位置。如果新的 Kerberos realm 用于您的整个 DNS 域 example.com,您应该给您的 Kerberos realm 相同的名称(全部大写,这是 Kerberos 的约定):EXAMPLE.COM。或者,如果您的正在为 example.com 中的工程部门设置一个新的 realm,则可以选择 realm 名称 ENG.EXAMPLE.COM。
创建您自己的 realm 的第一步是创建一个 /etc/krb5.conf 文件,其中包含有关此 realm 的所有必要信息。krb5.conf 文件需要位于每个想要访问您的新 Kerberos realm 的计算机上。以下是 realm EXAMPLE.COM 的示例文件,KDC 和管理服务器在机器 kdc.example.com 上运行
[libdefaults] # determines your default realm name default_realm = EXAMPLE.COM [realms] EXAMPLE.COM = { # specifies where the servers are and on # which ports they listen (88 and 749 are # the standard ports) kdc = kdc.example.com:88 admin_server = kdc.example.com:749 } [domain_realm] # maps your DNS domain name to your Kerberos # realm name .example.com = EXAMPLE.COM [logging] # determines where each service should write its # logging info kdc = SYSLOG:INFO:DAEMON admin_server = SYSLOG:INFO:DAEMON default = SYSLOG:INFO:DAEMON
下一个文件 /usr/local/var/krb5kdc/kdc.conf 配置 KDC 服务器。它只需要位于运行 KDC 守护进程的计算机上。每个条目都有一个合理的默认值。创建一个空文件应该足以满足大多数情况
% sudo touch /usr/local/var/krb5kdc/kdc.conf
以下命令需要在将成为您的 KDC 的计算机上执行。命令
% sudo /usr/local/sbin/kdb5_util create -s
为新 realm 创建初始 Kerberos 数据库。它会要求您输入新 realm 的数据库主密码,并将其存储在一个文件中 (/usr/local/var/krb5kdc/.k5.EXAMPLE.COM)。此命令还在您的 Kerberos 5 帐户数据库中创建第一组主体。您可以使用以下命令列出它们
% sudo /usr/local/sbin/kadmin.local
然后输入listprincs在 kadmin.local: 提示符下。这将打印列表
K/M@EXAMPLE.COM kadmin/admin@EXAMPLE.COM kadmin/changepw@EXAMPLE.COM kadmin/history@EXAMPLE.COM krbtgt/EXAMPLE.COM@EXAMPLE.COM
此时,我们尚未准备好使用 kadmin 工具的远程版本。
在您开始在新 realm 中创建任何主体之前,您应该定义一个策略来确定如何处理密码
kadmin.local: add_policy -maxlife 180days -minlife ↪2days -minlength 8 -minclasses 3 ↪-history 10 default
此输入定义了用于我们从现在开始创建的每个主体的默认策略。它确定密码的最长有效期为 180 天。最短有效期为两天。最小密码长度为八个字符,并且这些字符必须来自以下五个可用类别中的三个不同类别:小写字母、大写字母、数字、标点符号和其他符号。保留最近十个密码的历史记录以防止重复使用。如果您想根据字典检查密码,请添加 dict_file 定义,例如
[realms] EXAMPLE.COM = { dict_file = /usr/share/dict/words }
到您的 kdc.conf 文件。
您现在可以为自己创建一个管理主体了
kadmin.local: addprinc john/admin
调整名称以匹配 您的 帐户名,但保留 /admin。然后它会两次要求您输入此主体的新密码。您可以使用以下命令查看新帐户
kadmin.local: getprinc john/admin
这会打印类似
Principal: john/admin@EXAMPLE.COM Expiration date: [never] Last password change: Wed Dec 24 09:55:17 PST 2003 Password expiration date: Mon Jun 21 10:55:17 PDT 2004 Maximum ticket life: 1 day 00:00:00 Maximum renewable life: 0 days 00:00:00 Last modified: Wed Dec 24 09:55:17 PST 2003 (root/admin@EXAMPLE.COM) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 2 Key: vno 1, Triple DES cbc mode with HMAC/sha1, no salt Key: vno 1, DES cbc mode with CRC-32, no salt Attributes: Policy: default
通过键入以下命令退出 kadmin.local 程序quit并使用以下命令启动 KDC 守护进程
% sudo /usr/local/sbin/krb5kdc
通过键入以下命令获取 Kerberos 5 TGT
% /usr/local/bin/kinit john/admin@EXAMPLE.COM
并使用以下命令查看您的 TGT
% /usr/local/bin/klist Ticket cache: FILE:/tmp/krb5cc_5828 Default principal: john/admin@EXAMPLE.COM Valid starting Expires Service principal 12/23/03 14:15:39 12/24/03 14:15:39 krbtgt/EXAMPLE.COM@EXAMPLE.COM
恭喜!您刚刚完成了第一次成功的 Kerberos 身份验证。
您现在需要指定此管理帐户应具有哪些权限,这由文件 /usr/local/var/krb5kdc/kadm5.acl 中的条目确定。您可以通过添加以下行来授予 john/admin 管理所有主体(由通配符 * 指示)的权限
john/admin@EXAMPLE.COM *
到此文件。
在您可以开始通过网络使用管理守护进程 (kadmind) 之前,您必须创建一个密钥表文件,其中包含我们在初始化 realm 时创建的 kadmin 主体之一的密钥
kadmin.local: ktadd -k /usr/local/var/krb5kdc/ ↪kadm5.keytab kadmin/changepw
现在一切都已为 Kerberos 管理守护进程做好准备。使用以下命令启动它
% sudo /usr/local/sbin/kadmind
此守护进程允许您使用 kadmin 客户端工具远程管理您的 Kerberos 主体,而无需登录到您的 KDC。如果您希望您的 Kerberos 守护进程在启动时自动启动,请将它们添加到您的 KDC 的 /etc/rc 文件中。
使用上面获得的 Kerberos TGT,启动远程管理工具
% /usr/local/sbin/kadmin Authenticating as principal john/admin@EXAMPLE.COM with password. Password for john/admin@EXAMPLE.COM:
新帐户仍然需要添加到您的影子文件或密码映射中。但是,您不必将加密密码放入这些位置,而是必须创建一个新的 Kerberos 主体并将密码存储在 KDC 中。
使用 kadmin 工具
% /usr/local/sbin/kadmin
为普通用户添加主体,使用以下命令
kadmin: addprinc john NOTICE: no policy specified for john@EXAMPLE.COM; assigning "default" Enter password for principal "john@EXAMPLE.COM": Re-enter password for principal "john@EXAMPLE.COM": Principal "john@EXAMPLE.COM" created.
您在此主体创建过程中输入的密码是 john 需要输入的密码,以便获取 Kerberos TGT 或登录到配置为使用您的 Kerberos 5 realm 的计算机。
您现在可以手动为您的所有帐户创建主体,或者使用下面迁移部分中描述的技术。
如果您计划在您的站点生产环境中使用 Kerberos,您应该计划使用额外的从 KDC,以使您的安装更具容错能力。为此,主 KDC 需要安装一个额外的传播服务,该服务将 KDC 数据库的更新版本发送到所有从服务器。从服务器需要安装传播服务的接收端。有关如何设置此项,请参阅 MIT 文档。
启用计算机进行 Kerberos 身份验证的最简单方法是使用可插拔身份验证模块 (PAM)。因为它使用 Kerberos API 调用,所以它需要一个工作的 /etc/krb5.conf 文件。因此,第一步是将 /etc/krb5.conf 文件从您的 KDC(见上文)复制到每台客户端机器。
Kerberos 不仅用于验证用户身份,还用于验证计算机身份,以防止您登录到 IP 地址被劫持的计算机。为此,每台计算机都需要自己的 Kerberos 主体,其密钥(密码)存储在一个文件(密钥表文件)中。计算机的主体具有特殊形式
host/<hostname>.example.com@EXAMPLE.COM.
第一步是为您的每台客户端机器创建一个新的主体。以下命令使用计算机名 client1 作为示例。将字符串 client1 替换为客户端计算机的主机名。登录到您的每台客户端计算机并执行
% sudo /usr/local/sbin/kadmin kadmin: addprinc -randkey host/ ↪client1.example.com@EXAMPLE.COM
这会创建文件 /etc/krb5.keytab。要具有 /etc/ 目录的写入权限,您需要使用 sudo 运行 kadmin 命令。仅创建新主体不需要这些特殊权限。但是,请注意 /etc/krb5.keytab 的所有权和文件权限;它必须只能由 root 用户读取。否则,这台机器的安全性将受到威胁。
有几个适用于 Kerberos 5 的 PAM 模块,都称为 pam_krb5。由于 MIT Kerberos 5 版本 1.3 中的一些 API 更改,其中大多数不再工作。您现在最好的选择是使用 Linux 发行版附带的 PAM 模块。请参阅上面关于如何从源代码构建 Kerberos 5 的 PAM 模块的部分。
现在,通过编辑文件 /etc/pam.d/system-auth(在 Red Hat 系统上)将新的 PAM 模块添加到系统的身份验证堆栈中。这些条目应类似于这些 Red Hat 9 条目
auth required /lib/security/$ISA/pam_env.so auth sufficient /lib/security/$ISA/pam_unix.so likeauth nullok auth sufficient /lib/security/$ISA/pam_krb5.so use_first_pass auth required /lib/security/$ISA/pam_deny.so account required /lib/security/$ISA/pam_unix.so account [default=bad success=ok user_unknown=ignore ↪service_err=ignore system_err=ignore] ↪/lib/security/$ISA/pam_krb5.so password required /lib/security/$ISA/pam_cracklib.so ↪retry=3 type= password sufficient /lib/security/$ISA/pam_unix.so ↪nullok use_authtok md5 shadow password sufficient /lib/security/$ISA/pam_krb5.so ↪use_authtok password required /lib/security/$ISA/pam_deny.so session required /lib/security/$ISA/pam_limits.so session required /lib/security/$ISA/pam_unix.so session optional /lib/security/$ISA/pam_krb5.so
这些更改使 PAM 配置文件中具有 system-auth PAM 堆栈的每个程序(请参阅 /etc/pam.d/ 中的其他文件)都使用 Kerberos 进行身份验证。
如果您已经有一个正在运行的 Windows Active Directory (AD) KDC 安装,您可以将其用作 Linux/UNIX 机器的主 KDC。在这种情况下,您可以跳过整个服务器安装,只执行上面描述的客户端设置。您的 /etc/krb5.conf 文件需要定义 Windows KDC 而不是 UNIX KDC。有关如何创建和复制密钥表文件以及此场景的更多信息,请参阅资源。
如果您的组中有多台 Windows 机器,您也可以为它们使用您的 UNIX KDC。但是,这仅在您的 Windows 客户端不属于已经具有 Kerberos 的 Windows AD 域且 Kerberos 和 Windows 中的帐户名相同时才有效。有关详细信息,请参阅资源。
在您的 Kerberos 5 realm 中使用 Mac OS X 客户端就像在您的 Mac 上配置 UNIX KDC 的名称一样容易。同样,帐户名必须匹配。
现在您已经有了一个工作的 Kerberos 5 realm 并且配置了您的客户端,您必须转换您的所有用户帐户。到目前为止,您的帐户密码存储在机器的本地 /etc/shadow 文件中或 NIS/LDAP 密码映射中。这些密码使用单向哈希函数加密,这使得没有超级计算机的人不可能或至少不切实际地破解它们或将所有内容转换为 Kerberos 5 格式。从您当前的情况迁移到 Kerberos 的一个好方法是使用 pam_krb5_migrate(请参阅资源)。此可堆叠 PAM 模块可以安装在几台计算机上;每次有人登录时,它都会在您的 Kerberos 5 KDC 中为此帐户创建一个新的主体,并重用该帐户的当前密码。
在每个人都登录到这些特殊机器后,您的所有用户都将拥有相应的 Kerberos 5 主体。然后,您可以将本地文件或 NIS/LDAP 密码映射中的密码替换为占位符,例如 krb5。从现在开始,Kerberos PAM 模块将验证您的用户身份。此时,您也可以从迁移系统中删除 pam_krb5_migrate。
现在您的 Kerberos 已经启动并运行,您可以使用利用它的服务。您可以安装 Kerberized telnet 和 FTP,但您真的应该使用 SSH。您可以 Kerberize 您的 Apache Web 服务器和您的 Mozilla Web 浏览器。在使用 Kerberos 之前,您在使用这些服务时必须输入密码。使用 Kerberos,所有这些应用程序都使用您存储的 Kerberos 凭据并在内部使用它们来验证您对相应服务的身份。这就是许多人所说的单点登录。
Alf Wachsmann 博士自 1999 年以来一直在斯坦福直线加速器中心 (SLAC) 工作。他负责 Linux 自动化安装的所有领域,包括农场节点、服务器和桌面。他的工作重点是 AFS 支持、迁移到 Kerberos 5、用户注册表项目和用户顾问。