原文地址:https://help.ubuntu.com/14.04/serverguide/openldap-server.html
轻量目录访问协议(LDAP),是一个运行在TCP/IP协议的查询和修改基于X.500目录服务的协议。当前LDAP的版本为LDAPv3,定义在RFC4510中,在Ubuntu中的实现是OpenLDAP。
所以LDAP协议访问LDAP目录,这里有一些主要的概念和说明:
object, container, 和 node这些属于有一定自己的含义,但是基本上和entry在技术上描述的是同一个东西。
例如,下面我们有一个真实的条目,它由11个属性组成:
dn: cn=John Doe,dc=example,dc=com
cn: John Doe
givenName: John
sn: Doe
telephoneNumber: +1 888 555 6789
telephoneNumber: +1 888 555 1232
mail: [email protected]
manager: cn=Larry Smith,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
以上是LDIF格式(LDAP数据交换格式)的条目。任何你想要传输进你的DIT(目录信息树)的信息也必须是这样的格式。它被定义在RFC2849。
虽然本指南将介绍如何使用它做中央认证,但是在涉及到大量读请求、基于属性(name:value)的后端应用他都很不错。例子包括一个地址簿,一个电子邮件地址列表,和一个邮件服务器的配置。
分别使用slapd和ldap-utils包,来安装OpenLDAP服务进程和传统的LDAP管理工具。
slapd的安装会创建一个工作设置。特别地,它将创建一个数据库实体用来存储你的数据。但是,这个实例的后缀(或者叫base DN)将被定义成主机的域名。如果你想它不一样,配置/etc/hosts并把域名替换成你想要的后缀名。比如,如果你想要后缀名是dc=example,dc=com,那么你的host文件应该像这样:
127.0.1.1 hostname.example.com hostname
你可以恢复这些修改,在包安装之后。
这次的指导将会使用dc=example,dc=com这个数据库后缀。
继续安装:
sudo apt-get install slapd ldap-utils
从Ubuntu 8.10开始,slapd被设计成在他内部配置,通过建立一个独立DIT(目录信息树)的来达到这个目的。这就使得我们可以动态地配置slapd而不需要重启服务。配置数据库由一系列在/etc/ldap/slapd.d文件夹下的LDIF文本文件组成。这种工作方式有好几种名字: slapd-config方式、RTC方式(Real Time Configuration)、或者cn=config方式。你可以仍然实用传统的flat-file方式(slapd.conf)但是不推荐你这样。这个功能最后将被淘汰。
tips:Ubuntu 现在使用slapd-config的方式来配置slapd,本指南同样使用。
在安装的过程中,你将被提示定义管理凭证。这些是你数据库实体的rootDN的LDAP-based凭证。默认情况下,用户的DN是cn=admin,dc=example,dc=com。当然,默认地不会为slapd-config数据库创建管理帐号。所以你需要从外部认证LDAP来访问它。我们在接下来的文章中将展示如何做这个认证。
现在一些经典的schemas(cosine, nis, inetorgperson)被内置在slapd中。包括“core”schema,它是其他任何schema工作的先决条件。
安装过程需要设置两个DIT。一个是slapd-config另一个是你自己的数据(dc=example,dc=com)。让我们来看看。
slapd-config数据库/DIT看起来像这样。回想一下,这个数据库是LDIF-based的,并且在/etc/ldap/slapd.d文件夹下:
/etc/ldap/slapd.d/
/etc/ldap/slapd.d/cn=config
/etc/ldap/slapd.d/cn=config/cn=module{0}.ldif
/etc/ldap/slapd.d/cn=config/cn=schema
/etc/ldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif
/etc/ldap/slapd.d/cn=config/cn=schema/cn={1}cosine.ldif
/etc/ldap/slapd.d/cn=config/cn=schema/cn={2}nis.ldif
/etc/ldap/slapd.d/cn=config/cn=schema/cn={3}inetorgperson.ldif
/etc/ldap/slapd.d/cn=config/cn=schema.ldif
/etc/ldap/slapd.d/cn=config/olcBackend={0}hdb.ldif
/etc/ldap/slapd.d/cn=config/olcDatabase={0}config.ldif
/etc/ldap/slapd.d/cn=config/olcDatabase={-1}frontend.ldif
/etc/ldap/slapd.d/cn=config/olcDatabase={1}hdb.ldif
/etc/ldap/slapd.d/cn=config.ldif
tips:不要直接修改slapd-config数据库。通过LDAP协议(工具)修改。
通过LDAP协议,slapd-config DIT看起来像这样:
注意,在Ubuntu服务器14.10或更高的版本,这个命令可能不能使用了,因为这个bug。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
dn: cn=config
dn: cn=module{0},cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: olcBackend={0}hdb,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}hdb,cn=config
这些条目的解释:
cn=config: 全局设置
cn=module{0},cn=config: a dynamically loaded module
cn=schema,cn=config: contains hard-coded system-level schema
cn={0}core,cn=schema,cn=config: the hard-coded core schema
cn={1}cosine,cn=schema,cn=config: the cosine schema
cn={2}nis,cn=schema,cn=config: the nis schema
cn={3}inetorgperson,cn=schema,cn=config: the inetorgperson schema
olcBackend={0}hdb,cn=config: the ‘hdb’ backend storage type
olcDatabase={-1}frontend,cn=config: frontend database, default settings for other databases
olcDatabase={0}config,cn=config: slapd configuration database (cn=config)
olcDatabase={1}hdb,cn=config: your database instance (dc=examle,dc=com)
dc=example,dc=com DIT看起来像这样:
ldapsearch -x -LLL -H ldap:/// -b dc=example,dc=com dn
dn: dc=example,dc=com
dn: cn=admin,dc=example,dc=com
实体的解释:
让我们介绍下我们的的数据库的内容。我们将加入如下内容:
1. 一个叫做People的节点(用来存放users)
2. 一个叫做Group的节点(用来存放groups)
3. 一个组叫做miners
4. 一个用户叫做john
创建下面的LDIF文件,并叫做add_content.ldif:
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
dn: cn=miners,ou=Groups,dc=example,dc=com
objectClass: posixGroup
cn: miners
gidNumber: 5000
dn: uid=john,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: john
sn: Doe
givenName: John
cn: John Doe
displayName: John Doe
uidNumber: 10000
gidNumber: 5000
userPassword: johnldap
gecos: John Doe
loginShell: /bin/bash
homeDirectory: /home/john
tips:在你的目录中的uid和gid的值不与本地值冲突是很重要的。使用比较高的数值范围,比如从5000开始。通过在ldap中设置较高的uid和gid值,允许你更容易地控制本地用户和ldap用户。后面有更多关于它的内容。
添加内容:
ldapadd -x -D cn=admin,dc=example,dc=com -W -f add_content.ldif
Enter LDAP Password: ********
adding new entry "ou=People,dc=example,dc=com"
adding new entry "ou=Groups,dc=example,dc=com"
adding new entry "cn=miners,ou=Groups,dc=example,dc=com"
adding new entry "uid=john,ou=People,dc=example,dc=com"
你使用ldapsearch功能检查这些信息是否正确:
ldapsearch -x -LLL -b dc=example,dc=com 'uid=john' cn gidNumber
dn: uid=john,ou=People,dc=example,dc=com
cn: John Doe
gidNumber: 5000
开关的解释:
-x: “simple” binding; will not use the default SASL method
-LLL: disable printing extraneous information
uid=john: a “filter” to find the john user
cn gidNumber: requests certain attributes to be displayed (the default is to show all attributes)
slapd-config DIT(目录信息数)可以被查询和修改。下面是一些例子。
使用ldapmodify 添加一个”Index” 给你的{1}hdb,cn=config 数据库(dc=example,dc=com)。用以下内容创建一个文件,取名叫uid_index.ldif:
dn: olcDatabase={1}hdb,cn=config
add: olcDbIndex
olcDbIndex: uid eq,pres,sub
然后执行下面的命令:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f uid_index.ldif
modifying entry "olcDatabase={1}hdb,cn=config"
你可以用以下方式确认变化:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcDatabase={1}hdb)' olcDbIndex
dn: olcDatabase={1}hdb,cn=config
olcDbIndex: objectClass eq
olcDbIndex: uid eq,pres,sub
让我们添加一个schema.它首先需要转换为ldif格式。你可以在/etc/ldap/schema目录中找到除了已经被转换的schemas还有未被转换的schemas。
- 通常不要从slapd-config数据库删除schema。在测试系统增加一个schemas进行练习。
在增加任何schema之前,你应该检查哪些schemas已经被安装了(显示是一个默认的输出框的输出)。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=schema,cn=config dn
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
创建转换配置文件schema_convert.conf包含下面的行:
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/collective.schema
include /etc/ldap/schema/corba.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/duaconf.schema
include /etc/ldap/schema/dyngroup.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/java.schema
include /etc/ldap/schema/misc.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/openldap.schema
include /etc/ldap/schema/ppolicy.schema
include /etc/ldap/schema/ldapns.schema
include /etc/ldap/schema/pmi.schema
定义schema的index:
slapcat -f schema_convert.conf -F ldif_output -n 0 | grep corba,cn=schema
cn={1}corba,cn=schema,cn=config
tips:当slapd提取相同父DN的对象时。它会创建对象的index,index包含在括弧中:{x}。
使用slapcat来执行转换:
slapcat -f schema_convert.conf -F ldif_output -n0 -H \
ldap:///cn={1}corba,cn=schema,cn=config -l cn=corba.ldif
转换后的schema现在在cn=corba.ldif中。
编辑Edit cn=corba.ldif来达到以下的属性:
dn: cn=corba,cn=schema,cn=config
...
cn: corba
同时移除底下的如下所示的行:
structuralObjectClass: olcSchemaConfig
entryUUID: 52109a02-66ab-1030-8be2-bbf166230478
creatorsName: cn=config
createTimestamp: 20110829165435Z
entryCSN: 20110829165435.935248Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20110829165435Z
你的属性值可能有不同。
最后,使用ldapadd功能添加新的schema到slapd-config DIT:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f cn\=corba.ldif
adding new entry "cn=corba,cn=schema,cn=config"
确认现在被加载的schemas:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: cn={4}corba,cn=schema,cn=config
外部应用程序和客户端使用LDAP进行身份验证,都需要特别的配置。详细内容请参考合适的客户端文档。
当实施一个基于OpenLDAP的解决方案时,为slapd做日志的活动是很有必要的,但是,它需要在软件安装之后手动启动。否则,只有基本的信息将会出现在log中,就像其他slapd配置,它可以通过slapd-config数据库启动。
OpenLDAP有许多日志子系统(级别),每个级别都包含较弱级别的内容(递增的)。一个好的级别尝试是stats。在slapd-config主页上有关于各个级别的更详细的说明。
创建logging.ldif文件,包含下面内容:
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
实施这个改变:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f logging.ldif
一旦你的系统在生产环境中,这将会产生大量的日志,你将会想要回到一个更少日志的级别。当你在这种冗长的模式中,你的主机日志引擎(rsyslog)可能会比较难维持,并且可能丢失信息。
rsyslogd-2177: imuxsock lost 228 messages from pid 2547 due to rate-limiting
你将考虑修改rsyslog的配置。在/etc/rsyslog.conf中,输入:
# Disable rate limiting
# (default is 200 messages in 5 seconds; below we make the 5 become 0)
$SystemLogRateLimitInterval 0
然后重启rsyslog进程:
sudo service rsyslog restart
LDAP服务变得越来越重要,是因为更多的网络系统开始依赖它。在这样的环境中,一个标准的实践是在LDAP中建立冗余(高可用)来防止LDAP服务器变得不可响应带来的浩劫。这通过LDAP复制(replication)来实现。
复制通过Syncrepl引擎完成。这允许使用消费者/生产者模型同步更改。我们将在这次指南中实施的这种特殊方式的备份是下面模式的组合:refreshAndPersist和delta-syncrepl。每当修改产生时,生产者就会推送修改实体给消费者,但是,只有实际的修改才会被发送,而不是所有的实体。
从配置提供者开始。
创建一个包含以下内容的LDIF文件,并命名为provider_sync.ldif:
# Add indexes to the frontend db.
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: entryCSN eq
-
add: olcDbIndex
olcDbIndex: entryUUID eq
#Load the syncprov and accesslog modules.
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: syncprov
-
add: olcModuleLoad
olcModuleLoad: accesslog
# Accesslog database definitions
dn: olcDatabase={2}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {2}hdb
olcDbDirectory: /var/lib/ldap/accesslog
olcSuffix: cn=accesslog
olcRootDN: cn=admin,dc=example,dc=com
olcDbIndex: default eq
olcDbIndex: entryCSN,objectClass,reqEnd,reqResult,reqStart
# Accesslog db syncprov.
dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpNoPresent: TRUE
olcSpReloadHint: TRUE
# syncrepl Provider for primary db
dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpNoPresent: TRUE
# accesslog overlay definitions for primary db
dn: olcOverlay=accesslog,olcDatabase={1}hdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcAccessLogConfig
olcOverlay: accesslog
olcAccessLogDB: cn=accesslog
olcAccessLogOps: writes
olcAccessLogSuccess: TRUE
# scan the accesslog DB every day, and purge entries older than 7 days
olcAccessLogPurge: 07+00:00 01+00:00
在文件中修改rootDN来匹配你的目录的rootDN。
slapd的apparmor文件将不需要为访问日志数据库做调整,当/etc/apparmor.d/local/usr.sbin.slapd中包含 :
/var/lib/ldap/ r,
/var/lib/ldap/** rwk,
创建一个目录,设置一个数据库配置文件,并重新载入apparmor文件:
sudo -u openldap mkdir /var/lib/ldap/accesslog
sudo -u openldap cp /var/lib/ldap/DB_CONFIG /var/lib/ldap/accesslog
sudo service apparmor reload
由于apparmor改变,增加新的内容,并重启进程:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f provider_sync.ldif
sudo service slapd restart
现在,提供者配置好了。
现在,配置消费者。
安装软件,参考上面的安装部分。保证slapd-config数据库和提供者的是相同的。特别的,确保schemas和数 据库后缀相同。
创建一个LDIF文件包含如下内容,并命名为consumer_sync.ldif:
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: syncprov
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: entryUUID eq
-
add: olcSyncRepl
olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=admin,dc=example,dc=com"
credentials=secret searchbase="dc=example,dc=com" logbase="cn=accesslog"
logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on
type=refreshAndPersist retry="60 +" syncdata=accesslog
-
add: olcUpdateRef
olcUpdateRef: ldap://ldap01.example.com
保证下面的属性拥有正确的值:
provider (Provider服务器的名字 – ldap01.example.com 在本例中中 – 或者IP地址)
binddn (你正在使用的管理员DN)
credentials (管理员DN的密码)
searchbase (数据库后缀)
olcUpdateRef (Provider服务器的主机名或者ip地址)
rid (复制ID, 一个唯一的3为标志来区别这个复制。每个消费者都应该至少有一个rid)
增加新的内容:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f consumer_sync.ldif
完成,现在两个数据库应该是同步的(后缀:dc=example,dc=com)。
一旦复制开始,你就可以监视它,通过运行:
ldapsearch -z1 -LLLQY EXTERNAL -H ldapi:/// -s base -b dc=example,dc=com contextCSN
dn: dc=example,dc=com
contextCSN: 20120201193408.178454Z#000000#000#000000
在提供者和消费者两端。一旦输出(20120201193408.178454Z#000000#000#000000 in the above example) 两边 的机器都匹配的话,就表示复制成功了。每次在提供者端数据改变,在消费者端会做出相同的改变。
如果你的连接比较慢,或者(并且)你的ldap数据库比较大的话,消费者的contextCSN匹配提供者,可能需要花 费一点的时间。但是你将会知道它正在运行,因为消费者的contextCSN将会稳定增长。
一旦消费者的contextCSN丢失,或者没有匹配提供者,你应该在继续前停止并找出问题。尝试检查消费者主机的 slapd(日志)和用户的日志文件,查看是不是消费者的认证成功了或者它的请求数据的请求(他们看起来像很 多ldapsearch报表)没有错误。
用户应该被赋予什么样的权限(读,写等等)的管理被称为访问控制。被涉及的配置指令被称为访问控制列表或者ACL。
当我们安装slapd包时,各种ACL已经被自动地设置。我们将看一些重要的默认配置,这样做,我们将知道ACL是怎么工作的和我们是如何配置的。
为了获得一个有效的LDAP查询使用的ACL,我们需要查看被查询的数据库的ACL实体以及那些特殊的前端数据库实例。ACL属于后者作为默认值,假使前者不匹配。前端数据库是第二个被咨询的,并且在两个ACL资源中将被应用的ACL是第一个匹配项(先匹配的生效)。下面的命令将各自给hdb数据库 (“dc=example,dc=com”)的ACL和那些前端数据库。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcDatabase={1}hdb)' olcAccess
dn: olcDatabase={1}hdb,cn=config
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous
auth by dn="cn=admin,dc=example,dc=com" write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by self write by dn="cn=admin,dc=example,dc=com" write by *
read
tips:rootDN总是拥有对他的数据库的所有权限。在ACL中包含它确实提供了一个明确的配置,但是它也造成slapd引起性能的损失。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcDatabase={-1}frontend)' olcAccess
dn: olcDatabase={-1}frontend,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,
cn=external,cn=auth manage by * break
olcAccess: {1}to dn.exact="" by * read
olcAccess: {2}to dn.base="cn=Subschema" by * read
最先的ACL是至关重要的:
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous
auth by dn="cn=admin,dc=example,dc=com" write by * none
为了更容易消化这可能有不同的表现:
to attrs=userPassword
by self write
by anonymous auth
by dn="cn=admin,dc=example,dc=com" write
by * none
to attrs=shadowLastChange
by self write
by anonymous auth
by dn="cn=admin,dc=example,dc=com" write
by * none
这个混合的ACL(有两个)强制了下面:
发生初始链接时,匿名认证访问被userPassword属性提供。也许是反直觉的,‘匿名认证’是需要的即使你们访问DIT不需要。一旦远程终端连接,认证就会发生(见下一点)。
认证可以发生是因为用户对userPasword属性有读(因为“被自己写”)的权限。
userPassword属性对其他用户来说是没必要的,除了rootDN,它对这个属性有完全的权限。
为了让用户更改自己的密码,使用passwd或其他功能,shadowlastchange属性需要可访问一旦用户被认证。
DIT可以被匿名搜索因为在ACL中的”read”:
to *
by self write
by dn="cn=admin,dc=example,dc=com" write
by * read
如果这是不必要的那么你需要更改ACL。你可以选择性地(或与修改的ACL组合)使用 ‘olcRequire: authc’指令来在绑定请求时强制认证。
如前所述,没有为slapd-config数据库创建管理账户。但是,有一个SASL身份被授予权限完全访问它。它代表了本地主机的超级用户(root/sudo)。它在这儿:
dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
下面的命令将显示slapd-config数据库的ACL:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcDatabase={0}config)' olcAccess
dn: olcDatabase={0}config,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,
cn=external,cn=auth manage by * break
由于这是一个SASL身份,当调用考虑中的LDAP的工具时,我们需要使用SASL机制,并且我们在这本指南中看到它很多次。它是EXTERNAL机制。查看前面的命令作为一个例子。请注意:
一个简洁的方式来获得所有的ACL是这样的:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcAccess=*)' olcAccess olcSuffix
关于访问控制的话题有很多话要说。请看slapd.access手册页。
当对一个OpenLDAP服务器认证时,最好使用一个加密的session。这里可以使用传输层安全(TLS)来完成。
这里我们将是我们自己的证书颁发机构,如何创建并签署我们自己的LDAP服务器证书,叫做CA。由于slapd使用gnutls库进行编译,我们将使用certtool工具来完成这些任务。
安装gnutls-bin和ssl-cert包:
sudo apt-get install gnutls-bin ssl-cert
为证书颁发机构创建私钥:
sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
创建临时文件/etc/ssl/ca.info来定义CA:
cn = Example Company
ca
cert_signing_key
创建自己认证的CA证书:
sudo certtool --generate-self-signed \
--load-privkey /etc/ssl/private/cakey.pem \
--template /etc/ssl/ca.info \
--outfile /etc/ssl/certs/cacert.pem
为服务器创建一个私钥:
sudo certtool --generate-privkey \
--bits 1024 \
--outfile /etc/ssl/private/ldap01_slapd_key.pem
把文件名中的ldap01换成你的服务器名。使用主机和服务来命名证书和密钥对你清晰地使用它们会很有帮助。
创建/etc/ssl/ldap01.info信息文件包含:
organization = Example Company
cn = ldap01.example.com
tls_www_server
encryption_key
signing_key
expiration_days = 3650
上述证书10年比较好,根据需要调整。
创建服务器证书
sudo certtool --generate-certificate \
--load-privkey /etc/ssl/private/ldap01_slapd_key.pem \
--load-ca-certificate /etc/ssl/certs/cacert.pem \
--load-ca-privkey /etc/ssl/private/cakey.pem \
--template /etc/ssl/ldap01.info \
--outfile /etc/ssl/certs/ldap01_slapd_cert.pem
创建certinfo.ldif文件包含下面的内容(根据需要调整,我们的示例假设我们创建的证书使用https://www.cacert.org)
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap01_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap01_slapd_key.pem
使用ldapmodify命令来告诉slapd关于我们的TLS通过slapd-config数据库:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ssl/certinfo.ldif
与常识相反,你在/etc/default/slapd不需要ldaps://来使用加密,你只需要:
SLAPD_SERVICES="ldap:/// ldapi:///"
在TLS/SSL(ldaps://)上的LDAP反对支持StartTLS。后者关于一个存在的LDAP会话(监听在TCP 389端口)被TLS/SSL保护。 相反LDAPS,和HTTPS类似,是一个明确一开始就被加密的协议,它运行在TCP636端口。
加强所有权和权限:
sudo adduser openldap ssl-cert
sudo chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem
sudo chmod g+r /etc/ssl/private/ldap01_slapd_key.pem
sudo chmod o-r /etc/ssl/private/ldap01_slapd_key.pem
重启OpenLDAP:
sudo service slapd restart
检查你的主机日志(/var/log/syslog)看看是不是服务器正常启动了。
如果你已经在两个服务器之间配置了复制,常见的做法是在复制传输间加密来防止偷听。这和我们上面所做的使用认证加密是不同的。这节中我们将建立在TLS认证工作。
这里我们假设你已经设置了消费者和提供者之间的复制,通过“复制”章节,并且配置了TLS认证在提供者,通过“TLS”章节。
如前所述,复制的目的是LDAP服务的高可用。既然我们在提供者上有TLS认证,那么我们要求消费者同样拥有。除此之外,但是,我们希望对复制流进行加密。仍然要做的是为消费者创建一个密钥和证书,然后相应地配置。我们将在提供者上生成密钥/证书,以避免必须创建另一个证书,然后将必要的材料转移到消费者。
在提供者上,创建一个持久的目录(这将用于可能的传输)和消费者私钥:
mkdir ldap02-ssl
cd ldap02-ssl
sudo certtool --generate-privkey \
--bits 1024 \
--outfile ldap02_slapd_key.pem
创建一个信息文件,ldap02.info,为消费者服务器,根据需求修改它的值:
organization = Example Company
cn = ldap02.example.com
tls_www_server
encryption_key
signing_key
expiration_days = 3650
创建消费者证书:
sudo certtool --generate-certificate \
--load-privkey ldap02_slapd_key.pem \
--load-ca-certificate /etc/ssl/certs/cacert.pem \
--load-ca-privkey /etc/ssl/private/cakey.pem \
--template ldap02.info \
--outfile ldap02_slapd_cert.pem
复制CA证书:
cp /etc/ssl/certs/cacert.pem .
完成,现在把ldap02-ssl目录传输给消费者。这里我们使用scp(根据需要调整):
cd ..
scp -r ldap02-ssl user@consumer:
在消费者上,配置TLS认证:
sudo apt-get install ssl-cert
sudo adduser openldap ssl-cert
sudo cp ldap02_slapd_cert.pem cacert.pem /etc/ssl/certs
sudo cp ldap02_slapd_key.pem /etc/ssl/private
sudo chgrp ssl-cert /etc/ssl/private/ldap02_slapd_key.pem
sudo chmod g+r /etc/ssl/private/ldap02_slapd_key.pem
sudo chmod o-r /etc/ssl/private/ldap02_slapd_key.pem
创建文件 /etc/ssl/certinfo.ldif包含下面内容(根据需要调整):
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap02_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap02_slapd_key.pem
配置slapd-config数据库:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif
配置 /etc/default/slapd 作为提供者(SLAPD_SERVICES)。
在消费者上,为Consumer-side复制配置TLS。通过在一些TLS选项上增加的方式修改现有的olcSyncrepl属性。在这样做时,我们将看到,第一次,如何改变属性的值。
创建consumer_sync_tls.ldif文件包含下面内容:
dn: olcDatabase={1}hdb,cn=config
replace: olcSyncRepl
olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple
binddn="cn=admin,dc=example,dc=com" credentials=secret searchbase="dc=example,dc=com"
logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))"
schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog
starttls=critical tls_reqcert=demand
额外的选项指定,分别地,消费者必须使用StartTLS,并且CA证书是需要的来核实提供者的省份。同时改变(‘替代’)属性值的时候注意LDIF语法。
实施这些改变:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f consumer_sync_tls.ldif
并且重启slapd:
sudo service slapd restart
在提供者上,检查TLS会话是不是已经被建立。在/var/log/syslog中,提供你的’conns’-level日志设置,你应该看到类似如下的消息:
slapd[3620]: conn=1047 fd=20 ACCEPT from IP=10.153.107.229:57922 (IP=0.0.0.0:389)
slapd[3620]: conn=1047 op=0 EXT oid=1.3.6.1.4.1.1466.20037
slapd[3620]: conn=1047 op=0 STARTTLS
slapd[3620]: conn=1047 op=0 RESULT oid= err=0 text=
slapd[3620]: conn=1047 fd=20 TLS established tls_ssf=128 ssf=128
slapd[3620]: conn=1047 op=1 BIND dn="cn=admin,dc=example,dc=com" method=128
slapd[3620]: conn=1047 op=1 BIND dn="cn=admin,dc=example,dc=com" mech=SIMPLE ssf=0
slapd[3620]: conn=1047 op=1 RESULT tag=97 err=0 text
一旦你有了一个工作的LDAP服务器,你将需要安装一下包在客户端,那样将会知道如何和什么时候去连接它。在Ubuntu,一般通过安装libnss-ldap包来完成。这个包将会带来其他工具,它会在配置步骤中帮助你。现在安装这个包:
sudo apt-get install libnss-ldap
你将会被提示输入你的LDAP服务器细节。如果你发生错误,你可以重新试试,使用:
sudo dpkg-reconfigure ldap-auth-config
对话的结果可以在/etc/ldap.conf中看见。如果你的服务要求的选项没有被覆盖在菜单中,根据需要编辑下面的文件。
现在为NSS配饰LDAP文件:
sudo auth-client-config -t nss -p lac_ldap
使用LDAP为认证配置系统:
sudo pam-auth-update
选择LDAP和其他你需要的认证机制在菜单上。
你现在应该能够登录使用基于LDAP的凭据。LDAP客户端将需要关联到多个服务器如果复制使用的话。在/etc/ldap.conf中,你应该有些东西像这样:
uri ldap://ldap01.example.com ldap://ldap02.example.com
请求将会超时并且消费者(ldap02)将会尝试连接,如果提供者(ldap01)变得不响应的话。
如果你将使用LDAP来存samba用户,你将需要配置samba服务器来使用LDAP认证。详情查看Samba and LDAP。
tips:一个libnss-ldap包可替代的包是libnss-ldapd包,这,但是,会引入nscd包,它可能并不需要,直接移除它就可以了。
LDAP工具包来提供足够的工具来管理目录,但是选项所需的长字符串,给他们的使用带来了负担。ldapscripts包中包含了对这些功能的封装脚本,人们找到并使用它们更容易了。
安装这个包:
sudo apt-get install ldapscripts
然后编辑文件/etc/ldapscripts/ldapscripts.conf达到类似下面:
SERVER=localhost
BINDDN='cn=admin,dc=example,dc=com'
BINDPWDFILE="/etc/ldapscripts/ldapscripts.passwd"
SUFFIX='dc=example,dc=com'
GSUFFIX='ou=Groups'
USUFFIX='ou=People'
MSUFFIX='ou=Computers'
GIDSTART=10000
UIDSTART=10000
MIDSTART=10000
现在,创建ldapscripts.passwd文件允许rootdn访问目录:
sudo sh -c "echo -n 'secret' > /etc/ldapscripts/ldapscripts.passwd"
sudo chmod 400 /etc/ldapscripts/ldapscripts.passwd
tips: 使用你的数据库的rootDN用户的真实的密码替换‘secret’。
脚本现在已经准备好帮助管理您的目录。这里有一些如何使用它们的例子:
创建一个新用户:
sudo ldapadduser george example
这将使用uid george创建一个用户并且设置用户的初始组(gid)为example。
修改用户密码:
sudo ldapsetpasswd george
Changing password for user uid=george,ou=People,dc=example,dc=com
New Password:
New Password (verify):
删除一个用户
sudo ldapdeleteuser george
增加一个组:
sudo ldapaddgroup qa
删除一个组:
sudo ldapdeletegroup qa
在组中增加一个用户:
sudo ldapaddusertogroup george qa
你现在应该看见一个qa组的memberUid属性值为george。
在组中移除一个用户:
sudo ldapdeleteuserfromgroup george qa
现在memberUid属性现在应该已经从qa组中被移除。
ldapmodifyuser脚本允许你增加,删除或者替换一个用户的属性。脚本使用和ldapmodify工具相同的语法,比如:
sudo ldapmodifyuser george
# About to modify the following entry :
dn: uid=george,ou=People,dc=example,dc=com
objectClass: account
objectClass: posixAccount
cn: george
uid: george
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/george
loginShell: /bin/bash
gecos: george
description: User account
userPassword:: e1NTSEF9eXFsTFcyWlhwWkF1eGUybVdFWHZKRzJVMjFTSG9vcHk=
# Enter your modifications here, end with CTRL-D.
dn: uid=george,ou=People,dc=example,dc=com
replace: gecos
gecos: George Carlin
用户的gecos现在应该是“George Carlin”。
ldapscripts的一个好的特征是模板系统。模板允许你自定义用户,组和机器对象的属性。例如: 编辑/etc/ldapscripts/ldapscripts.conf改变来启用用户模板:
UTEMPLATE="/etc/ldapscripts/ldapadduser.template"
有sample模板在/usr/share/doc/ldapscripts/examples目录。复制或重命名ldapadduser.template.sample文件为/etc/ldapscripts/ldapadduser.template:
sudo cp /usr/share/doc/ldapscripts/examples/ldapadduser.template.sample \
/etc/ldapscripts/ldapadduser.template
编辑新模板以添加所需的属性。下面将创建一个inetOrgPerson对象类的新用户:
dn: uid=,,
objectClass: inetOrgPerson
objectClass: posixAccount
cn:
sn:
uid:
uidNumber:
gidNumber:
homeDirectory:
loginShell:
gecos:
description: User account
title: Employee
注意在sn属性上被使用的选项。它将使ldapadduser提示你输入它的值。
包中还有没有被覆盖的工具,这里是完整地列表:
ldaprenamemachine
ldapadduser
ldapdeleteuserfromgroup
ldapfinger
ldapid
ldapgid
ldapmodifyuser
ldaprenameuser
lsldap
ldapaddusertogroup
ldapsetpasswd
ldapinit
ldapaddgroup
ldapdeletegroup
ldapmodifygroup
ldapdeletemachine
ldaprenamegroup
ldapaddmachine
ldapmodifymachine
ldapsetprimarygroup
ldapdeleteuser
现在我们有了按照我们想要的方式运行的LDAP,是时候来确保我们可以保存我们所有人的工作和根据需要恢复它。我们要做的就是备份LDAP数据库,特别是后端(cn=config)和前端(dc=example,dc=com)。如果我们将要备份这些数据库,输出到 /export/backup,我们可以使用如下显示的slapcat脚本,称为/usr/local/bin/ldapbackup:
#!/bin/bash
BACKUP_PATH=/export/backup
SLAPCAT=/usr/sbin/slapcat
nice ${SLAPCAT} -n 0 > ${BACKUP_PATH}/config.ldif
nice ${SLAPCAT} -n 1 > ${BACKUP_PATH}/example.com.ldif
nice ${SLAPCAT} -n 2 > ${BACKUP_PATH}/access.ldif
chmod 640 ${BACKUP_PATH}/*.ldif
这些文件是未经压缩的文本文件包含所有在你的LDAP数据库中的东西,包括树的结构,用户的一切,和每一个密码。所以你可能想要考虑使/export/backup变成一个加密的部分,甚至有脚本加密这些文件和创建它们一样。理想的情况下,你应该这两个都做,但这取决于你的安全要求。
然后,就需要有一个cron脚本根据我们觉得合适的方式定时运行这个程序。对大多数人来说,一天一次就够了。对其他人,频率可能更高。这里是一个cron脚本实例被称为/etc/cron.d/ldapbackup每晚22:45h运行:
MAILTO=backup-emails@domain.com
45 22 * * * root /usr/local/bin/ldapbackup
现在文件被创建了,他们一个被拷贝到一个备份服务器。
假设我们新安装了一个LDAP,恢复过程可能是这样的:
sudo service slapd stop
sudo mkdir /var/lib/ldap/accesslog
sudo slapadd -F /etc/ldap/slapd.d -n 0 -l /export/backup/config.ldif
sudo slapadd -F /etc/ldap/slapd.d -n 1 -l /export/backup/domain.com.ldif
sudo slapadd -F /etc/ldap/slapd.d -n 2 -l /export/backup/access.ldif
sudo chown -R openldap:openldap /etc/ldap/slapd.d/
sudo chown -R openldap:openldap /var/lib/ldap/
sudo service slapd start
有许多关于slapd包的手册页。这里有一些重要的,特别考虑在本指南中提到的材料:
其他主页:
Zytrax的LDAP for Rocket Scientists; 一个LDAP的不卖弄但综合的对待。
Ubuntu社区OpenLDAP wiki页有一系列的内容。
O’Reilly的LDAP System Administration (textbook; 2003)
Packt的Mastering OpenLDAP (textbook; 2007)
转载请注明出处:http://blog.csdn.net/m1213642578/article/category/6390054