OpenLDAP 无处不在再探

作者:Craig Swanson

许多读者曾使用我们在 2002 年 12 月发表的文章《OpenLDAP 无处不在》,实现了公司范围内的统一登录。自那时以来,OpenLDAP 和 Linux 都取得了进步。本文中,我们将演示如何使用 OpenLDAP 作为混合环境的核心目录服务。LDAP 服务器为所有客户端提供共享电子邮件目录、Linux 和 Microsoft Windows 客户端的登录、主目录的自动挂载和文件共享。本文示例中使用的简单混合环境如图 1 所示。

OpenLDAP Everywhere Revisited

图 1. 在混合环境中,Linux 和 Windows 客户端都使用通用的 LDAP 基础设施。

LDAP 服务器的安装和配置

我们讨论的 LDAP 服务器是使用 RPM 二进制软件包和 Fedora Core 3 上的 openldap-2.2.13-2 安装的。还需要 nss_ldap 软件包。有关来自 openldap.org 的最新源代码,请参阅在线资源。编辑服务器配置文件 /etc/openldap/slapd.conf,如列表 1 所示。以空格开头的行被解释为前一行的延续,因此无需在长行末尾使用反斜杠。

列表 1. slapd.conf 文件包含安全运行 LDAP 的重要设置。

# slapd.conf
# schemas to use
include     /etc/openldap/schema/core.schema
include     /etc/openldap/schema/cosine.schema
include     /etc/openldap/schema/inetorgperson.schema
include     /etc/openldap/schema/nis.schema
include     /etc/openldap/schema/samba.schema
include     /etc/openldap/schema/redhat/autofs.schema

# database definition
database   ldbm
suffix     "dc=foo,dc=com"
rootdn     "cn=Manager,dc=foo,dc=com"
# Cleartext passwords, especially for the rootdn,
# should be avoided.   Use strong authentication.
#rootpw     secret
rootpw     {SSHA}xxxxxxxxxxxxxxxxxxxxx
directory  /var/lib/ldap

# Indices to maintain for this database
index     objectClass,uid,uidNumber,gidNumber,
          memberUid eq
index     cn,mail,surname,givenname eq,subinitial
index     sambaSID eq
index     sambaPrimaryGroupSID eq
index     sambaDomainName eq

# Users can authenticate and change their password
access to attrs=userPassword,sambaNTPassword,
      sambaLMPassword
      by dn="cn=Manager,dc=foo,dc=com" write
      by self write
      by anonymous auth
      by * none
# All other attributes are readable to everybody
access to *
      by self write
      by dn="cn=Manager,dc=foo,dc=com" write
      by * read

LDAP 模式定义了构成目录条目的对象类和属性。Red Hat 的 autofs 模式符合我们的需求,并与 RPM 安装包一起打包。如果您发现需要向目录添加 objectClass 或属性,请参阅 OpenLDAP 管理指南。

我们使用默认数据库类型 ldbm。我们的示例使用 LDAP 域组件。因此,foo.com 变为 dc=foo,dc=com。

管理员对 LDAP 条目具有完全写入权限。使用 /usr/sbin/slappasswd 创建管理员密码。将加密后的密码粘贴到 slapd.conf 中的 rootpw 条目中。

索引行增强了常用查询属性的性能。访问控制限制了对 userPassword 条目的访问。用户和管理员可以修改该条目。对于所有其他条目,管理员具有写入权限,而其他所有人均被授予读取权限。

创建目录结构

目录中的每个条目都通过 distinguished name (dn) 唯一标识。foo.com 的 dn 是 dn: dc=foo, dc=com。organizationalUnit (ou) 提供了一种对条目进行分组的方法。目录结构如列表 2 所示。

列表 2. LDAP distinguished name 被组织成 organizational unit 树。

+ dc=foo,dc=com
|- ou=People                  Persons
|  |- ou=contacts,ou=people   Email contacts
|- ou=Groups                  System groups
|- ou=auto.master             Automount master map
|- ou=auto.home               Automount map
|- ou=auto.misc               Automount map
|- ou=Computers               Samba domain members
|- cn=NextFreeUnixId          Samba Next Free ID
|- SambaDomainName            Samba domain info object class

我们以 LDAP Interchange Format (LDIF) 创建顶级条目,并将它们保存到 top.ldif 中,如列表 3 所示。

列表 3. 以简单的键:值 LDIF 格式手动创建 LDAP 树的顶部,top.ldif。

dn: dc=foo,dc=com
objectClass: dcObject
objectClass: organization
o: Foo Company
dc: foo

dn:ou=People,dc=foo,dc=com
objectClass: organizationalUnit
ou: People

dn:ou=Groups,dc=foo,dc=com
objectClass: organizationalUnit
ou: Groups

dn:ou=contacts,ou=people,dc=foo,dc=com
associatedDomain: foo.com
ou: contacts
ou: people
objectClass: organizationalUnit
objectClass: domainRelatedObject

使用 ldapadd 将顶级条目添加到目录

ldapadd -x -D 'cn=manager,dc=foo,dc=com' \
-W -f top.ldif

然后,使用 ldapsearch 命令检索所有条目来测试您的工作

ldapsearch -x -b 'dc=foo,dc=com'
共享电子邮件联系人

至此,我们在 LDAP 中拥有足够的结构来投入实际使用。我们首先共享我们的电子邮件联系人。为了简化流程,您或许可以以 LDIF 格式导出您的电子邮件地址簿。例如,在 Mozilla Thunderbird 中,您可以从地址簿窗口的“工具”菜单中以 LDIF 格式导出。您需要处理生成的文件,使其看起来像我们下面的联系人示例。我们建议使用 Perl 来完成此任务。

联系人通过其电子邮件地址唯一标识。以下是联系人的 dn

dn: uid=someone@somewhere.com,ou=contacts,
↪ou=people,dc=foo,dc=com.

包含所有属性的完整联系人条目如下所示

dn: uid=someone@somewhere.com,ou=contacts,
↪ou=people,dc=foo,dc=com
mail: someone@somewhere.com
uid: someone@somewhere.com
givenName: Someone
sn: Youknow
cn: Someone Youknow
objectClass: person
objectClass: top
objectClass: inetOrgPerson

用空行分隔每个联系人条目,并将其保存到名为 contacts.ldif 的文件中。使用 ldapadd 将联系人添加到目录

ldapadd -x -D 'cn=manager,dc=foo,dc=com' \
-W -f contacts.ldif

然后,使用如上所示的 ldapsearch 命令进行测试。

配置电子邮件客户端
OpenLDAP Everywhere Revisited

图 2. 要使用公司地址簿,请在 Thunderbird 的“目录服务器属性”中填写您的服务器信息。

接下来,我们配置 Mozilla Thunderbird 以使用新的 LDAP 服务器(图 2)。在 Thunderbird 的“工具”菜单中,选择“选项”。在“撰写”选项卡中,选择“目录服务器”,“编辑目录”,然后选择“添加”。使用以下信息填写“目录服务器属性”:

Name: FOO
Server: ldapserver.foo.com
base DN: ou=people,dc=foo,dc=com

在“高级”选项卡中,增加返回结果的数量以适应您的目录大小。对于 foo.com,我们选择了 1,000 个结果。

通过向 LDAP 目录中的某个联系人撰写邮件来测试您的设置。地址应在您键入时自动完成。另一个测试是从 Thunderbird 邮件地址簿中搜索 LDAP 目录。在 FOO 地址簿中搜索“名称或电子邮件包含:*”。这应返回所有联系人条目。

使用 LDAP 的统一 Linux 登录

通过将用户帐户信息存储在 LDAP 中,您可以在任何 Linux 控制台上使用相同的用户名和密码。首先,您必须确定应在 LDAP 中输入哪些用户名。表 1 显示了我们的 UID/GID 用户方案。

表 1. UID/GID 用户方案

帐户类型UID
系统帐户UID < 500
Samba 特殊帐户499 < UID < 1,000
统一登录帐户999 < UID < 10,000
本地用户和组,不在 LDAP 中> 10,000

此用户方案允许 9,000 个 LDAP 统一登录条目,同时也允许不干扰 LDAP UID 和 GID 的本地用户和组。该用户方案还允许 Samba 主域控制器所需的帐户。

创建 LDAP 用户登录条目

用户登录条目通过登录名 uid 标识。登录用户是 ou=people 的成员,从而产生以下 dn

dn: uid=gomerp,ou=people,dc=foo,dc=com

完整条目包含控制帐户访问所需的属性,如列表 4 所示。完整条目还包括下面讨论的 Samba 配置所需的属性。

列表 4. 用户登录条目包含登录所需的密码信息,以及 Samba 配置。

dn:uid=gomerp,ou=People,dc=foo,dc=com
uid: gomerp
cn: Gomer Pyle
sn: Pyle
givenname: Gomer
mail: gomer.pyle@foo.com
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
objectClass: sambaSAMAccount
uidNumber: 5000
homeDirectory: /h/gomerp
loginShell: /bin/bash
description: Gomer Pyle
displayName: Gomer Pyle
gecos: Gomer Pyle
gidNumber: 513
userPassword: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxx
sambaLogonTime: 0
sambaLogoffTime: 2147483647
sambaKickoffTime: 2147483647
sambaPwdCanChange: 0
sambaSID: S-1-5-21-1400792368-3813960858-1703501993-11000
sambaPrimaryGroupSID: S-1-5-21-1400792368-3813960858-1703501993-513
sambaLogonScript: gomerp.cmd
sambaHomeDrive: H:
sambaHomePath: \\LDAPSERVER\gomerp
sambaLMPassword: XXXXXXXXXX
sambaAcctFlags: [U]
sambaNTPassword: XXXXXXXXXX
sambaPwdLastSet: 1097240543
sambaPwdMustChange: 1105016543

OpenLDAP 附带了可以提取用户帐户信息的迁移实用程序;请参阅 /usr/share/openldap/migration。要将现有的 /etc/passwd 文件转换为 LDIF,请首先检查 migrate_common.ph。编辑该文件以包含您的域名、默认 base 并启用扩展模式

# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foo.com";

# Default base
$DEFAULT_BASE = "dc=foo,dc=com";

# turn this on to support more general object classes
# such as person.
$EXTENDED_SCHEMA = 1;

从 /etc/passwd 中提取用户帐户信息

/usr/share/openldap/migration/migrate_passwd.pl \
/etc/passwd > people.ldif

查看生成的 LDIF 文件。您应该删除系统帐户(如 root)和不需要出现在 LDAP 中的本地用户的私有组的条目。

将用户条目添加到 LDAP 并使用如上所述的 ldapsearch 命令进行测试

ldapadd -x -D 'cn=manager,dc=foo,dc=com' -W \
-f people.ldif

由于登录用户属于 ou=people,您现在可以在您的电子邮件客户端中查找他们的电子邮件地址。

创建组条目

您需要为每个要在多台 Linux 计算机之间共享的组创建一个组条目。每个用户还需要一个用户私有组的组条目。组条目由 cn 标识,每个组都属于 ou=Groups。例如

dn: cn=gomerp,ou=Groups,dc=foo,dc=com

用户私有组将如下所示

dn: cn=gomerp,ou=Groups,dc=foo,dc=com
objectclass: posixGroup
objectclass: top
cn: gomerp
userPassword: {crypt}x
gidNumber: 5223

共享组将如下所示

dn: cn=web_dev,ou=Groups,dc=foo,dc=com
objectclass: posixGroup
objectclass: top
cn: web_dev
gidNumber: 5019
memberUid: gomerp
memberUid: goober
memberUid: barneyf

从 /etc/group 中提取组信息

/usr/share/openldap/migration/migrate_passwd.pl \
/etc/group > group.ldif

查看生成的 LDIF 文件。您应该删除系统组和不需要出现在 LDAP 中的本地系统用户的条目。

将组条目添加到 LDAP 并使用 ldapsearch 命令进行测试

ldapadd -x -D 'cn=manager,dc=foo,dc=com' -W \
-f group.ldif

配置自动挂载以共享主目录和 NFS 共享

通过统一登录,用户拥有一个通过网络文件系统 (NFS) 共享的单一主目录。我们从 ldapserver.foo.com 托管我们的主目录并共享 /home,但文件服务器和 OpenLDAP 不需要在同一台机器上运行。NFS 的详细信息超出了本文的范围,但以下是 /etc/exports 中的一行,用于导出主目录

/home *.foo.com(rw)

Linux LDAP 客户端在登录时使用 automount 和 NFS 挂载用户的主目录。LDAP 使用 automount 是 NIS(网络信息服务)自动挂载映射的替代方案。替换 auto.master、auto.home 和 auto.misc 的自动挂载映射。为此,我们为 auto.master 创建一个新的 organizational unit

dn: ou=auto.master,dc=foo,dc=com
objectClass: top
objectClass: automountMap
ou: auto.master

auto.master 条目由 cn 标识。automountInformation 属性指示 automount 在 LDAP 中查找映射

dn: cn=/h,ou=auto.master,dc=foo,dc=com
objectClass: automount
automountInformation: ldap:ou=auto.home,dc=foo,dc=com
cn: /h

趁热打铁,让我们为其他 NFS 共享目录创建一个 auto.master 条目

dn: cn=/share,ou=auto.master,dc=foo,dc=com
objectClass: automount
automountInformation: ldap:ou=auto.misc,dc=foo,dc=com
cn: /share

以 LDIF 格式创建自动挂载条目,保存为 auto.master.ldif,并将条目添加到 LDAP

ldapadd -x -D 'cn=manager,dc=foo,dc=com' -W -f auto.master.ldif

接下来,我们为 auto.home 创建一个新的 organizational unit

dn:ou=auto.home,dc=foo,dc=com
objectClass: top
objectClass: automountMap
ou: auto.home

主目录条目由 cn 标识

dn: cn=gomerp,ou=auto.home,dc=foo,dc=com
objectClass: automount
automountInformation: ldapserver.foo.com:/home/gomerp
cn: gomerp

为每个用户以 ldif 格式创建 auto.home 条目,保存为 auto.home.ldif,并将条目添加到 LDAP

ldapadd -x -D 'cn=manager,dc=foo,dc=com' -W \
-f auto.home.ldif

从 Linux LDAP 客户端自动挂载时,您的主目录 ldapserver.foo.com:/home/gomerp 将挂载在 /h/gomerp 上。其他 NFS 共享可以根据需要在 LDAP 中输入并自动挂载。auto.misc organizational unit 包含这些自动挂载映射,其形式为 ou=auto.misc。

我们已经为 /share 创建了一个 auto.master 条目,如上所示。现在,我们创建 ou=auto.misc 条目

dn:ou=auto.misc,dc=foo,dc=com
ou: auto.misc
objectClass: top
objectClass: automountMap

在 ou=auto.misc 下为 NFS 共享创建条目

dn:cn=redhat,ou=auto.misc,dc=foo,dc=com
objectClass: automount
automountInformation: bigdisk.foo.com:/pub/redhat
cn: redhat

dn:cn=engineering,ou=auto.misc,dc=foo,dc=com
objectClass: automount
automountInformation: bigdisk.foo.com:/data/engineering
cn: engineering

将条目保存为 auto.misc.ldif,并将条目添加到 LDAP

ldapadd -x -D 'cn=manager,dc=foo,dc=com' -W -f auto.misc.ldif

从 Linux LDAP 客户端自动挂载时,您的共享目录 bigdisk.foo.com:/data/engineering 将挂载在 /share/engineering 上。

配置 Linux LDAP 客户端

要开始配置 Linux LDAP 客户端,您需要安装名称切换服务软件包 nss_ldap。Red Hat 工具 /usr/bin/authconfig 对于配置客户端非常方便。选择“使用 LDAP”并填写字段,使其显示“服务器:ldapserver.foo.com”和“Base DN:dc=foo,dc=com”。Authconfig 会写入以下文件:/etc/ldap.conf、/etc/openldap/ldap.conf 和 /etc/nsswitch.conf。

验证 /etc/nsswitch.conf 是否具有以下条目

passwd:     files ldap
shadow:     files ldap
group:      files ldap
automount:  files ldap

验证 /etc/ldap.conf 是否具有以下条目

host ldapserver.foo.com
base dc=foo,dc=com

验证 /etc/openldap/ldap.conf 是否具有以下条目

HOST ldapserver.foo.com
BASE dc=foo,dc=com
最终 Linux 服务器配置

用户的密码和组条目必须从主目录所在的 NFS 服务器上的密码和组文件中删除。创建备份,然后编辑 /etc/passwd、/etc/shadow、/etc/group 和 /etc/gshadow 以删除 LDAP 真实人员条目。在我们的示例中,/etc/passwd 应该没有 UID 从 1000 到 9999 的帐户。

要进行测试,请使用 LDAP 用户名登录到 Linux LDAP 客户端。您应该看到用户的相应登录 shell 和主目录。要测试 auto.misc 共享,您必须按名称访问共享,例如

cd /share/redhat

Automount 仅在 NFS 共享被使用时才挂载它们,因此目录 /share/redhat 在被访问之前是不可见的。

使用 Samba 和 LDAP 实现统一登录

将 Samba 和 LDAP 结合使用的主要目的是为 Microsoft Windows 客户端实现统一登录。这对您的组织意味着用户将能够从任何工作站登录到您的网络,并访问所有共享文件夹、文件和打印机。

统一登录的第一步是从将 Samba 配置为主域控制器 (PDC) 开始。有关如何设置 Samba 作为 PDC 的完整配置详细信息超出了本文的范围。请访问 Idealx 网站以获取出色的 HOWTO(请参阅资源)。Idealx 的人员为 Samba 项目做出了巨大贡献,如果您计划使用 Samba,您应该熟悉他们的工具。

假设您已经有设置 Samba 域控制器的经验,此 Samba 配置文件应该可以帮助您启动并运行本文中的目录示例(列表 5)。完整文件可从 Linux Journal FTP 站点获取(请参阅资源)。

列表 5. 配置为与 OpenLDAP 目录配合使用的 Samba smb.conf 文件摘录。

[global]

...
  obey pam restrictions = No
  ldap passwd sync = Yes
  ldap passwd sync = Yes
...
  passdb backend = ldapsam:ldap://ldapserver.foo.com/
  ldap admin dn = cn=Manager,dc=foo,dc=com
  ldap suffix = dc=foo,dc=com
  ldap group suffix = ou=Groups
  ldap user suffix = ou=People
  ldap machine suffix = ou=Computers
  ldap idmap suffix = ou=People
  ldap ssl = no
  add user script = \
    /usr/local/sbin/smbldap-useradd -m "%u"
  ldap delete dn = Yes
  delete user script = \
    /usr/local/sbin/smbldap-userdel "%u"
  add machine script = \
    /usr/local/sbin/smbldap-useradd -w "%u"
  add group script = \
    /usr/local/sbin/smbldap-groupadd -p "%g"
  delete group script = \
    /usr/local/sbin/smbldap-groupdel "%g"
  add user to group script = \
    /usr/local/sbin/smbldap-groupmod -m "%u" "% g"
  delete user from group script = \
    /usr/local/sbin/smbldap-groupmod -x "% u" "%g"
  set primary group script = \
    /usr/local/sbin/smbldap-usermod -g "%g" "%u "

谜题的剩余部分涉及设置 LDAP 以利用 Samba 在过去几年中所做的改进。这应该类似于上面的 LDAP 设置,但添加了 Samba 的更新功能。使用新的 Samba 3 版本,我们现在可以将所有 Samba 帐户信息存储在 LDAP 目录中。这很有益,因为现在所有信息都存储在一个中心位置。

Samba LDAP 设置

LDAP/Samba 组合设置中的一个区别是,需要填充额外的帐户和 LDAP 条目才能使两者协同工作。您的统一登录服务器需要几个众所周知的 Windows 域用户帐户和域组帐户才能正常运行。服务器还需要特殊的 LDAP OU 条目来存储域帐户信息。幸运的是,有一个名为 smbldap-populate 的脚本可以为您完成所有这些工作。此脚本是 Idealx smbldap-tools 软件包的一部分,它可以帮助您设置 PDC 和启用 Samba 的 LDAP 目录。列表 6 是您运行 smbldap-populate 脚本时应该看到的示例输出。

列表 6. smbldap-populate 工具自动添加使您的 OpenLDAP 服务器与 Samba 协同工作所需的帐户。

[root]# smbldap-populate
Using builtin directory structure
adding new entry: dc=foo,dc=com
adding new entry: ou=Users,dc=foo,dc=com
adding new entry: ou=Groups,dc=foo,dc=com
adding new entry: ou=Computers,dc=foo,dc=com
adding new entry: ou=Idmap,dc=foo,dc=org
adding new entry: cn=NextFreeUnixId,dc=foo,dc=org
adding new entry: uid=Administrator,ou=Users,dc=foo,dc=com
adding new entry: uid=nobody,ou=Users,dc=foo,dc=com
adding new entry: cn=Domain Admins,ou=Groups,dc=foo,dc=com
adding new entry: cn=Domain Users,ou=Groups,dc=foo,dc=com
adding new entry: cn=Domain Guests,ou=Groups,dc=foo,dc=com
adding new entry: cn=Print Operators,ou=Groups,dc=foo,dc=com
adding new entry: cn=Backup Operators,ou=Groups,dc=foo,dc=com
adding new entry: cn=Replicator,ou=Groups,dc=foo,dc=com
adding new entry: cn=Domain Computers,ou=Groups,dc=foo,dc=com

如果您检查此填充脚本的示例输出,您应该注意到它已向目录添加了几个新用户、组和 OU。例如,该脚本将众所周知的 Domain Admins 和 Domain Users 组添加到目录中。基于 NT 版本的 Microsoft Windows 都预配置了特定的用户和组条目。每个条目都有一个与之关联的相对标识符 (RID)。这对 LDAP 意味着相应的 LDAP 用户或组条目必须分配给 Windows 用户或组的相应 RID。使用 smbldap-populate 脚本可以为您处理这种关系。所需的众所周知用户和组 RID 是

Name          RID
-----------------
Domain Admins 512
Domain Users  513
Domain Guests 514

除了新的用户和组条目之外,几个新的 OU 条目还可以提供进一步的域功能。第一个是 ou=Computers,它用于存储域上成员服务器和工作站的所有机器帐户。其次,如果 Samba 用作 Windows 服务器控制域的域成员服务器,则使用 ou=Idmap。最后一个新条目是 ou=NextFreeUnixId。此条目用于定义可用于创建新用户和组的下一个 UID 和 GID。

管理您的目录

在您的 LDAP 目录填充完毕并且 Samba 设置正确后,您就可以开始添加用户和组来填充您的目录了。Idealx 命令行实用程序可以很好地完成这项工作。一些基于 PHP 的目录管理器也可用,它们在这里也很有用。考虑使用 phpLDAPadmin 和/或 LDAP Account Manager (LAM) 来承担此任务。两者都很有帮助,提供了目录的图形化视图。每个工具还提供了在用户友好的图形环境中查看和编辑 LDAP 条目的能力(图 3)。基于 Java 的 LDAP 浏览器是查看和编辑目录的另一个选择。

OpenLDAP Everywhere Revisited

图 3. 使用 phpLDAPadmin 获取目录的 Web 视图。

自 2002 年 12 月的文章以来,我们看到了 Samba 3.x 版本的巨大改进。迁移到新版本应该意味着对帐户的更大控制和改进的组映射功能,从而使您能够更好地控制您的域。

维护

我们强烈建议您使用简单身份验证和安全层 (SASL) 和传输层安全 (TLS) 来保护您的新 LDAP 目录。有关详细信息,请参阅资源。

恭喜!您的 LDAP 服务器已启动并运行,具有共享电子邮件联系人、统一登录和可从任何客户端访问的共享文件存储。

本文资源: /article/8267

Craig Swanson (craig.swanson@midwest-tool.com) 在 SLS Solutions 设计网络并提供 Linux 咨询服务。他还在 Midwest Tool & Die 开发 Linux 软件。Craig 自 1993 年以来一直使用 Linux。

Matt Lung (matt.lung@midwest-tool.com) 在 SLS Solutions 提供网络和计算机系统咨询服务。他还在 Midwest Tool & Die 担任网络工程师。

加载 Disqus 评论