一、ldap目录服务介绍
什么是目录服务?
  目录是一类为了浏览和搜索数据而设计的特殊的数据库。例如,为人所熟知的微软公司的活动目录(active directory)就是目录数据库的一种。目录服务是按照树状形式存储信息的,目录包含基于属性的描述性信息,并且支持高级的过滤功能。

什么是LDAP?
  LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单多了并且可以根据需要定制。与X.500不同,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。

1、LDAP模型和扩展框架
信息模型:确定LDAP目录中信息的格式和字符集,如何表示目录信息(定义对象类、属性、匹配规则和语法等模式)
命名空间:信息组织方式-目录信息树DIT,以DN和RDN为基础的命名方式,以及LDAP信息的Internet表示方式
功能模型:执行操作的通信协议以及在客户端进行这些操作的API接口
安全框架:保证目录中信息的安全,多种认证方式,以及与TLS结合的通信保护框架
LDAP扩展框架:基于控制和扩展操纵的LDAP扩展框架

2、LDAP的存储方式
  LDAP以树型结构存储,具体信息存储在条目的数据结构中。一个目录信息树由若干条目组成,一个条目一个对象,每个条目具有唯一的标识名DN,并由多个属性组成,每个属性对应一个或多个值。
  LDAP目录服务器是通过目录数据库来存储网络信息以提供目录服务的,目录信息树及其相关概念构成了LDAP协议的信息模型。
注:dc(domain component)表示域名的部分,其格式是将完整的域名分为几部分;uid表示用户ID;ou(organization unit)表示组织单位;cn(common name)表示公共名称;关键字sn(surname)表示姓;dn(distinguished name)表示唯一辨别名,
rdn(relative dn)表示相对辨别名;关键字c(country)表示国家;关键字o(organization)表示组织名。

二、深入认识LDAP
1、LDAP的几种基本模型
  LDAP的体系结构由信息模型、命名模型、功能模型以及安全模型4种基本模型组成。其中,信息模型描述LDAP的信息表示方式;命名模型描述LDAP的数据如何组织;功能模型描述LDAP的数据操作访问方式;安全模型描述LDAP的安全机制。
(1)信息模型
  LDAP信息模型定义了能够在目录中存储的数据类型和基本的信息单位。LDAP中的信息是以树状结构组织,在树状信息中的基本数据单位是条目(即关于对象的信息集合),而每个条目由属性构成,属性中存储属性值,每个属性类型又有对应的语法和匹配规则。通常,条目中的信息说明真实世界的对象。
(2)命名模型
  在LDAP中每个条目均有自己的DN和RDN(Relative Distinguished Name,相对标识名),其中DN是该条目在整个树中的唯一名称标识,而RDN是条目在父节点下的唯一名称标识。
    dn:每个条目的唯一标识符,如上图中linuxprobe的dn值是:
    cn=linuxprobe,ou=marketing,ou=people,dc=mydomain,dc=org
    rdn:一般为dn值中最左侧的部分,如上图中linuxprobe的rdn值是:
    cn=linuxprobe
    base DN:此为基准DN值,表示顶层的根部,上图中的base DN值是:
    dc=mydomain,dc=org
(3)功能模型
说明了能够使用LDAP协议对目录执行的操作,共4类10中操作。
更新类操作:添加条目、删除条目、修改条目、修改条目名
查询类操作:搜索、比较
认证类操作:绑定、解绑定
其他操作:放弃和扩展操作
注:除扩展操作,其余9种是LDAP的标准操作,扩展操作是LDAP中为了增加新的功能所提供的一种标准的扩展框架。
(4)安全模型
LDAP的安全模型主要通过身份认证、安全通道和访问控制来实现。
身份认证:
  匿名认证:适用于没有数据安全问题且不涉及访问权限的完全公开方式
  基本认证:通过用分辨名(DN)和密码进行身份识别,密码识别有分为简单密码和摘要密码认证
  SASL(Simple Authentication and Secure Layer)认证:在SSL和TLS安全通道基础上进行的身份认证,包括数字证书的认证
  通信安全在LDAP中提供了基于SSL/TLS的通信安全保障。SSL/TLS是基于PKI信息安全技术的,是目前Internet上广泛采用的安全服务。TLS服务可以被LDAP通过StartTLS方式启动,该服务既可以提供通信中的数据保密性、完整性保护,也可以实现客户端身份和服务器端身份的双向验证。
访问控制的标准:目前并无访问控制的标准,但LDAP的访问控制非常灵活和丰富。在LDAP中访问控制是通过访问控制策略语句来实现的,而RDBS和应用系统是通过访问控制列表来实现的。

2、LDAP的应用领域
LDAP被广泛用于基础性、关键性信息的管理。
信息安全类:数字证书管理、授权管理、单点登录
网络资源管理类:MAIL系统、DNS系统、网络用户管理、电话号码簿。
科学计算类:DCE(Distributed Computing Environment,分布式计算环境),UDDI(Universal Description,Discovery and Integration,统一描述,发现和集成协议)
电子政务资源管理:内网组织信息服务,电子政务目录体系,人口基础库,法人基础库
LDAP之所以能广泛用于管理用户信息、网络资源信息等,是由于LDAP具有高效率的查询,树状的信息管理模式,分布式的部署框架以及细致灵活的访问控制的特点。

三、OpenLDAP环境搭建
1.环境准备
[root@ldap ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@ldap ~]# uname -r
2.6.32-642.el6.x86_64
[root@ldap ~]# hostname
ldap.server


2.服务端安装配置
[root@ldap ~]# getenforce
Enforcing
[root@ldap ~]# setenforce 0
[root@ldap ~]# service iptables stop
[root@ldap ~]# service ip6tables stop
[root@ldap ~]# chkconfig iptables off
[root@ldap ~]# chkconfig ip6tables off
[root@ldap ~]# getenforce
Permissive
[root@ldap ~]# ntpdate time.windows.com
[root@ldap ~]# date
Tue Nov  1 23:26:22 CST 2016
[root@ldap ~]# crontab -e
#time sync
*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1
[root@ldap ~]# echo "192.168.0.111 etiantian.org" >>/etc/hosts
[root@ldap ~]# tail -1 /etc/hosts
192.168.0.111 etiantian.org
[root@ldap ~]# ping etiantian.org
PING etiantian.org (192.168.0.111) 56(84) bytes of data.
64 bytes from etiantian.org (192.168.0.111): icmp_seq=1 ttl=64 time=0.054 ms
64 bytes from etiantian.org (192.168.0.111): icmp_seq=2 ttl=64 time=0.037 ms
64 bytes from etiantian.org (192.168.0.111): icmp_seq=3 ttl=64 time=0.036 ms
64 bytes from etiantian.org (192.168.0.111): icmp_seq=4 ttl=64 time=0.038 ms

--- etiantian.org ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5567ms
rtt min/avg/max/mdev = 0.036/0.040/0.054/0.006 ms
[root@ldap ~]# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
[root@ldap ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
[root@ldap ~]# yum makecache
[root@ldap ~]# rpm -qa |grep openldap compat-openldap-2.3.43-2.el6.x86_64 openldap-2.4.40-12.el6.x86_64
[root@ldap ~]# yum -y install openldap openldap-*
[root@ldap ~]# yum -y install nscd nss-pam-ldapd nss-* pcre pcre-*
[root@ldap ~]# yum -y install nscd nss-pam-ldapd nss-* pcre pcre-* --exclude=nss-softokn-freebl --skip-broken
[root@ldap ~]# yum -y install nss-pkcs11-devel
[root@ldap ~]# cd /etc/openldap/
[root@ldap openldap]# ll
total 20
drwxr-xr-x. 2 root root 4096 Nov  1 23:46 certs
-rw-r-----. 1 root ldap  121 May 11 07:32 check_password.conf
-rw-r--r--. 1 root root  280 May 11 07:32 ldap.conf
drwxr-xr-x. 2 root root 4096 Nov  1 23:46 schema
drwx------. 3 ldap ldap 4096 Nov  1 23:46 slapd.d
[root@ldap openldap]# ll slapd.d/
total 8
drwx------. 3 ldap ldap 4096 Nov  1 23:46 cn=config
-rw-------. 1 ldap ldap 1281 Nov  1 23:46 cn=config.ldif
[root@ldap openldap]# cp /usr/share/openldap-servers/slapd.conf.obsolete slapd.conf  //openldap的配置文件(2.3版的),此处2.4版的配置文件在/etc/openldap/slapd.d/cn=config
[root@ldap openldap]# slappasswd --help
slappasswd: invalid option -- '-'
Usage: slappasswd [options]
  -c format     crypt(3) salt format
  -g            generate random password
  -h hash       password scheme
  -n            omit trailing newline
  -o [=val] specify an option with a(n optional) value
        module-path=
        module-load=
  -s secret     new password
  -u            generate RFC2307 values (default)
  -v            increase verbosity
  -T file       read file for new password
生成管理员密钥(记下生成出的值,后面要用):
方法一:
[root@ldap openldap]# slappasswd -s 123456
{SSHA}lIMVmm0Xk6gdurluKsvVWAsPTo5lUvJo
然后把上一步生成的管理员密钥加入到配置文件slapd.conf中,如下:
rootpw  {SSHA}lIMVmm0Xk6gdurluKsvVWAsPTo5lUvJo
方法二:
[root@ldap openldap]# slappasswd -s 123456|sed -e "s#{SSHA}#rootpw\t{SSHA}#g" >>slapd.conf
[root@ldap openldap]# tail -1 slapd.conf
rootpw  {SSHA}mDsZ2A7nq6PCQ9CQmLTZThIDqHbxvHT3
[root@ldap openldap]# cp slapd.conf slapd.conf.ori
[root@ldap openldap]# vim slapd.conf
114 #database       bdb
115 #suffix         "dc=my-domain,dc=com"
116 #checkpoint     1024 15
117 #rootdn         "cn=Manager,dc=my-domain,dc=com"
118 #add start by linuxzkq 2016/11/2
119 base       bdb
120 suffix     "dc=etiantian,dc=org"
121 rootdn     "cn=admin,dc=etiantian,dc=org"
122 #add end by linuxzkq 2016/11/2
提示:这是全部的配置内容,特别强调,参数在文件中的先后位置不能随意移动。
空行和以“#”开头的注释行将被忽略。如果一行以空格开头,它将被认为是接着前一行的(即使前一行是注释)。
[root@ldap openldap]# diff slapd.conf.ori slapd.conf
114,117c114,123
< database      bdb
< suffix                "dc=my-domain,dc=com"
< checkpoint    1024 15
< rootdn                "cn=Manager,dc=my-domain,dc=com"
---
> #database     bdb
> #suffix               "dc=my-domain,dc=com"
> #checkpoint   1024 15
> #rootdn               "cn=Manager,dc=my-domain,dc=com"
> #add start by linuxzkq 2016/11/2
> database       bdb  //指定使用的数据库
> suffix     "dc=etiantian,dc=org"  //指定要搜索的后缀
> rootdn     "cn=admin,dc=etiantian,dc=org"  //指定管理员dn路径,使用这个dn可以登录OpenLDAP服务器
> #add end by linuxzkq 2016/11/2
>
Ldap管理员:admin 密码:123456
[root@ldap openldap]# egrep -v "^$|#" slapd.conf
include         /etc/openldap/schema/corba.schema
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/duaconf.schema
include         /etc/openldap/schema/dyngroup.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/java.schema
include         /etc/openldap/schema/misc.schema
include         /etc/openldap/schema/nis.schema
include         /etc/openldap/schema/openldap.schema
include         /etc/openldap/schema/ppolicy.schema
include         /etc/openldap/schema/collective.schema
allow bind_v2
pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args
TLSCACertificatePath /etc/openldap/certs
TLSCertificateFile "\"OpenLDAP Server\""
TLSCertificateKeyFile /etc/openldap/certs/password
database config
access to *
        by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
        by * none
database monitor
access to *
        by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
        by dn.exact="cn=Manager,dc=my-domain,dc=com" read
        by * none
base       bdb
suffix     "dc=etiantian,dc=org"
rootdn     "cn=admin,dc=etiantian,dc=org"
directory       /var/lib/ldap
index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub
rootpw  {SSHA}mDsZ2A7nq6PCQ9CQmLTZThIDqHbxvHT3

Openldap参数配置优化:
a.日志及缓存参数
[root@ldap openldap]# cat >>slapd.conf<> #add start by linuxzkq 2016/11/2
> loglevel      296
> cachesize     1000
> checkpoint    2048   10
> #add end by linuxzkq 2016/11/2
> EOF
[root@ldap openldap]# tail -6 slapd.conf
rootpw  {SSHA}mDsZ2A7nq6PCQ9CQmLTZThIDqHbxvHT3
#add start by linuxzkq 2016/11/2
loglevel      296
cachesize     1000
checkpoint    2048   10
#add end by linuxzkq 2016/11/2
b.授权及安全参数配置
Table 6.3: Access Entity Specifiers Specifier     Entities
*                             All, including anonymous and authenticated users
anonymous                     Anonymous (non-authenticated) users
users                             Authenticated users
self                             User associated with target entry  //自己
dn[.]=     Users matching a regular expression
dn.=             Users within scope of a DN

Table 6.4: Access Levels Level     Privileges     Description
none =             0     no access
disclose =     d     needed for information disclosure on error
auth =             dx     needed to authenticate (bind)
compare =     cdx     needed to compare
search =     scdx     needed to apply search filters
read =             rscdx     needed to read search results
write =     wrscdx     needed to modify/rename
manage =     mwrscdx needed to manage

A simple example:
    access to * by * read
This access directive grants read access to everyone.
    access to *
        by self write
        by anonymous auth
        by * read

This directive allows the user to modify their entry, allows anonymous to authentication against these entries, and allows all others to read these entries. Note that only the first by clause which matches applies. Hence, the anonymous users are granted auth, not read. The last clause could just as well have been "by users read".
[root@ldap openldap]# vi slapd.conf
删除98行至108行内容:
98 database config
99 access to *
100       by dn.exact="gidNumber=0+uidNumber=0
        ,cn=peercred,cn=external,cn=auth" manage
101        by * none
102
103 # enable server status monitoring (cn=monitor)
104 database monitor
105 access to *
106         by dn.exact="gidNumber=0+uidNumber=0
        ,cn=peercred,cn=external,cn=auth" read
107         by dn.exact="cn=Manager,dc=my-domain
        ,dc=com" read
108         by * none
然后加入以下内容:
access to *
     by self write
     by anonymous auth
     by * read

配置rsyslog记录ldap服务日志:
[root@ldap openldap]# cp /etc/rsyslog.conf /etc/rsyslog.conf.ori
[root@ldap openldap]# echo "record ldap.log by linuxzkq 2016/11/2" >>/etc/rsyslog.conf
[root@ldap openldap]# echo "local4.*          /var/log/ldap.log">> /etc/rsyslog.conf    
[root@ldap openldap]# tail -2 /etc/rsyslog.conf
record ldap.log by linuxzkq 2016/11/2
local4.*          /var/log/ldap.log
[root@ldap openldap]# /etc/init.d/rsyslog restart
Shutting down system logger:                       [  OK  ]
Starting system logger:                            [  OK  ]
[root@ldap openldap]# ll /var/log/ldap.log
-rw-------. 1 root root 0 Nov  2 23:13 /var/log/ldap.log

配置LDAP数据库路径:
[root@ldap openldap]# grep "directory" slapd.conf|grep -v "#"
directory       /var/lib/ldap
[root@ldap openldap]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
[root@ldap openldap]# ll /var/lib/ldap
total 4
-rw-r--r--. 1 root root 845 Nov  2 23:17 DB_CONFIG
[root@ldap openldap]# chown ldap:ldap /var/lib/ldap/DB_CONFIG
[root@ldap openldap]# chmod 700 /var/lib/ldap/DB_CONFIG
[root@ldap openldap]# ll /var/lib/ldap              total 4
-rwx------. 1 ldap ldap 845 Nov  2 23:17 DB_CONFIG
[root@ldap openldap]# egrep -v "\#|^$" /var/lib/ldap/DB_CONFIG
set_cachesize 0 268435456 1
set_lg_regionmax 262144
set_lg_bsize 2097152
[root@ldap openldap]# slaptest -u  //测试配置文件是否配置成功
config file testing succeeded
最终LDAP完整配置文件:
[root@ldap openldap]# egrep -v "^$|^.*#" slapd.conf
include         /etc/openldap/schema/corba.schema
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/duaconf.schema
include         /etc/openldap/schema/dyngroup.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/java.schema
include         /etc/openldap/schema/misc.schema
include         /etc/openldap/schema/nis.schema
include         /etc/openldap/schema/openldap.schema
include         /etc/openldap/schema/ppolicy.schema
include         /etc/openldap/schema/collective.schema
allow bind_v2
pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args
TLSCACertificatePath /etc/openldap/certs
TLSCertificateFile "\"OpenLDAP Server\""
TLSCertificateKeyFile /etc/openldap/certs/password
    access to *
        by self write
        by anonymous auth
        by * read
base       bdb
suffix     "dc=etiantian,dc=org"
rootdn     "cn=admin,dc=etiantian,dc=org"
directory       /var/lib/ldap
index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub
rootpw  {SSHA}mDsZ2A7nq6PCQ9CQmLTZThIDqHbxvHT3
loglevel      296
cachesize     1000
checkpoint    2048   10
[root@ldap openldap]# diff slapd.conf.ori slapd.conf
98,108c98,101
< database config
< access to *
<       by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
<       by * none
<
< # enable server status monitoring (cn=monitor)
< database monitor
< access to *
<       by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
<         by dn.exact="cn=Manager,dc=my-domain,dc=com" read
<         by * none
---
>     access to *
>         by self write
>         by anonymous auth
>         by * read
114,117c107,116
< database      bdb
< suffix                "dc=my-domain,dc=com"
< checkpoint    1024 15
< rootdn                "cn=Manager,dc=my-domain,dc=com"
---
> #database     bdb
> #suffix               "dc=my-domain,dc=com"
> #checkpoint   1024 15
> #rootdn               "cn=Manager,dc=my-domain,dc=com"
> #add start by linuxzkq 2016/11/2
> base       bdb
> suffix     "dc=etiantian,dc=org"
> rootdn     "cn=admin,dc=etiantian,dc=org"
> #add end by linuxzkq 2016/11/2
>
141a141,145
> #add start by linuxzkq 2016/11/2
> loglevel      296
> cachesize     1000
> checkpoint    2048   10
> #add end by linuxzkq 2016/11/2
[root@ldap openldap]# /etc/init.d/slapd start
Starting slapd:                                    [  OK  ]
[root@ldap openldap]# netstat -tunlp|grep slapd
tcp        0      0 0.0.0.0:389                 0.0.0.0:*                   LISTEN      3002/slapd          
tcp        0      0 :::389                      :::*                        LISTEN      3002/slapd          
[root@ldap openldap]# lsof -i:389
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
slapd   3002 ldap    7u  IPv4  22382      0t0  TCP *:ldap (LISTEN)
slapd   3002 ldap    8u  IPv6  22383      0t0  TCP *:ldap (LISTEN)
[root@ldap openldap]# ps -ef|grep ldap|grep -v grep
ldap       3002      1  0 23:31 ?        00:00:00 /usr/sbin/slapd -h  ldap:/// ldapi:/// -u ldap
[root@ldap openldap]# chkconfig slapd on
[root@ldap openldap]# chkconfig --list slapd
slapd           0:off   1:off   2:on    3:on    4:o5:on     6:off

查看ldap master数据库:
[root@ldap openldap]# ldap
ldapadd      ldapmodify   ldapurl
ldapcompare  ldapmodrdn   ldapwhoami
ldapdelete   ldappasswd   
ldapexop     ldapsearch
[root@ldap openldap]# ldapsearch -LLL -W -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -b "dc=etiantian,dc=org" "(uid=*)"
Enter LDAP Password:
ldap_bind: Invalid credentials (49)  //查询ldap数据库报错,密码对也连接不上。
出错,解决ldap2.3和2.4配置冲突问题,解决方法如下:
[root@ldap openldap]# ll /etc/openldap/slapd.d/
total 8
drwx------. 3 ldap ldap 4096 Nov  1 23:46 cn=config
-rw-------. 1 ldap ldap 1281 Nov  1 23:46 cn=config.ldif
[root@ldap openldap]# rm -rf /etc/openldap/slapd.d/*
[root@ldap openldap]# slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d
581a0d14 bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
config file testing succeeded
[root@ldap openldap]# ll /etc/openldap/slapd.d      total 8
drwxr-x---. 3 root root 4096 Nov  2 23:59 cn=config
-rw-------. 1 root root 1301 Nov  2 23:59 cn=config.ldif
[root@ldap openldap]# /etc/init.d/slapd restart
Stopping slapd:                                    [  OK  ]
Checking configuration files for slapd:            [FAILED]
581a0daf ldif_read_file: Permission denied for "/etc/openldap/slapd.d/cn=config.ldif"
slaptest: bad configuration file!
[root@ldap openldap]# chown -R ldap.ldap /etc/openldap/slapd.d/
[root@ldap openldap]# ll /etc/openldap/slapd.d     

total 8
drwxr-x---. 3 ldap ldap 4096 Nov  2 23:59 cn=config
-rw-------. 1 ldap ldap 1301 Nov  2 23:59 cn=config.ldif
[root@ldap openldap]# /etc/init.d/slapd restart     
Stopping slapd:                                    [FAILED]
Starting slapd:                                    [  OK  ]
[root@ldap openldap]# lsof -i:389
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
slapd   3186 ldap    7u  IPv4  23490      0t0  TCP *:ldap (LISTEN)
slapd   3186 ldap    8u  IPv6  23491      0t0  TCP *:ldap (LISTEN)
[root@ldap openldap]# ldapsearch -LLL -W -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -b "dc=etiantian,dc=org" "(uid=*)"
Enter LDAP Password:
No such object (32)
至此问题解决。
查询LDAP的目录条目,介绍一下ldapsearch命令,具体可以使用man帮助手册查看。
    -b:指定查找的节点
    -D:指定查找的DN
    -x:使用简单认证
    -W:查询是输入密码,或者使用-w password
    -h:OpenLDAP的主机地址,可以使用IP或者域名
    -H:使用LDAP服务器的URI地址进行操作

为ldap master数据库添加数据的方法:
为ldap添加用户数据,有四种方法,分别如下,我们选择第四种方法进行试验。
 1)可以直接修改slapd.d目录下面的数据文件,好处是不用重启服务,直接生效;
 2)安装开源工具migrationtools来生成ldif文件,并通过ldapadd来添加;
 3)安装ldap 客户端,这种方法最为简单;
 4)直接编辑ldif文件,然后通过ldapadd添加。
  首先我们手动编辑base.ldif文件,直接复制好像会因为格式有问题。每个条目之间有个空格,直接复制过去会有点问题,需要你把每个条目之间“空行”的第一个空格删除一下。
[root@ldap openldap]# vi base.ldif
dn: dc=etiantian,dc=org
objectClass: organization
objectClass: dcObject
dc: etiantian
o: etiantian

dn: ou=People,dc=etiantian,dc=org
objectClass: organizationalUnit
ou: People

dn: ou=group,dc=etiantian,dc=org
objectClass: organizationalUnit
ou: group

开始导入数据并初始化ldap测试数据:
[root@ldap openldap]# ldapadd -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -W -f base.ldif
Enter LDAP Password:
adding new entry "dc=etiantian,dc=org"

adding new entry "ou=People,dc=etiantian,dc=org"

adding new entry "ou=group,dc=etiantian,dc=org"

查询导入的结果:
[root@ldap openldap]# ldapsearch -LLL -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -b "dc=etiantian,dc=org" -w 123456   
dn: dc=etiantian,dc=org
objectClass: organization
objectClass: dcObject
dc: etiantian
o: etiantian

dn: ou=People,dc=etiantian,dc=org
objectClass: organizationalUnit
ou: People

dn: ou=group,dc=etiantian,dc=org
objectClass: organizationalUnit
ou: group

然后我们通过user.ldif和group.ldif增加一个用户和一个组。
1.编辑用户和用户组配置文件
[root@ldap openldap]# vi user.ldif
dn: uid=test1,ou=People,dc=etiantian,dc=org
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
objectClass: shadowAccount
gidNumber: 0
givenName: test1
sn: test1
uid: test1
homeDirectory: /home/test1
loginShell: /bin/bash
shadowFlag: 0
shadowMin: 0
shadowMax: 99999
shadowWarning: 0
shadowInactive: 99999
shadowLastChange: 12011
shadowExpire: 99999
cn: test1
uidNumber: 24422
userPassword:: e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRR
VpOcXc9
[root@ldap openldap]# vi group.ldif
dn: cn=DBA,ou=group,dc=etiantian,dc=org
objectClass: posixGroup
objectClass: top
cn: DBA
memberUid: test1
gidNumber: 10673
2.添加用户和组
[root@ldap openldap]# ldapadd -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -f user.ldif -w 123456   
adding new entry "uid=test1,ou=People,dc=etiantian,dc=org"
[root@ldap openldap]# ldapadd -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -f group.ldif -w 123456
adding new entry "cn=DBA,ou=group,dc=etiantian,dc=org"
3.查看是否添加成功
[root@ldap openldap]# ldapsearch -LLL -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -b "dc=etiantian,dc=org" -w 123456
dn: dc=etiantian,dc=org
objectClass: organization
objectClass: dcObject
dc: etiantian
o: etiantian

dn: ou=People,dc=etiantian,dc=org
objectClass: organizationalUnit
ou: People

dn: ou=group,dc=etiantian,dc=org
objectClass: organizationalUnit
ou: group

dn: uid=test1,ou=People,dc=etiantian,dc=org
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
objectClass: shadowAccount
gidNumber: 0
givenName: test1
sn: test1
uid: test1
homeDirectory: /home/test1
loginShell: /bin/bash
shadowFlag: 0
shadowMin: 0
shadowMax: 99999
shadowWarning: 0
shadowInactive: 99999
shadowLastChange: 12011
shadowExpire: 99999
cn: test1
uidNumber: 24422
userPassword:: e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9

dn: cn=DBA,ou=group,dc=etiantian,dc=org
objectClass: posixGroup
objectClass: top
cn: DBA
memberUid: test1
gidNumber: 10673

备份当前初始化的ldap数据库数据:
[root@ldap openldap]# ldapsearch -LLL -x -H ldap://etiantian.org -D "cn=admin,dc=etiantian,dc=org" -b "dc=etiantian,dc=org" -w 123456 >/data/bak_ldap_data.ldif
[root@ldap openldap]# ll /data/bak_ldap_data.ldif
-rw-r--r--. 1 root root 834 Nov  3 23:05 /data/bak_ldap_data.ldif

为ldap master配置web管理接口:
1.安装LAMP服务环境
[root@ldap openldap]# yum -y install httpd php php-ldap php-gd
[root@ldap openldap]# rpm -qa httpd php php-ldap php-gd
httpd-2.2.15-54.el6.centos.x86_64
php-gd-5.3.3-48.el6_8.x86_64
php-ldap-5.3.3-48.el6_8.x86_64
php-5.3.3-48.el6_8.x86_64
2.下载解压配置ldap客户端软件
[root@ldap openldap]# cd /var/www/html
[root@ldap html]# tar xf ldap-account-manager-3.9.tar.gz
[root@ldap html]# mv ldap-account-manager-3.9 ldap
[root@ldap html]# cd ldap/config
[root@ldap config]# cp config.cfg_sample config.cfg_sample.bak
[root@ldap config]# cp lam.conf_sample lam.conf_sample.bak
[root@ldap config]# mv lam.conf_sample lam.conf
[root@ldap config]# mv config.cfg_sample config.cfg
[root@ldap config]# sed -i 's#cn=Manager#cn=admin#g' lam.conf
[root@ldap config]# sed -i 's#dc=my-domain#dc=etiantian#g' lam.conf
[root@ldap config]# sed -i 's#dc=com#dc=org#g' lam.conf
[root@ldap config]# diff lam.conf_sample lam.conf   13c13
< admins: cn=Manager,dc=my-domain,dc=com
---
> admins: cn=admin,dc=etiantian,dc=org
55c55
< types: suffix_user: ou=People,dc=my-domain,dc=com
---
> types: suffix_user: ou=People,dc=etiantian,dc=org
59c59
< types: suffix_group: ou=group,dc=my-domain,dc=com
---
> types: suffix_group: ou=group,dc=etiantian,dc=org
63c63
< types: suffix_host: ou=machines,dc=my-domain,dc=com
---
> types: suffix_host: ou=machines,dc=etiantian,dc=org
67c67
< types: suffix_smbDomain: dc=my-domain,dc=com
---
> types: suffix_smbDomain: dc=etiantian,dc=org
[root@ldap config]# chown -R apache.apache /var/www/html/ldap
[root@ldap config]# /etc/init.d/httpd start
Starting httpd:                                    [  OK  ]
登录ldap master的web管理接口:
http://192.168.0.111/ldap/templates/login.php
  出现登录界面后,首先点击右上角的"LAM configuration"配置选项,再点击"Edit general settings",按提示输入客户端的密码,默认为"lam",配置修改"LAM configuration"的默认密码,这里设置为123456。然后登录,尽情的使用吧!

配置网络服务通过LDAP服务进行身份验证:
1.配置svn+sasl通过LDAP进行身份验证
a.安装配置svn服务(非apache svn)
见前一节课程:http://linuxzkq.blog.51cto.com/9379412/1867490
b.启用svn服务器的SASL验证机制
  SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。简单认证与安全层 (SASL) 是一个在网络协议中用来认证和数据加密的构架。它把认证机制从程序中分离开, 理论上使用SASL的程序协议都可以使用SASL所支持的全部认证机制。认证机制可支持代理认证, 这让一个用户可以承担另一个用户的认证。 SASL同样提供数据安全层,这提供了数据完整验证和数据加密。支持SASL的应用程序通常也支持 传输层安全 (TLS) 作为对SASL提供的服务的补充。
[root@ldap sadoc]# rpm -qa|grep sasl
cyrus-sasl-lib-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-plain-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-devel-2.1.23-15.el6_6.2.x86_64
系统默认安装了4个,包不全,接着安装相关SASL包。
[root@ldap sadoc]# yum -y install *sasl*
省略。。。。。。
Installed:
  cyrus-sasl-gssapi.x86_64 0:2.1.23-15.el6_6.2  
  cyrus-sasl-ldap.x86_64 0:2.1.23-15.el6_6.2    
  cyrus-sasl-md5.x86_64 0:2.1.23-15.el6_6.2     
  cyrus-sasl-ntlm.x86_64 0:2.1.23-15.el6_6.2    
  cyrus-sasl-sql.x86_64 0:2.1.23-15.el6_6.2     
  python-saslwrapper.x86_64 0:0.14-1.el6        
  ruby-saslwrapper.x86_64 0:0.14-1.el6          
  saslwrapper.x86_64 0:0.14-1.el6               
  saslwrapper-devel.x86_64 0:0.14-1.el6         
Dependency Installed:
  postgresql-libs.x86_64 0:8.4.20-6.el6         
  ruby.x86_64 0:1.8.7.374-4.el6_6               
  ruby-libs.x86_64 0:1.8.7.374-4.el6_6          
Complete!
[root@ldap sadoc]# rpm -qa|grep sasl    
saslwrapper-devel-0.14-1.el6.x86_64
cyrus-sasl-ntlm-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-lib-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-2.1.23-15.el6_6.2.x86_64
saslwrapper-0.14-1.el6.x86_64
cyrus-sasl-sql-2.1.23-15.el6_6.2.x86_64
python-saslwrapper-0.14-1.el6.x86_64
cyrus-sasl-ldap-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-md5-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-plain-2.1.23-15.el6_6.2.x86_64
cyrus-sasl-devel-2.1.23-15.el6_6.2.x86_64
ruby-saslwrapper-0.14-1.el6.x86_64
cyrus-sasl-gssapi-2.1.23-15.el6_6.2.x86_64

查看密码验证机制列表,输入:
[root@ldap sadoc]# sasl
sasl2-sample-client    saslauthd
sasl2-sample-server    sasldblistusers2
sasl2-shared-mechlist  saslpasswd2
[root@ldap sadoc]# saslauthd -v
saslauthd 2.1.23
authentication mechanisms: getpwent kerberos5 pam rimap shadow ldap
[root@ldap sadoc]# grep -i "mech" /etc/sysconfig/saslauthd
# Mechanism to use when checking passwords.  Run "saslauthd -v" to get a list
# of which mechanism your installation was compiled with the ablity to use.
MECH=pam
# Options sent to the saslauthd. If the MECH is other than "pam" uncomment the next line.
[root@ldap sadoc]# sed -i 's#MECH=pam#MECH=shadow#g' /etc/sysconfig/saslauthd
[root@ldap sadoc]# grep -i "mech" /etc/sysconfig/saslauthd|grep -v "#"
MECH=shadow
[root@ldap sadoc]# /etc/init.d/saslauthd restart
Stopping saslauthd:                            [FAILED]
Starting saslauthd:                            [  OK  ]
[root@ldap sadoc]# ps -ef|grep sasl
root       3817      1  0 21:49 ?        00:00:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a shadow
root       3819   3817  0 21:49 ?        00:00:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a shadow
root       3820   3817  0 21:49 ?        00:00:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a shadow
root       3821   3817  0 21:49 ?        00:00:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a shadow
root       3822   3817  0 21:49 ?        00:00:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a shadow
root       3824   3717  0 21:49 pts/0    00:00:00 grep sasl

测试saslauthd进程的认证功能:
[root@ldap sadoc]# testsaslauthd -uadmin -p123456
0: NO "authentication failed"  //失败,因为系统用户里面没有这个用户,所以失败,下面添加用户。
[root@ldap sadoc]# grep "admin" /etc/passwd
[root@ldap sadoc]# id admin
id: admin: No such user
[root@ldap sadoc]# useradd admin
[root@ldap sadoc]# passwd admin
Changing password for user admin.
New password:
BAD PASSWORD: it is too simplistic/systematic
BAD PASSWORD: is too simple
Retype new password:  //设置密码为上面的"123456"
passwd: all authentication tokens updated successfully.
[root@ldap sadoc]# testsaslauthd -uadmin -p123456
0: OK "Success."
[root@ldap sadoc]# testsaslauthd -utest1 -p123456
0: NO "authentication failed"  //使用LDAP的用户测试,认证失败,说明目前还不支持LDAP的用户。

测试通过LDAP进行验证:
[root@ldap sadoc]# man saslauthd  //man配置文件,输入"/ldap"搜索ldap相关配置。
SASLAUTHD(8)              BSD System Manager’s Manual             SASLAUTHD(8)
NAME
     saslauthd - sasl authentication server
SYNOPSIS
     saslauthd -a authmech [-Tvdchlr]
               [-O option] [-m mux_path]
               [-n threads] [-s size]
               [-t timeout]
DESCRIPTION
     saslauthd is a daemon process that
...skipping...
     ldap       (All platforms that support
                OpenLDAP 2.0 or higher)
                Authenticate against an
                ldap server.  The ldap con-
                figuration parameters are
                read from /etc/saslau-
                thd.conf.  The location of
                this file can be changed
                with the -O parameter. See
                the LDAP_SASLAUTHD file
                included with the distribu-
                tion for the list of avail-
                able parameters.
[root@ldap sadoc]# history|grep sed
    8  sed -i 's/keepcache=0/keepcache=1/g' /etc/yum.conf
  275  slappasswd -s 123456|sed -e "s#{SSHA}#rootpw\t{SSHA}#g" >>slapd.conf
  383  sed -i 's#cn=Manager#cn=amin#g' lam.conf
  384  sed -i 's#dc=my-domain#dc=etiantian#g' lam.conf
  385  sed -i 's#dc=com#dc=org#g' lam.conf
  387  sed -i 's#cn=amin#cn=admin#g' lam.conf
  411  sed -i 's#MECH=pam#MECH=shadow#g' /etc/sysconfig/saslauthd
  426  history|grep sed
[root@ldap sadoc]# sed -i 's#MECH=shadow#MECH=ldap#g' /etc/sysconfig/saslauthd
[root@ldap sadoc]# grep -i "mech" /etc/sysconfig/saslauthd|grep -v "#"        
MECH=ldap
[root@ldap sadoc]# /etc/init.d/saslauthd restart
Stopping saslauthd:                            [  OK  ]
Starting saslauthd:                            [  OK  ]
[root@ldap sadoc]# testsaslauthd -utest1 -p123456
0: NO "authentication failed"
[root@ldap sadoc]# testsaslauthd -uadmin -p123456
0: NO "authentication failed"
再次使用系统用户admin和ldap用户test1认证都失败了。

配置saslauthd连接LDAP的连接信息:
[root@ldap sadoc]# vi /etc/saslauthd.conf       
ldap_servers: ldap://etiantian.org/
#ldap_uri: ldap://ldap.test1.etiantian.org/
#ldap_version: 3
#ldap_start_tls: 0
ldap_bind_dn: cn=admin,dc=etiantian,dc=org
ldap_bind_pw: 123456
ldap_search_base: ou=People,dc=etiantian,dc=org
ldap_filter: uid=%U
#ldap_filter: mail=%[email protected]
ldap_password_attr: userPassword
#ldap_sasl: 0
[root@ldap sadoc]# /etc/init.d/saslauthd restart
Stopping saslauthd:                            [  OK  ]
Starting saslauthd:                            [  OK  ]
[root@ldap sadoc]# testsaslauthd -u oldboy -p 123456
0: OK "Success."  //ldap用户认证成功
[root@ldap sadoc]# testsaslauthd -u test1 -p 123456    
0: OK "Success."  //ldap用户认证成功
[root@ldap sadoc]# testsaslauthd -u admin -p 123456
0: NO "authentication failed"  //系统用户admin认证失败

开发脚本一键安装svn服务并测试成功:
[root@client ~]# vi auto_install_svn.sh
#!/bin/sh
#the scripts is auto_install_svn script command
#date:2016-11-04
#author:linuxzkq
#mail:[email protected]
#version:v1.0

#yum install svn
yum -y install subversion

#set "keepcache=1"
sed -i 's/keepcache=0/keepcache=1/g' /etc/yum.conf
grep "keepcache" /etc/yum.conf

#create svn svndata and svnpasswd directory
mkdir -p /application/svndata
mkdir -p /application/svnpasswd

#start svn
svnserve -d -r /application/svndata/
ps -ef| grep svn|grep -v grep
netstat -tunlp|grep 3690

#create svn Project
svnadmin create /application/svndata/sadoc

#start config svn
cd /application/svndata/sadoc/conf/
/bin/cp svnserve.conf svnserve.conf.bak
sed -i 's/# anon-access = read/anon-access = none/g' svnserve.conf
sed -i 's/# auth-access = write/auth-access = write/g' svnserve.conf
sed -i 's@# password-db = passwd@password-db = /application/svnpasswd/passwd@g' svnserve.conf
sed -i 's@# authz-db = authz@authz-db = /application/svnpasswd/authz@g' svnserve.conf

#start config svn passwd and authz
/bin/cp authz passwd /application/svnpasswd/
chmod 700 /application/svnpasswd/*
cat >>/application/svnpasswd/passwd<linuxzkq = 123456
guest = guest
EOF
cat >>/application/svnpasswd/authz<[groups]
linux = linuxzkq,guest
[sadoc:/]
linuxzkq = rw
guest = r
@linux = r
* =
EOF

#restart svn
pkill svnserve
sleep 3
svnserve -d -r /application/svndata/

#test local file
echo "please exec the cmd bellow:"
echo "svn checkout svn://192.168.0.110/sadoc /opt --username=linuxzkq --password=123456"
sleep 600

配置svn通过LDAP验证并且授权:
[root@ldap ~]# ll /etc/sasl2/
total 4
-rw-r--r--. 1 root root 49 Feb 20  2014 smtpd.conf
[root@ldap ~]# vi /etc/sasl2/svn.conf
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
[root@ldap ~]# cp /application/svndata/sadoc/conf/svnserve.conf /application/svndata/sadoc/conf/svnserve.conf.ori
[root@ldap ~]# sed -i 's@# use-sasl = true@use-sasl = true@g' /application/svndata/sadoc/conf/svnserve.conf
[root@ldap ~]# grep "sasl" /application/svndata/sadoc/conf/svnserve.conf
[sasl]
use-sasl = true
[root@ldap ~]# vi /application/svnpasswd/authz
在[groups]标签下加入:
ldap = test1,oldboy
在[sadoc:/]标签下加入:
@ldap = rw
特别注意:加入以上内容,给予ldap用户访问svn版本库的权限。
[root@ldap ~]# pkill svnserve
[root@ldap ~]# svnserve -d -r /application/svndata
[root@ldap ~]# netstat -tunlp|grep 3690
tcp        0      0 0.0.0.0:3690                0.0.0.0:*                   LISTEN      1870/svnserve
[root@ldap ~]# svn checkout svn://192.168.0.111/sadoc /opt --username=oldboy --password=123456
A    /opt/a
A    /opt/22.txt
A    /opt/b
A    /opt/c
A    /opt/d
A    /opt/7.txt
A    /opt/8.txt
A    /opt/新建 Microsoft Access 数据库.accdb
A    /opt/55.txt
Checked out revision 48.
[root@ldap ~]# svn ls svn://192.168.0.111/sadoc --username=test1 --password=123456        
22.txt
55.txt
7.txt
8.txt
a
b
c
d
通过以上结果,可以看出ldap用户oldboy访问svn版本库正常。

svn通过ldap验证的总结:
1.配置成功saslauthd,前提条件;
2.配置/etc/sasl2/svn.conf;
[root@ldap ~]# vi /etc/sasl2/svn.conf
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
3.配置好svn服务,并且开启sasl支持,重启svn;
[root@ldap ~]# grep "sasl" /application/svndata/sadoc/conf/svnserve.conf
[sasl]
use-sasl = true
4.配置authz授权ldap用户访问相关项目的权限;
[root@ldap ~]# vi /application/svnpasswd/authz
在[groups]标签下加入:
ldap = test1,oldboy
在[sadoc:/]标签下加入:
@ldap = rw
5.测试访问linux或win32
[root@ldap ~]# svn ls svn://192.168.0.111/sadoc --username=test1 --password=123456