Product SiteDocumentation Site

11.7. LDAP 目录

OpenLDAP 是 LDAP 协议的应用;换句话说,它是设计来存储目录的特定功能数据库。在最通常的使用情况下,使用 LDAP 服务器允许集中管理用户账户和相关的权限。而且,LDAP 数据库复制容易,这允许设置多个同步的 LDAP 服务器。当网络和用户基础迅速增长时,负载然后会在几台服务器之间平衡。
LDAP 数据是结构化的并且分层级的。结构由“schemas(架构)”来确定,它使用了所有可能的属性列表,来描述数据库可以存储的对象的种类。用于指示数据库中特定对象的语法基于这个结构,它解释了其复杂性。

11.7.1. 安装

slapd 软件包包含 OpenLDAP 服务器。ldap-utils 软件包包括了与 LDAP 服务器交互的命令行工具。
安装 slapd 通常只询问管理员的密码,并且产生的数据库可能并不适合您的需求。幸运的是,简单的 dpkg-reconfigure slapd 将让您更具体地重新配置 LDAP 数据库:
  • 省略 OpenLDAP 服务器的配置?不,当然不,我们想要配置这个服务。
  • DNS 域名:“falcot.com”。
  • 组织名称:“Falcot Corp”。
  • 管理密码需要键入。
  • 数据库后端要使用:“MDB”。
  • 当清除 slapd 时想要删除数据库吗?不,没有必要在犯错误的情况下冒丢失数据库的风险。
  • 移动旧的数据库吗?只有在数据库已经存在而尝试进行配置的情况下才询问这个问题。如果真的想从干净的数据库重新开始时才能回答“是”,例如,如果刚好在初始安装后运行 dpkg-reconfigure slapd 的情况下。
现在配置了最小数据库,如后面的查询所说明的:
$ ldapsearch -x -b dc=falcot,dc=com
# extended LDIF
#
# LDAPv3
# base <dc=falcot,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# falcot.com
dn: dc=falcot,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Falcot Corp
dc: falcot

# admin, falcot.com
dn: cn=admin,dc=falcot,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
请求返回两个对象:组织自身和管理用户。

11.7.2. 填入目录

由于空数据库不特别有用,我们将所有现有目录注入其中;这包括用户、用户组、服务和主机数据库。
migrationtools 软件包提供一组脚本,专门用于从标准 Unix 目录中提取数据(/etc/passwd/etc/group/etc/services/etc/hosts 以及等等诸如此类),转换这个数据,并将其注入 LDAP 数据库中。
一旦安装了软件包,就必须编辑 /etc/migrationtools/migrate_common.ph;需要启用 IGNORE_UID_BELOWIGNORE_GID_BELOW 选项(将其取消注释就足够了),并且需要更新 DEFAULT_MAIL_DOMAIN/DEFAULT_BASE
真正的迁移操作由 migrate_all_online.sh 命令来处理,如下:
# cd /usr/share/migrationtools
# PERL5LIB="${PERL5LIB}:/etc/migrationtools" LDAPADD="/usr/bin/ldapadd -c" ETC_ALIASES=/dev/null ./migrate_all_online.sh
migrate_all_online.sh 询问一些关于数据迁移到 LDAP 数据库的问题。表 11.1 概括了 Falcot 公司的使用案例中给出回答。

表 11.1. 对 migrate_all_online.sh 脚本询问的问题的回答

问题回答
X.500 命名文本dc=falcot,dc=com
LDAP 服务器主机名localhost
管理者 DNcn=admin,dc=falcot,dc=com
绑定证明管理员密码
创建 DUAConfigProfile
You might notice that we extend the PERL5LIB variable. This is due to Debian bug report #982666.
As you might have also noticed, we deliberately ignore migration of the /etc/aliases file, since the standard schema as provided by Debian does not include the structures that this script uses to describe email aliases. Should we want to integrate this data into the directory, the /etc/ldap/schema/misc.schema file should be added to the standard schema.
还要注意 -c 选项在 ldapadd 命令中的使用;这个选项需要在错误的情况下不将处理停止下来。使用这个选项的使用是需要的,因为 /etc/services 的转换通常产生一些可以被安全地忽略的错误。

11.7.3. 使用 LDAP 管理账户

现在 LDAP 数据库包含了一些有用的信息,是时候使用这些数据了。这一节聚焦于如何配置 Linux 系统,从而各个系统目录可以使用 LDAP 数据库。

11.7.3.1. 配置 NSS

NSS 系统(Name Service Switch——名称服务交换,请参见边栏 进一步 NSS 与系统数据库)是个模块化的系统,设计来为系统目录确定或取回信息。使用 LDAP 作为 NSS 的数据源需要安装 libnss-ldap 软件包。它的安装会询问一些问题;回答概括在 表 11.2 中。

表 11.2. Configuring the libnss-ldap package:

问题回答
LDAP server URI (Uniform Resource Identifier)ldapi://ldap.falcot.com
搜索基础的区分名称dc=falcot,dc=com
使用的 LDAP 版本3
根的 LDAP 账户cn=admin,dc=falcot,dc=com
LDAP 根账户密码管理员密码
允许 LDAP 管理账户的行为像本地根用户一样吗?
LDAP 数据库需要登录吗?
然后需要修改 /etc/nsswitch.conf 文件,从而配置 NSS 来使用刚刚安装的 ldap 模块。可以使用 /usr/share/doc/libnss-ldap/examples/nsswitch.ldap 中提供的示例,或者编辑现有的配置。

例 11.23. The /etc/nsswitch.conf file

#ident $Id: nsswitch.ldap,v 2.4 2003/10/02 02:36:25 lukeh Exp $
#
# An example file that could be copied over to /etc/nsswitch.conf; it
# uses LDAP conjunction with files.
#
# "hosts:" and "services:" in this file are used only if the
# /etc/netconfig file has a "-" for nametoaddr_libs of "inet" transports.

# the following lines obviate the "+" entry in /etc/passwd and /etc/group.
passwd:         files ldap
shadow:         files ldap
group:          files ldap

# consult DNS first, we will need it to resolve the LDAP host. (If we
# can't resolve it, we're in infinite recursion, because libldap calls
# gethostbyname(). Careful!)
hosts:          dns ldap

# LDAP is nominally authoritative for the following maps.
services:   ldap [NOTFOUND=return] files
networks:   ldap [NOTFOUND=return] files
protocols:  ldap [NOTFOUND=return] files
rpc:        ldap [NOTFOUND=return] files
ethers:     ldap [NOTFOUND=return] files

# no support for netmasks, bootparams, publickey yet.
netmasks:   files
bootparams: files
publickey:  files
automount:  files

# I'm pretty sure nsswitch.conf is consulted directly by sendmail,
# here, so we can't do much here. Instead, use bbense's LDAP
# rules ofr sendmail.
aliases:    files
sendmailvars:   files

# Note: there is no support for netgroups on Solaris (yet)
netgroup:   ldap [NOTFOUND=return] files
ldap 模块通常插在其它之前,这样会被首先询问。显著的例外是 hosts 服务,因为联系 LDAP 服务器需要首先咨询 DNS (来解析 ldap.falcot.com)。没有这个例外的话,主机名查询将试图询问 LDAP 服务器;这会触发对 LDAP 服务器的名称解析,于是进入死循环。
如果 LDAP 服务器被认为是权威的(并且不理会 files 模块使用的本地文件),那么服务可以使用后面的语法来配置:
服务: ldap [NOTFOUND=return] files.
如果请求的入口在 LDAP 数据库中不存在,那么即使资源真实存在于一个本地文件中,查询也会返回“不存在”的回复;这些本地文件只当 LDAP 服务关闭时才会使用。

11.7.3.2. 配置 PAM

本节描述了 PAM 配置(请参见边栏 幕后/etc/environment/etc/default/locale),它允许应用针对 LDAP 数据库来执行所需要的授权。
用于 PAM 的 LDAP 模块由 libpam-ldap 软件包提供。安装这个软件包会询问一些问题,与 libnss-ldap 中的那些问题非常相似;一些配置参数(如 LDAP 服务器的 URI)甚至被 libnss-ldap 软件包真正共享。 回答概括在 表 11.3 中。

表 11.3. libpam-ldap 的配置

问题回答
允许 LDAP 管理账户的行为像本地根用户一样吗?是。这允许使用通常的 passwd 命令来更改存储在 LDAP 数据库中的密码。
LDAP 数据库需要登录吗?
LDAP account for root:cn=admin,dc=falcot,dc=com
LDAP administrative password:LDAP 数据库管理密码
Local encryption algorithm to use for passwords: crypt
PAM profiles to enable:LDAP Authentication is among the enabled profiles
安装 libpam-ldap 会自动适应 /etc/pam.d/common-auth/etc/pam.d/common-password/etc/pam.d/common-account 文件中的默认 PAM 配置。这个机制使用专用的 pam-auth-update 工具(由 libpam-runtime 软件包提供)。这个工具还可以由管理员运行,如果他们想要启用或禁止 PAM 模块的话。

11.7.3.3. 保护 LDAP 数据交换

LDAP 协议默认在网络上明文传输;这包括(加密的)密码。由于加密的密码可以从网络上提取,它们对字典类型的攻击会是脆弱的。这可以通过使用另外的加密层来避免;启用这层是本节的主题。
11.7.3.3.1. 配置服务器
第一步是为 LDAP 服务器创建密钥对(包括公钥和私钥)。Falcot 公司的管理员重复使用 easy-rsa 来生成它(请参见 第 10.2.2 节 “公钥基础设施:easy-rsa)。运行 ./easyrsa build-server-full ldap.falcot.com nopass 会询问有关“通用名称”。对问题的回答必须是 LDAP 服务器完全合格的主机名;在我们的例子中是 ldap.falcot.com
这个命令在 pki/issued/ldap.falcot.com.crt 文件中创建了证书;相应的私钥存储在 pki/private/ldap.falcot.com.key 中。
现在这些密钥必须安装到其标准位置上,并且我们必须确定私有文件可以被openldap身份下运行的 LDAP 服务器读取:
# adduser openldap ssl-cert
Adding user `openldap' to group `ssl-cert' ...
Adding user openldap to group ssl-cert
Done.
# mv pki/private/ldap.falcot.com.key /etc/ssl/private/ldap.falcot.com.key
# chown root.ssl-cert /etc/ssl/private/ldap.falcot.com.key
# chmod 0640 /etc/ssl/private/ldap.falcot.com.key
# mv pki/issued/ldap.falcot.com.crt /etc/ssl/certs/ldap.falcot.com.pem
# chown root.root /etc/ssl/certs/ldap.falcot.com.pem
# chmod 0644 /etc/ssl/certs/ldap.falcot.com.pem
还需要告知 slapd 守护进程使用这些密钥来加密。LDAP 服务器的配置被动态地管理:可以在 cn=config 对象层次结构上通过正常的 LDAP 操做来更新配置;并且服务器实时更新 /etc/ldap/slapd.d 而使配置持续。这样 ldapmodify 就是更新配置的合适工具了:

例 11.24. 配置 slapd 来加密

# cat >ssl.ldif <<END
dn: cn=config
changetype: modify
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap.falcot.com.key
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap.falcot.com.pem
END
# ldapmodify -Y EXTERNAL -H ldapi:/// -f ssl.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
# systemctl restart slapd.service
# ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config -s base | grep TLS
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
olcTLSCertificateFile: /etc/ssl/certs/ldap.falcot.com.pem
olcTLSCertificateKeyFile: /etc/ssl/certs/ldap.falcot.com.key
启用加密的最后一步包括更改 /etc/default/slapd 文件中的 SLAPD_SERVICES 变量。我们将同时安全地运行并禁止不安全 LDAP。

例 11.25. /etc/default/slapd 文件

# Default location of the slapd.conf file or slapd.d cn=config directory. If
# empty, use the compiled-in default (/etc/ldap/slapd.d with a fallback to
# /etc/ldap/slapd.conf).
SLAPD_CONF=

# System account to run the slapd server under. If empty the server
# will run as root.
SLAPD_USER="openldap"

# System group to run the slapd server under. If empty the server will
# run in the primary group of its user.
SLAPD_GROUP="openldap"

# Path to the pid file of the slapd server. If not set the init.d script
# will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.d by
# default)
SLAPD_PIDFILE=

# slapd normally serves ldap only on all TCP-ports 389. slapd can also
# service requests on TCP-port 636 (ldaps) and requests via unix
# sockets.
# Example usage:
# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
SLAPD_SERVICES="ldaps:/// ldapi:///"

# If SLAPD_NO_START is set, the init script will not start or restart
# slapd (but stop will still work).  Uncomment this if you are
# starting slapd via some other means or if you don't want slapd normally
# started at boot.
#SLAPD_NO_START=1

# If SLAPD_SENTINEL_FILE is set to path to a file and that file exists,
# the init script will not start or restart slapd (but stop will still
# work).  Use this for temporarily disabling startup of slapd (when doing
# maintenance, for example, or through a configuration management system)
# when you don't want to edit a configuration file.
SLAPD_SENTINEL_FILE=/etc/ldap/noslapd

# For Kerberos authentication (via SASL), slapd by default uses the system
# keytab file (/etc/krb5.keytab).  To use a different keytab file,
# uncomment this line and change the path.
#export KRB5_KTNAME=/etc/krb5.keytab

# Additional options to pass to slapd
SLAPD_OPTIONS=""
11.7.3.3.2. 配置客户端
在客户端一侧,需要修改用于 libpam-ldaplibnss-ldap 模块的配置,来使用 ldaps:// URI。
LDAP clients also need to be able to authenticate the server. In an X.509 public key infrastructure, public certificates are signed by the key of a certificate authority (CA). With easy-rsa, the Falcot administrators have created their own CA and they now need to configure the system to trust the signatures of Falcot's CA. This can be done by putting the CA certificate in /usr/local/share/ca-certificates and running update-ca-certificates.
# cp pki/ca.crt /usr/local/share/ca-certificates/falcot.crt
# update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

Adding debian:falcot.pem
done.
done.
最后但不是最重要的,各种命令行工具使用的默认 LDAP URI 和默认基础 DN可以在 /etc/ldap/ldap.conf 中修改。这会节省一些输入工作。

例 11.26. /etc/ldap/ldap.conf 文件

#
# LDAP Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-provider.example.com:666

#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never

# TLS certificates (needed for GnuTLS)
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt