OpenLDAP是一个轻量级目录访问协议(Lightweight Directory Access Protocal,LDAP),是开源集中账号管理架构的实现。

概念

OpenLDAP默认以Brekeley DB作为后端数据库,主要以散列的数据类型进行数据存储,例如以键值对的方式进行存储。BerkeleyDB数据库是面向查询和读取进行优化的数据库,它不支持事务型数据库所支持的高并发的吞吐量以及复杂的事务操作。

OpenLDAP目录中的信息是按照树形结构进行组织,具体信息存储在条目(entry)中,条目可以看成关系数据库中的表记录,条目是具有区别名(Distinguished Name, DN)的属性(attribute),DN是用来引用条目,DN相当于关系数据库中的主键,是唯一的,属性由类型(type)和一个或者多值(value)组成。

功能

  1. 查询操作
  2. 更新操作
  3. 同步操作
  4. 认证和管理操作

目录树

  • 目录树

    在一个目录服务系统中,整个目录信息集可以表示为一个目录信息树,树中的每个节点是一个条目(Entry)。

  • 条目(Entry)

    条目,也叫记录项,是 LDAP 中最基本的颗粒,就像字典中的词条,或者是数据库中的记录。通常对 LDAP 的添加、删除、更改、检索都是以条目为基本对象的。

    LDAP 目录的条目(entry)由属性(attribute)的一个聚集组成,并由一个唯一性的名字引用,即专有名称distinguished name,DN)。例如,DN 能取这样的值:”cn=group,dc=eryajf,dc=net“。

  • 对象类(ObjectClass)

    对象类是属性的集合,LDAP 预想了很多人员组织机构中常见的对象,并将其封装成对象类。比如人员(person)含有姓(sn)、名(cn)、电话(telephoneNumber)、密码(userPassword)等属性,单位职工(organizationalPerson)是人员(person)的继承类,除了上述属性之外还含有职务(title)、邮政编码(postalCode)、通信地址(postalAddress)等属性。

  • 属性 (Attribute)

    每个条目都可以有很多属性(Attribute),比如常见的人都有姓名、地址、电话等属性。每个属性都有名称及对应的值,属性值可以有单个、多个。

字段

  • dc (Domain Component)

    域名的部分,其格式是将完整的域名分成几部分,如域名为eryajf.net变成dc=eryajf,dc=net

  • ou(Organization Unit)

    组织单位,组织单位可以包含其他各种对象(包括其他组织单元)。

  • cn (Common Name)

    常用名称,可用作分组的名字,或者用户的全名。参考(opens new window)

  • dn (Distinguished Name)

    每一个条目都有一个唯一的标识名,dn 在 ldap 中全局唯一,相当于该条目的唯一 ID,如上边示例中的:cn=group,dc=eryajf,dc=net就是该条目的 dn。

  • rdn (Relative dn)

    一般指 dn 逗号最左边的部分,如cn=group,dc=eryajf,dc=net的 rdn 就是 cn=group

  • Base DN

    LDAP 目录树的最顶部就是根,比如上边示例中的 base dn 为 dc=eryajf,dc=net

  • description

    在不同类别中,对应不同类别的说明信息,比如用户的说明信息,分组的说明信息。

部署

安装

# 安装软件包
dnf install -y openldap openldap-clients openldap-servers
# 拉起服务
systemctl enable --now slapd
# 验证端口
netstat -antup | grep -i 389
# 开通防火墙
firewall-cmd --add-service={ldap,ldaps}
firewall-cmd --runtime-to-permanent

目录结构

[root@ldap ~]# tree /etc/openldap/
/etc/openldap/
├── certs
├── check_password.conf
├── ldap.conf
├── schema
│   ├── collective.ldif
│   ├── collective.schema
│   ├── corba.ldif
│   ├── corba.schema
│   ├── core.ldif
│   ├── core.schema
│   ├── cosine.ldif
│   ├── cosine.schema
│   ├── dsee.ldif
│   ├── dsee.schema
│   ├── duaconf.ldif
│   ├── duaconf.schema
│   ├── dyngroup.ldif
│   ├── dyngroup.schema
│   ├── inetorgperson.ldif
│   ├── inetorgperson.schema
│   ├── java.ldif
│   ├── java.schema
│   ├── misc.ldif
│   ├── misc.schema
│   ├── msuser.ldif
│   ├── msuser.schema
│   ├── namedobject.ldif
│   ├── namedobject.schema
│   ├── nis.ldif
│   ├── nis.schema
│   ├── openldap.ldif
│   ├── openldap.schema
│   ├── pmi.ldif
│   └── pmi.schema
└── slapd.d
├── cn=config
│   ├── cn=schema
│   │   └── cn={0}core.ldif
│   ├── cn=schema.ldif
│   ├── olcDatabase={0}config.ldif
│   ├── olcDatabase={-1}frontend.ldif
│   ├── olcDatabase={1}monitor.ldif
│   └── olcDatabase={2}mdb.ldif
└── cn=config.ldif

5 directories, 39 files

配置

从openldap2.4.23版本开始,所有配置都保存在/etc/openldap/slapd.d目录下的cn=config文件夹内,不再使用slapd.conf作为配置文件。配置文件的后缀为 ldif,且每个配置文件都是通过命令自动生成的,

# 复制一个默认配置到指定目录下,并授权,这一步一定要做,然后再启动服务,不然生产密码时会报错
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown -R ldap /var/lib/ldap/DB_CONFIG

# 记录生成的加密密码qwe123
[root@ldap ~]# slappasswd -s qwe123
# 将上述密码作为管理密码导入
[root@ldap ~]# cat > ~/chrootpw.ldif <<EOF
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}SJr5jXEbK0VQi56OwFXSDJdizYqPULIs
EOF
[root@ldap ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={0}config,cn=config"

# 导入基本架构
# 依次执行下面的命令,导入基础的一些配置,我这里将所有的都导入一下
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/collective.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/corba.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/duaconf.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/dyngroup.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/java.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/misc.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/openldap.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/pmi.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/ppolicy.ldif

# 设置LDAP的Manager密码qq2211
[root@ldap ~]# slappasswd -s qq2211

# 创建自定义contoso.com的组织架构
[root@ldap ~]# cat > ~/chdomain.ldif <<EOF
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
read by dn.base="cn=Manager,dc=contoso,dc=com" read by * none

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=contoso,dc=com

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=contoso,dc=com

dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}GHsRW7TOj5T0ffYyCkdE9mRKzyPUG9sP

dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by
dn="cn=Manager,dc=srv,dc=world" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=Manager,dc=srv,dc=world" write by * read
EOF

# 导入架构
[root@ldap ~]# ldapmodify -Y EXTERNAL -H ldapi:/// -f chdomain.ldif

#启用memberof功能,开启memberof支持并新增用户支持memberof配置
# 新增add-memberof.ldif, #开启memberof支持并新增用户支持memberof配置
[root@ldap ~]# cat > ./add-memberof.ldif << EOF
dn: cn=module{0},cn=config
cn: modulle{0}
objectClass: olcModuleList
objectclass: top
olcModuleload: memberof.la
olcModulePath: /usr/lib64/openldap

dn: olcOverlay={0}memberof,olcDatabase={2}hdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfUniqueNames
olcMemberOfMemberAD: uniqueMember
olcMemberOfMemberOfAD: memberOf
EOF
[root@ldap ~]# cat > ./refint1.ldif <<EOF
dn: cn=module{0},cn=config
add: olcmoduleload
olcmoduleload: refint
EOF
[root@ldap ~]# cat > ./refint2.ldif <<EOF
dn: olcOverlay=refint,olcDatabase={2}hdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: refint
olcRefintAttribute: memberof uniqueMember manager owner
EOF
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f add-memberof.ldif
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f refint1.ldif
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f refint2.ldif

# 创建组织结构,建立DC和三个OU
[root@ldap ~]# cat > ~/basedomain.ldif <<EOF
dn: dc=contoso,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: CONTOSO Company
dc: contoso

dn: cn=Manager,dc=contoso,dc=com
objectClass: organizationalRole
cn: Manager
description: Directory Manager

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

dn: ou=Group,dc=contoso,dc=com
objectClass: organizationalUnit
ou: Group
EOF
# 创建相应组织和OU,需要输入密码
[root@ldap ~]# ldapadd -x -D cn=Manager,dc=contoso,dc=com -W -f basedomain.ldif
Enter LDAP Password:
adding new entry "dc=contoso,dc=com"

adding new entry "cn=Manager,dc=contoso,dc=com"

adding new entry "ou=People,dc=contoso,dc=com"

adding new entry "ou=Group,dc=contoso,dc=com"

# 配置SSL
wget http://pub.contoso.com/ssl/contoso.com.crt
wget http://pub.contoso.com/ssl/contoso.com.key
mkdir -p /etc/ssl/contoso.com
cp ~/contoso.com.* /etc/ssl/contoso.com
cp /etc/ssl/contoso.com/contoso.com.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust

[root@ldap ~]# cat > ~/mod_ssl.ldif <<EOF
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/contoso.com/contoso.com.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/contoso.com/contoso.com.key
EOF

# 重启服务
[root@ldap ~]# systemctl restart slapd

创建用户

# 增加管理员用户ldapadm,密码为rty456
[root@ldap ~]# slappasswd -h {SSHA} -s rty456
[root@ldap ~]# cat > ./ldapadm.ldif <<EOF
dn: dc=contoso,dc=com
dc: CONTOSO
objectClass: top
objectClass: domaincd
userPassword: {SSHA}NQz/ZsS0WDt+9rFGZ/PspbCAblPKVmJ0
uidNumber: 2000
gidNumber: 2000

dn: cn=ldapadm ,dc=contoso,dc=com
objectClass: organizationalRole
cn: ldapadm
description: LDAP Manager
EOF
[root@ldap ~]# ldapadd -x -W -D "cn=ldapadm,dc=contoso,dc=com" -f ldapadm.ldif

# 增加用户sujx,密码为1234qwer!!
[root@ldap ~]# slappasswd -h {SSHA} -s 123qwe!!
[root@ldap ~]# cat > ./sujx.ldif <<EOF
dn: uid=sujx,ou=People,dc=contoso,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: sujx
userPassword: {SSHA}DxyuX0Q223A9cyjlDn6bj6cFxfhecq7u
description: Test User
EOF
[root@ldap ~]# ldapadd -x -W -D "cn=sujx,dc=contoso,dc=com" -f sujx.ldif

参考

  1. openLDAP的基础概念
  2. 我花了一个五一终于搞懂了OpenLDAP
  3. 一个现代化的LDAP管理工具