本文详细介绍了 OpenLDAP 的命令行操作,涵盖了从基础的用户和组管理(包括用户创建、组分配及成员关系检查)到高级的服务器配置(如
slapd
守护进程的工作原理及其配置方式)。通过具体的 LDIF 文件示例和ldapadd
、ldapmodify
、ldapsearch
等常用工具的演示,帮助读者全面理解和掌握 OpenLDAP 的数据管理与服务器维护。特别强调了从传统slapd.conf
到动态cn=config
配置的演进,并提供了cn=config
的实际修改案例。
OpenLDAP可以使用WEBUI来管理,也可以使用命令行来管理。OpenLDAP的部署请参考 OpenLDAP 部署与基本原理解析(含 Docker Compose 与 Nginx 代理配置)。
我们今天使用命令行来进行LDAP的操作,一步一步演示怎么添加用户和组并将用户添加到组中。
先测试账号密码是否能登录Openldap,再尝试显示DN下所有的对象。
ldapwhoami -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W
Enter LDAP Password:
dn:cn=admin,dc=example,dc=com
ldapsearch -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -b "dc=example,dc=com" "(objectClass=*)"
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (objectClass=*)
# requesting: ALL
#
# example.com
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: MyOrg
dc: example
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
新建一个OU的LDIF文件。
# add_ou_people.ldif
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
description: All people in the organization
添加新的OU。
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_ou_people.ldif
Enter LDAP Password:
adding new entry "ou=People,dc=example,dc=com"
在Openldap内部生成密码哈希。
root@69a9b6c75c35:/# slappasswd -s "userpass"
{SSHA}lP2pSP56cT5EE98/bkvcNY8zJ0bB6O6n
新建一个User的LDIF文件。
# add_test_user.ldif
dn: cn=testu,ou=People,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: testu
sn: User
givenName: Test
mail: test.user@example.com
uid: 1000
userPassword: {SSHA}lP2pSP56cT5EE98/bkvcNY8zJ0bB6O6n
description: General test user account
添加新的User。
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_test_user.ldif
Enter LDAP Password:
adding new entry "cn=testu,ou=People,dc=example,dc=com"
新建一个OU为Groups的LDIF文件。
# add_ou_groups.ldif
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
description: All groups in the organization
添加新的OU Groups。
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_ou_groups.ldif
Enter LDAP Password:
adding new entry "ou=Groups,dc=example,dc=com"
新建一个Group的LDIF文件。
# add_new_group_testg.ldif
dn: cn=testg,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfUniqueNames
cn: testg
description: My new test group
uniqueMember: cn=testu,ou=People,dc=example,dc=com
添加新的Group并分配User。
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_new_group_testg.ldif
Enter LDAP Password:
adding new entry "cn=testg,ou=Groups,dc=example,dc=com"
检查Test User是否属于Test Group。
ldapsearch -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -b "cn=testg,ou=Groups,dc=example,dc=com" "(uniqueMember=cn=testu,ou=People,dc=example,dc=com)" dn
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <cn=testg,ou=Groups,dc=example,dc=com> with scope subtree
# filter: (uniqueMember=cn=testu,ou=People,dc=example,dc=com)
# requesting: dn
#
# testg, Groups, example.com
dn: cn=testg,ou=Groups,dc=example,dc=com
# search result
search: 2
result: 0 Success
# numResponses:
新建一个修改用户的LDIF文件。
# modify_user.ldif
dn: cn=testu,ou=People,dc=example,dc=com
changetype: modify
replace: sn
sn: NewSurname
-
replace: givenName
givenName: NewGivenName
-
add: mobile
mobile: 18812345678
-
delete: mail
更改姓和名,新增手机号码,删除邮件地址。每一项操作中间添加分隔符 -
。
ldapmodify -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f modify_user.ldif
Enter LDAP Password:
modifying entry "cn=testu,ou=People,dc=example,dc=com"
命令行分为客户端和服务端两大类。
下面示例,客户端和服务端在同一个服务器上,所以使用localhost。如果是不在同一个服务器上,则需要指定-H后面的域名或是IP,为了安全考虑,要使用加密连接 如ldaps://IP:636。
ldapsearch
ldapsearch -x -H ldap://localhost:389 -b "dc=example,dc=com" "(objectClass=inetOrgPerson)"
ldapadd
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f new_user.ldif
ldapmodify
ldapmodify -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f modify_user.ldif
ldapdelete
ldapdelete -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W "cn=testu,ou=People,dc=example,dc=com"
ldappasswd
testu
更改自己的密码:ldappasswd -x -H ldap://localhost:389 -D "cn=testu,ou=People,dc=example,dc=com" -W -s "new_password"
testu
用户的密码:ldappasswd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -s "new_password_for_testu" "cn=testu,ou=People,dc=example,dc=com"
ldapwhoami
ldapwhoami -x -H ldap://localhost:389 -D "cn=testu,ou=People,dc=example,dc=com" -W
这些工具通常在 OpenLDAP 服务器主机上运行,并且通常需要 root 权限或 OpenLDAP 用户的权限。譬如在容器内部显示可以用的slap命令。最常用的是数据库的导入导出。
root@69a9b6c75c35:/# slap
slapacl slapadd slapauth slapcat slapd slapdn slapindex slappasswd slapschema slaptest
slapcat
slapcat -b "dc=example,dc=com" -l backup.ldif
slapadd
slapadd -b "dc=example,dc=com" -l backup.ldif
slapindex
slapindex -b "dc=example,dc=com"
slaptest
slapd.conf
或 cn=config
目录) 的语法是否正确。在启动 slapd
服务之前进行配置验证非常有用。 slaptest -f /etc/ldap/slapd.conf -u
slapd
是 OpenLDAP 项目的核心组件,它是 OpenLDAP Directory Server 的守护进程(daemon)。简单来说,slapd
就是 OpenLDAP 服务器本身,它负责处理所有对 LDAP 目录的请求,包括认证、查询、添加、修改和删除条目等。
slapd
监听标准的 LDAP 端口(默认 389 用于非加密连接,636 用于 LDAPS/SSL/TLS 加密连接),等待客户端(如 ldapsearch
, ldapadd
, ldapmodify
等)的连接。slapd
会根据其配置、目录数据和访问控制列表(ACLs)来处理这些请求。slapd
管理后端数据库,负责数据的持久化存储和检索。MDB (Memory-Mapped Database / LMDB) 是由 Symas Corporation 开发,并作为 OpenLDAP 项目的一部分发布的。它现在是 OpenLDAP 默认和推荐的数据库后端。基于文本文件的配置模式。在容器中的位置为/etc/ldap/ldap.conf
。和Nginx的配置文件类似,每次更改配置后需要检查配置有效性并重启服务。文件示例:
root@69a9b6c75c35:/etc/ldap# cat 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-master.example.com:666
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
# TLS certificates (needed for GnuTLS)
TLS_CACERT /container/run/service/slapd/assets/certs/ca.crt
TLS_REQCERT never
关于TLS的配置是Docker Compose里面的环境变量的映射。这种方式已不再使用,进而转变到基于 LDAP 目录本身的动态配置。
cn=config
是一种将 slapd
的配置本身存储为 LDAP 目录中的特殊条目的方式。这意味着你可以像管理普通 LDAP 数据一样,使用标准的 LDAP 工具(如 ldapadd
, ldapmodify
, ldapdelete
)来实时修改 slapd
的配置,而无需重启服务。
cn=config
并不是一个单一的文件。它通常对应文件系统上的一个目录(例如 /etc/ldap/slapd.d/
),该目录下包含一系列的 LDIF 文件,每个文件代表一个配置条目。这些 LDIF 文件在 slapd
启动时被读取并加载到内存中,之后对配置的修改会直接反映在内存中,并同步更新到这些 LDIF 文件。
root@69a9b6c75c35:/etc/ldap# ls slapd.d/
'cn=config' 'cn=config.ldif' docker-openldap-was-admin-password-set docker-openldap-was-started-with-tls
root@69a9b6c75c35:/etc/ldap/slapd.d# ls cn\=config
'cn=module{0}.ldif' 'cn=schema.ldif' 'olcDatabase={-1}frontend.ldif' 'olcDatabase={1}mdb.ldif'
'cn=schema' 'olcDatabase={0}config.ldif' 'olcDatabase={1}mdb'
通过下面的命令可以查看所有的配置,它非常的冗长。
root@69a9b6c75c35:/etc/ldap/slapd.d# ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"
......省略
# {0}memberof, {1}mdb, config
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcMemberOf
olcOverlay: {0}memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfUniqueNames
olcMemberOfMemberAD: uniqueMember
olcMemberOfMemberOfAD: memberOf
# {1}refint, {1}mdb, config
dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
olcOverlay: {1}refint
olcRefintAttribute: owner
olcRefintAttribute: manager
olcRefintAttribute: uniqueMember
olcRefintAttribute: member
olcRefintAttribute: memberOf
......省略
更改配置就和更改其他目录里的条目是类似的。创建一个LDIF文件并应用它。譬如修改上面例子里的配置,olcRefintAttribute
是一个多值属性。
# delete_refint_attr.ldif
dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcRefintAttribute
olcRefintAttribute: owner
修改 cn=config
配置通常需要使用 EXTERNAL
SASL 机制通过 Unix Domain Socket (ldapi:///
) 进行认证。这意味着你需要以 root
用户或 slapd
进程所属的用户身份执行 ldapmodify
命令。在容器内部,就是以root用户运行的。
root@69a9b6c75c35:/etc/ldap/slapd.d# ldapmodify -Y EXTERNAL -H ldapi:/// -f delete_refint_attr.ldif
更多内容持续更新于我的博客:https://www.zenseek.site
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。