使用 LDAP 和 Kerberos
在使用 Kerberos 时,在您的本地网络中分发用户信息(如用户 ID、组、主目录)的一种方法就是使用 LDAP。这需要一种强大的身份验证机制来防止包被窃取以及他攻击。一种解决方案是将 Kerberos 也用于 LDAP 通信。
OpenLDAP 通过 SASL(简单身份验证会话层)实现了大部分身份验证功能。SASL 基本上是一种用于身份验证的网络协议。SASL 实施是 cyrus-sasl,它支持许多不同的身份验证方法。Kerberos 身份验证是通过 GSSAPI(通用安全服务 API) 执行的。默认情况下,不安装用于 GSSAPI 的 SASL 插件。请使用 rpm -ivh cyrus-sasl-gssapi-*.rpm 来手动安装它。
为了使 Kerberos 能够绑定到 OpenLDAP 服务器,请创建一个主体 ldap/earth.example.com 并将其添加到 keytab:
默认情况下,LDAP 服务器 slapd 以用户和组 ldap 的身份运行,但只有 root 用户才能读取 keytab 文件。因此,要么更改 LDAP 配置以便使服务器以 root 用户身份运行,要么使组 ldap 可读取 keytab 文件。如果 /etc/sysconfig/openldap 中的 OPENLDAP_KRB5_KEYTAB 变量中指定了 keytab 文件并且 OPENLDAP_CHOWN_DIRS 变量设置成 yes(这是默认设置),则由 OpenLDAP 启动脚本 (/etc/init.d/ldap) 自动执行后一项操作。如果 OPENLDAP_KRB5_KEYTAB 保留为空,则使用 /etc/krb5.keytab 下的默认 keybab 文件,并且您必须如以下描述的那样自己调整优先级。
要以 root 用户身份运行 slapd,请编辑 /etc/sysconfig/openldap。通过在 OPENLDAP_USER 和 OPENLDAP_GROUP 变量前放置一个注释字符来禁用它们。
要使 keytab 对组 LDAP 可读,请执行
chgrp ldap /etc/krb5.keytab
chmod 640 /etc/krb5.keytab
第三个方案(可能是最好的解决方案)是指示 OpenLDAP 使用特殊的 keytab 文件。要完成此操作,启动 kadmin 然后在添加主体 ldap/earth.example.com 后输入以下命令:
ktadd -k /etc/openldap/ldap.keytab ldap/earth.example.com@EXAMPLE.COM
然后,在 shell 上运行:
chown ldap.ldap /etc/openldap/ldap.keytab
chmod 600 /etc/openldap/ldap.keytab
要指示 OpenLDAP 使用不同的 keytab 文件,在 /etc/sysconfig/openldap 中更改以下变量:
OPENLDAP_KRB5_KEYTAB="/etc/openldap/ldap.keytab"
最后,使用 rcldap restart 重启动 LDAP 服务器。
将 Kerberos 身份验证与 LDAP 一起使用
现在应该可以自动将 ldapsearch 等工具与 Kerberos 认证一起使用。
ldapsearch -b ou=people,dc=example,dc=com '(uid=newbie)'
SASL/GSSAPI authentication started
SASL SSF: 56
SASL installing layers
[...]
# newbie, people, example.com
dn: uid=newbie,ou=people,dc=example,dc=com
uid: newbie
cn: Olaf Kirch
[...]
正如您所看到的,ldapsearch 打印一条消息,表示它已经启动 GSSAPI 身份验证。下一条信息无疑颇具隐蔽性,它实际上表明了安全强度系数(缩写为 SSF)是 56(值 56 有些随意,之所以选择这个数字,很可能因为它是 DES 加密密钥中的位数)。这里要告诉您的是 GSSAPI 认证是成功的,并且该加密要用于为 LDAP 连接提供集成保护和机密性。
在 Kerberos 中,身份验证永远是相互的。这意味着不仅您向 LDAP 服务器身份验证自己,而且 LDAP 服务器本身也向您身份验证。这意味着您是与所需的 LDAP 服务器而不是攻击者设置的假冒服务进行通讯。
Kerberos 身份验证和 LDAP 访问控制
现在,允许每个用户修改他们的 LDAP 用户记录的登录壳层属性。假定在您的纲要中 joe 用户的 LDAP 项位于 uid=joe,ou=people,dc=example,dc=com,请在/etc/openldap/slapd.conf 中设置以下访问控制:
# This is required for things to work _at all_
access to dn.base="" by * read
# Let each user change their login shell
access to dn="*,ou=people,dc=example,dc=com" attrs=loginShell
by self write
# Every user can read everything
access to *
by users read
第 2 个语句授予已通过身份验证的用户对他们自己的 LDAP 项的 loginShell 属性进行写访问的权限。第 3 个语句授予所有已通过身份验证的用户对整个 LDAP 目录进行读访问的权限。
这里还有个不太重要的方面未明确,即 LDAP 服务器如何能够得知 Kerberos 用户 joe@EXAMPLE.COM 与 LDAP 判别名 uid=joe,ou=people,dc=example,dc=com 相对应。这种映射必须使用 saslExpr 指令进行手动配置。在本例中,则是将以下语句添加到 slapd.conf:
authz-regexp
uid=(.*),cn=GSSAPI,cn=auth
uid=$1,ou=people,dc=example,dc=com
要了解它的工作原理,您需要知道,当 SASL 身份验证用户时,OpenLDAP 将使用 SASL 为它指派的名称(如 joe)和 SASL 功能的名称 (GSSAPI) 构成一个判别名。结果是uid=joe,cn=GSSAPI,cn=auth。
如果已经配置了 authz-regexp,它会将第一个参数用作常规表达式来检查从 SASL 信息构成的判别名。如果此常规表达式匹配,就用 authz-regexp 语句的第 2 个参数替换此名称。占位符 $1 被替换为 (.*) 表达式所匹配的子字符串。
可能有更复杂的匹配表达式。如果您的目录结构或纲要更加复杂(其中用户名不是判别名的一部分),则甚至可以使用搜索表达式来将 SASL 判别名映射为用户判别名。