OpenLDAP 无处不在再探
许多读者曾使用我们在 2002 年 12 月发表的文章《OpenLDAP 无处不在》,实现了公司范围内的统一登录。自那时以来,OpenLDAP 和 Linux 都取得了进步。本文中,我们将演示如何使用 OpenLDAP 作为混合环境的核心目录服务。LDAP 服务器为所有客户端提供共享电子邮件目录、Linux 和 Microsoft Windows 客户端的登录、主目录的自动挂载和文件共享。本文示例中使用的简单混合环境如图 1 所示。
我们讨论的 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 命令进行测试。
接下来,我们配置 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 中输入哪些用户名。表 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 主域控制器所需的帐户。
用户登录条目通过登录名 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) 共享的单一主目录。我们从 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 客户端,您需要安装名称切换服务软件包 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
用户的密码和组条目必须从主目录所在的 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 结合使用的主要目的是为 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 目录中。这很有益,因为现在所有信息都存储在一个中心位置。
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 浏览器是查看和编辑目录的另一个选择。
自 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 担任网络工程师。