OpenLDAP 是 LDAP 的开源实现,服务端工具集的名字以 slap (stand-alone LDAP) 为前缀,客户端工具集的名字以 ldap 为前缀。
从 2.4 版本开始,slapd 的配置使用 LDIF 格式进行定义(man slapd-config),以 DIT(Directory Information Tree) 的组织形式存储在指定的配置文件夹中,原有的配置文件格式(man slapd.conf)在未来的版本中将可能被废弃。
http://www.openldap.org/doc/admin24/guide.html#Configuring slapd
1. 安装
1.1 CentOS 7
~$ rpm -qi openldap-servers
Name : openldap-servers
Version : 2.4.44
Release : 21.el7_6
...
~$ yum whatprovides */ldapsearch
...
openldap-clients-2.4.44-20.el7.x86_64 : LDAP client utilities
Repo : os
Matched from:
Filename : /usr/bin/ldapsearch
~$ sudo yum install openldap-clients
~$ rpm -ql openldap-servers
/etc/openldap/check_password.conf
/etc/openldap/schema
/etc/openldap/schema/collective.ldif
...
/etc/openldap/slapd.conf
/etc/openldap/slapd.d
/etc/sysconfig/slapd
...
/usr/sbin/slapacl
/usr/sbin/slapadd
/usr/sbin/slapauth
/usr/sbin/slapcat
/usr/sbin/slapd
/usr/sbin/slapdn
/usr/sbin/slapindex
/usr/sbin/slappasswd
/usr/sbin/slapschema
/usr/sbin/slaptest
...
/usr/share/openldap-servers/DB_CONFIG.example
/usr/share/openldap-servers/slapd.ldif
...
~$ rpm -ql openldap-clients
/usr/bin/ldapadd
/usr/bin/ldapcompare
/usr/bin/ldapdelete
/usr/bin/ldapexop
/usr/bin/ldapmodify
/usr/bin/ldapmodrdn
/usr/bin/ldappasswd
/usr/bin/ldapsearch
/usr/bin/ldapurl
/usr/bin/ldapwhoami
...
看看 slapd 是如何生成初始配置的:
~$ rpm -q --scripts openldap-servers
...
postinstall scriptlet (using /bin/sh):
...
# generate sample TLS certificate for server (will not replace)
/usr/libexec/openldap/generate-server-cert.sh -o &>/dev/null || :
# generate/upgrade configuration
if [ ! -f /etc/openldap/slapd.d/cn=config.ldif ]; then
if [ -f /etc/openldap/slapd.conf ]; then
/usr/libexec/openldap/convert-config.sh &>/dev/null
mv /etc/openldap/slapd.conf /etc/openldap/slapd.conf.bak
else
/usr/libexec/openldap/convert-config.sh -f /usr/share/openldap-servers/slapd.ldif &>/dev/null
fi
fi
...
1.2 Ubuntu 18.04
~$ dpkg -s slapd
Package: slapd
Status: install ok installed
Priority: optional
Section: net
Installed-Size: 15450
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Source: openldap
Version: 2.4.45+dfsg-1ubuntu1.2
...
~$ dpkg -L slapd
/.
/etc
/etc/apparmor.d
/etc/apparmor.d/usr.sbin.slapd
/etc/default
/etc/default/slapd
/etc/init.d
/etc/init.d/slapd
/etc/ldap
/etc/ldap/sasl2
/etc/ldap/schema
/etc/ldap/schema/README
/etc/ldap/schema/collective.ldif
...
/etc/ufw
/etc/ufw/applications.d
/etc/ufw/applications.d/slapd
...
/usr/sbin/slapacl
/usr/sbin/slapadd
/usr/sbin/slapauth
/usr/sbin/slapcat
/usr/sbin/slapd
/usr/sbin/slapdn
/usr/sbin/slapindex
/usr/sbin/slappasswd
/usr/sbin/slapschema
/usr/sbin/slaptest
...
/usr/share/slapd/DB_CONFIG
/usr/share/slapd/ldiftopasswd
/usr/share/slapd/slapd.conf
/usr/share/slapd/slapd.init.ldif
...
~$ dpkg -L ldap-utils
...
/usr/bin/ldapcompare
/usr/bin/ldapdelete
/usr/bin/ldapexop
/usr/bin/ldapmodify
/usr/bin/ldapmodrdn
/usr/bin/ldappasswd
/usr/bin/ldapsearch
/usr/bin/ldapurl
/usr/bin/ldapwhoami
...
看看 slapd 是如何生成初始配置的:
# debian/slapd.postinst
postinst_initial_configuration() { # {{{
# Configure slapd for the first time (when first installed)
# Usage: postinst_initial_configuration
if manual_configuration_wanted; then
echo " Omitting slapd configuration as requested." >&2
else
crypt_admin_pass
create_new_configuration
fi
}
# Configuration.
if is_initial_configuration "$@"; then
postinst_initial_configuration
else
postinst_upgrade_configuration
fi
# debian/slapd.scripts-common
create_new_configuration() { # {{{
# Create a new configuration and directory
local basedn dc backend
# For the domain really.argh.org we create the basedn
# dc=really,dc=argh,dc=org with the dc entry dc: really
db_get slapd/domain
basedn="dc=`echo $RET | sed 's/^\.//; s/\.$//; s/\./,dc=/g'`"
dc="`echo $RET | sed 's/^\.//; s/\..*$//'`"
db_get slapd/backend
backend="`echo $RET|tr A-Z a-z`"
backup_config_once
if [ -e "/var/lib/ldap" ] && ! is_empty_dir /var/lib/ldap; then
echo >&2 " Moving old database directory to /var/backups:"
move_old_database_away /var/lib/ldap
fi
create_ldap_directories
create_new_slapd_conf "$basedn" "$backend"
create_new_directory "$basedn" "$dc"
# Put the right permissions on this directory.
update_permissions /var/lib/ldap
# Now that we created the new directory we don't need the passwords in the
# debconf database anymore. So wipe them.
wipe_admin_pass
}
在 debian 系发行版下,初始化 slapd 配置可以使用如下的交互式方式:
~$ sudo dpkg-reconfigure slapd
1.3 docker
~$ docker pull osixia/openldap
~$ docker run -idt --net host --rm osixia/openldap
注意:使用 host
容器网络需要确保主机自身没有 slapd 服务(即 OpenLDAP 服务)已启用,否则会因为端口冲突导致容器进程启动失败。
2. 配置
通过 slapcat 命令可以以 LDIF 格式查看当前 OpenLDAP 数据库的内容。
~# slapcat -b cn=config
或者:
~# slapcat -n 0
其中数据库名(suffix) cn=config
或者编号 0
是 OpenLDAP 自身的配置数据库,而用户数据库名或编号可以通过查询配置数据库得到。
2.1 CentOS 7
2.1.1 删除配置及用户数据库
~# systemctl stop slapd
~# rm -rf /etc/openldap/slapd.d/*
~# rm -f /var/lib/ldap/*
2.1.2 定义配置及用户数据库
~$ cp /usr/share/openldap-servers/slapd.ldif .
~$ vi slapd.ldif
--- /usr/share/openldap-servers/slapd.ldif 2019-01-30 01:43:29.000000000 +0800
+++ slapd.ldif 2019-06-06 10:00:46.031012384 +0800
@@ -11,9 +11,9 @@
#
# TLS settings
#
-olcTLSCACertificatePath: /etc/openldap/certs
-olcTLSCertificateFile: "OpenLDAP Server"
-olcTLSCertificateKeyFile: /etc/openldap/certs/password
+#olcTLSCACertificatePath: /etc/openldap/certs
+#olcTLSCertificateFile: "OpenLDAP Server"
+#olcTLSCertificateKeyFile: /etc/openldap/certs/password
#
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
@@ -131,18 +131,19 @@
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,c
- n=auth" read by dn.base="cn=Manager,dc=my-domain,dc=com" read by * none
+ n=auth" read by dn.base="cn=admin,dc=runsisi,dc=com" read by * none
#
# Backend database definitions
#
-dn: olcDatabase=hdb,cn=config
+dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
-objectClass: olcHdbConfig
-olcDatabase: hdb
-olcSuffix: dc=my-domain,dc=com
-olcRootDN: cn=Manager,dc=my-domain,dc=com
+objectClass: olcMdbConfig
+olcDatabase: mdb
+olcSuffix: dc=runsisi,dc=com
+olcRootDN: cn=admin,dc=runsisi,dc=com
+olcRootPW: {SSHA}UNC/GjBr74HdBGx92smagS0sjP0HhT2u
olcDbDirectory: /var/lib/ldap
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
其中 olcSuffix 是用户数据库名,olcRootPW 是 OpenLDAP 管理员密码,使用 slappasswd 生成。
这里禁用了 tls,因为 rpm 包的 postinst 脚本无法正确的生成证书,如果需要启用 tls 可以阅读参考资料中的相关链接。
2.1.3 生成配置数据
~# slapadd -F /etc/openldap/slapd.d/ -n 0 -l slapd.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
或者:
~# slapadd -F /etc/openldap/slapd.d/ -b cn=config -l slapd.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
2.1.4 查看配置数据
~# slapcat -n 0
...
dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
al,cn=auth" manage by * none
structuralObjectClass: olcDatabaseConfig
entryUUID: 6e901e92-1c4b-1039-9278-c58c446c6567
creatorsName: cn=config
createTimestamp: 20190606020625Z
entryCSN: 20190606020625.057105Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190606020625Z
dn: olcDatabase={1}monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {1}monitor
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
al,cn=auth" read by dn.base="cn=admin,dc=runsisi,dc=com" read by * none
structuralObjectClass: olcDatabaseConfig
entryUUID: 6e903fda-1c4b-1039-9279-c58c446c6567
creatorsName: cn=config
createTimestamp: 20190606020625Z
entryCSN: 20190606020625.057957Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190606020625Z
dn: olcDatabase={2}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {2}mdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=runsisi,dc=com
olcRootDN: cn=admin,dc=runsisi,dc=com
olcRootPW:: e1NTSEF9VU5DL0dqQnI3NEhkQkd4OTJzbWFnUzBzalAwSGhUMnU=
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
structuralObjectClass: olcMdbConfig
entryUUID: 6e904bc4-1c4b-1039-927a-c58c446c6567
creatorsName: cn=config
createTimestamp: 20190606020625Z
entryCSN: 20190606020625.058262Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190606020625Z
2.1.5 启用服务
启用服务时用户数据库会自动创建。
~# chown -R ldap.ldap /etc/openldap/slapd.d/
~# chown ldap.ldap /var/lib/ldap/
~# chmod 700 /var/lib/ldap/
~# systemctl start slapd
2.1.6 创建用户 DIT
DIT 名称空间(根目录,suffix, namingContexts)定义的约定可以查看如下链接:
https://ldap.com/dit-and-the-ldap-root-dse/
~$ vi root.ldif
dn: dc=runsisi,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
dc: runsisi
o: my own company
注意这里的 dn 需要与用户数据库中定义的 olcSuffix 一致(即用户数据库与用户 DIT 两者的名称空间命名要一致),否则会报如下的错:
~# slapadd -F /etc/openldap/slapd.d/ -n 2 -l root.ldif
slapadd: line 1: database #2 (dc=runsisi,dc=com) not configured to hold "dc=hustlrb,dc=com"; no database configured for that naming context
_#################### 100.00% eta none elapsed none fast!
Closing DB...
~# slapadd -F /etc/openldap/slapd.d/ -b dc=runsisi,dc=com -l root.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
或者:
~# slapadd -F /etc/openldap/slapd.d/ -n 2 -l root.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
注意:-n
指定的数据库编号通过前面的 slapcat 得到。
2.2 Ubuntu 18.04
2.2.1 删除配置及用户数据库
~# systemctl stop slapd
~# rm -rf /etc/ldap/slapd.d/*
~# rm -f /var/lib/ldap/*
2.2.2 定义配置及用户数据库
~$ cp /usr/share/slapd/slapd.init.ldif .
~$ vi slapd.init.ldif
--- /usr/share/slapd/slapd.init.ldif 2018-10-23 21:01:47.000000000 +0800
+++ slapd.init.ldif 2019-06-05 15:38:56.773924017 +0800
@@ -49,32 +49,32 @@
cn: module{0}
# Where the dynamically loaded modules are stored
olcModulePath: /usr/lib/ldap
-olcModuleLoad: back_@BACKEND@
+olcModuleLoad: back_mdb
# Set defaults for the backend
-dn: olcBackend=@BACKEND@,cn=config
+dn: olcBackend=mdb,cn=config
objectClass: olcBackendConfig
-olcBackend: @BACKEND@
+olcBackend: mdb
# The database definition.
-dn: olcDatabase=@BACKEND@,cn=config
+dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
-objectClass: @BACKENDOBJECTCLASS@
-olcDatabase: @BACKEND@
+objectClass: olcMdbConfig
+olcDatabase: mdb
# Checkpoint the database periodically in case of system
# failure and to speed slapd shutdown.
olcDbCheckpoint: 512 30
-@BACKENDOPTIONS@
+olcDbMaxSize: 1073741824
# Save the time that the entry gets modified, for database #1
olcLastMod: TRUE
# The base of your directory in database #1
-olcSuffix: @SUFFIX@
+olcSuffix: dc=runsisi,dc=com
# Where the database file are physically stored for database #1
olcDbDirectory: /var/lib/ldap
# olcRootDN directive for specifying a superuser on the database. This
# is needed for syncrepl.
-olcRootDN: cn=admin,@SUFFIX@
-olcRootPW: @PASSWORD@
+olcRootDN: cn=admin,dc=runsisi,dc=com
+olcRootPW: {SSHA}UNC/GjBr74HdBGx92smagS0sjP0HhT2u
# Indexing options for database #1
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
其中 olcSuffix 是用户数据库名,olcRootPW 是 OpenLDAP 管理员密码,使用 slappasswd 生成。
olcRootPW 的修改也可以后期通过 ldapmodify 进行修改:
~$ vi xxx.ldif
dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}UNC/GjBr74HdBGx92smagS0sjP0HhT2u
2.2.3 生成配置数据
~# slapadd -F /etc/ldap/slapd.d/ -b cn=config -l slapd.init.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
或者:
~# slapadd -F /etc/ldap/slapd.d/ -n 0 -l slapd.init.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
2.2.4 查看配置数据
~# slapcat -n 0
...
dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=extern
al,cn=auth manage by * break
structuralObjectClass: olcDatabaseConfig
entryUUID: 9649c6be-1c45-1039-9dd0-35ab91e2fabd
creatorsName: cn=config
createTimestamp: 20190606012434Z
entryCSN: 20190606012434.724590Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190606012434Z
dn: olcDatabase={1}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=runsisi,dc=com
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * non
e
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
olcLastMod: TRUE
olcRootDN: cn=admin,dc=runsisi,dc=com
olcRootPW:: e1NTSEF9VU5DL0dqQnI3NEhkQkd4OTJzbWFnUzBzalAwSGhUMnU=
olcDbCheckpoint: 512 30
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq
olcDbMaxSize: 1073741824
structuralObjectClass: olcMdbConfig
entryUUID: 964a75e6-1c45-1039-9dd8-35ab91e2fabd
creatorsName: cn=config
createTimestamp: 20190606012434Z
entryCSN: 20190606012434.729075Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190606012434Z
2.2.5 启用服务
启用服务时用户数据库会自动创建。
~# chown -R openldap.openldap /etc/ldap/slapd.d/
~# chown openldap.openldap /var/lib/ldap/
~# chmod 700 /var/lib/ldap/
~# systemctl start slapd
2.2.6 创建用户 DIT
~$ vi root.ldif
dn: dc=runsisi,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
dc: runsisi
o: my own company
注意这里的 dn 需要与用户数据库中定义的 olcSuffix 一致(即用户数据库与用户 DIT 两者的名称空间命名要一致),否则会报如下的错:
~# slapadd -F /etc/ldap/slapd.d/ -n 1 -l root.ldif
slapadd: line 1: database #1 (dc=runsisi,dc=com) not configured to hold "dc=hustlrb,dc=com"; no database configured for that naming context
_#################### 100.00% eta none elapsed none fast!
Closing DB...
~# slapadd -F /etc/ldap/slapd.d/ -b dc=runsisi,dc=com -l root.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
或者:
~# slapadd -F /etc/ldap/slapd.d/ -n 1 -l root.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
注意:-n
指定的数据库编号通过前面的 slapcat 得到。
2.3 docker
docker-openldap 镜像所创建的容器可以通过环境变量进行配置,具体的可以参考其 github 项目主页的 readme 文档。
4. 参考资料
Step by Step OpenLDAP Server Configuration on CentOS 7 / RHEL 7
Configure OpenLDAP with SSL on CentOS 7 / RHEL 7
CentOS openLDAP cert trust issues
https://serverfault.com/questions/437546/centos-openldap-cert-trust-issues
A docker image to run OpenLDAP
https://github.com/osixia/docker-openldap
最后修改于 2019-06-04