Ubuntu 22.04 安装 OpenLDAP 2.5.20 指南
Ubuntu 22.04 从零安装 OpenLDAP 2.5.20 实测:debconf 静默安装与重配域、组织结构与用户导入、ACL 收紧、自签 TLS 与远程客户端验证,全部命令回显实测。
Ubuntu 22.04 安装 OpenLDAP 2.5.20 指南
目标:在一台 Ubuntu 22.04 服务器上从零安装 OpenLDAP 2.5.20(slapd 2.5.20+dfsg-0ubuntu0.22.04.1),完成域初始化(dc=lab,dc=local)、组织结构与用户导入、ACL 收紧、TLS(自签证书 ldaps/StartTLS)与远程客户端验证,全流程命令与回显均已在真实环境实测通过。
一、环境信息
本文实测环境:
- 操作系统:Ubuntu 22.04.5 LTS(amd64)
- 主机名:ldap01.lab.local(FQDN)
- 内网 IP:10.89.63.2
- 软件版本:slapd 2.5.20+dfsg-0ubuntu0.22.04.1、ldap-utils 2.5.20+dfsg-0ubuntu0.22.04.1(均来自 Ubuntu jammy-updates/main 官方仓库)、openssl 3.0.2-0ubuntu1.30
- 目录域(suffix):dc=lab,dc=local
- 管理员 DN:cn=admin,dc=lab,dc=local,密码 q1w2e3r4
- 端口:389(ldap)、636(ldaps)、Unix socket(ldapi:///,本地管理)
- 数据目录:/var/lib/ldap;配置目录:/etc/ldap/(cn=config 树位于 /etc/ldap/slapd.d/)
💡 说明:Ubuntu 22.04 仓库的 slapd 是上游 2.5 系最终版 2.5.20 的发行版打包。官网最新稳定版为 2.7.1(feature)/2.6.15(LTS),apt 渠道装不到,需源码编译,版本口径详见《OpenLDAP 2.7.1 介绍与选型指南》。
二、前置条件
- 一台 Ubuntu 22.04 服务器(物理机或虚拟机均可),具备 sudo 权限的账号;
- 服务器可访问 Ubuntu 官方软件源(archive.ubuntu.com / security.ubuntu.com;内网环境需配置镜像源或代理);
- 规划好目录域:本文用
dc=lab,dc=local,对应组织域名lab.local; - 主机名建议设为该域下的 FQDN(如 ldap01.lab.local)——slapd 安装时会从主机名推导默认域,FQDN 与目标域一致可省去重配(原理见 11.1);
- 确认 389/636 端口未被占用:
ss -ltn | grep -E ':389|:636'
实测回显(空闲时应无输出):
(无输出,端口空闲)
- TLS 章节需要 openssl 签发证书。Ubuntu Server 22.04 通常自带;最小化系统可能没有,先确认:
which openssl || echo "openssl not installed"
实测回显(最小化环境):
openssl not installed
缺失则安装:
sudo apt-get install -y openssl
实测回显(输出节选):
Setting up openssl (3.0.2-0ubuntu1.30) ...
三、版本选型说明
安装前先看仓库里 slapd 的候选版本:
sudo apt update && apt-cache policy slapd
实测回显(输出节选):
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [4759 kB]
Fetched 12.5 MB in 9s (1437 kB/s)
Reading package lists...
slapd:
Installed: (none)
Candidate: 2.5.20+dfsg-0ubuntu0.22.04.1
Version table:
2.5.20+dfsg-0ubuntu0.22.04.1 500
500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
2.5.16+dfsg-0ubuntu0.22.04.2 500
500 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages
版本结论:
- Ubuntu 22.04 在线仓库候选版即 2.5.20+dfsg-0ubuntu0.22.04.1(上游 2.5.20,2025-09-24 打包),本文主线安装此版本;
- 官网 2.6.15(LTS)/2.7.1(feature)仅源码发布,编译安装见官网 Admin Guide 的 Quick Start(https://www.openldap.org/doc/admin26/quickstart.html),不在本篇展开;
- 与 OpenLDAP 同类的其他目录服务(389DS、ApacheDS、FreeIPA、Samba AD)的对比见《OpenLDAP 2.7.1 介绍与选型指南》。
四、安装方案 A:Ubuntu 仓库 apt 在线安装(预置 debconf 静默安装)
4.1 方案说明
Ubuntu 的 slapd 包在安装时会通过 debconf 向导询问四个问题:目录域、管理员密码(两次确认)、是否允许 LDAPv2、数据库是否随卸载删除。自动化安装(脚本/批量装机)推荐用 debconf-set-selections 预置答案再静默安装,一次成型。本方案的目标配置:域 lab.local(dc=lab,dc=local)、管理员密码 q1w2e3r4。
4.2 预置 debconf 答案
sudo debconf-set-selections << "EOF"
slapd slapd/domain string lab.local
slapd shared/organization string lab.local
slapd slapd/password1 password q1w2e3r4
slapd slapd/password2 password q1w2e3r4
slapd slapd/no_configuration boolean false
slapd slapd/allow_ldap_v2 boolean false
slapd slapd/purge_database boolean false
slapd slapd/move_old_database boolean true
slapd slapd/dump_database select when needed
EOF
实测无输出即预置成功。各答案含义:
| 问题 | 预置值 | 说明 |
|---|---|---|
| slapd/domain 与 shared/organization | lab.local | 目录域,生成 dc=lab,dc=local 后缀,两个问题必须同时给 |
| password1/password2 | q1w2e3r4 | cn=admin,dc=lab,dc=local 的管理员口令,两次一致 |
| no_configuration | false | 走标准初始化(true 会跳过配置生成) |
| allow_ldap_v2 | false | 关闭已废弃的 LDAPv2 |
| purge_database | false | 卸载时保留数据库 |
| move_old_database | true | 重装时自动迁移旧库(⚠️ 必须为 true,false 的后果见 11.2) |
| dump_database | when needed | 升级/重配前自动 dump 备份到 /var/backups/slapd-版本号/ |
4.3 静默安装
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y slapd ldap-utils
实测回显(输出节选,实测首尾):
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
ldap-utils liblber-2.5-0 libldap-2.5-0 slapd
Setting up slapd (2.5.20+dfsg-0ubuntu0.22.04.1) ...
Creating new user openldap... done.
Creating initial configuration... done.
Creating LDAP directory... done.
Setting up ldap-utils (2.5.20+dfsg-0ubuntu0.22.04.1) ...
安装器创建了 openldap 运行账号、生成了初始 cn=config 配置并初始化了目录库。Ubuntu 的 slapd 包安装完成即由 systemd 自动启动。
4.4 验证服务与域
systemctl is-active slapd
实测回显:
active
查看数据库后缀与根 DN(cn=config 配置库,编号 -n 0):
sudo slapcat -n 0 | grep -E 'olcSuffix|olcRootDN:'
实测回显:
olcRootDN: cn=admin,cn=config
olcSuffix: dc=lab,dc=local
olcRootDN: cn=admin,dc=lab,dc=local
用管理员口令验证绑定(本地 ldapi socket):
ldapwhoami -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4
实测回显:
dn:cn=admin,dc=lab,dc=local
绑定成功且回显身份 DN,安装与域初始化闭环完成。
五、安装方案 B:交互安装与 dpkg-reconfigure 重配域
5.1 方案说明
未预置 debconf 直接交互安装、或安装后想改域/改管理员密码,用 dpkg-reconfigure slapd 重走向导。本方案演示:在已装好的机器上把配置重配为 lab.local + 密码 q1w2e3r4(与方案 A 等效,也是「装错了域怎么改」的标准做法)。
5.2 交互式重配
sudo dpkg-reconfigure slapd
交互向导依次回答(每屏一个):
DNS domain name:输入lab.local(生成 dc=lab,dc=local);Organization name:输入lab.local;Administrator password:输入q1w2e3r4;Confirm administrator password:再次输入q1w2e3r4;Move old database?选<Yes>(把旧库转存到 /var/backups 后重建,⚠️ 选 No 会撞库报错,见 11.2);Allow LDAPv2 protocol?选<No>。
脚本化等价写法(预置答案 + 非交互重配):
sudo debconf-set-selections << "EOF"
slapd slapd/domain string lab.local
slapd shared/organization string lab.local
slapd slapd/password1 password q1w2e3r4
slapd slapd/password2 password q1w2e3r4
slapd slapd/move_old_database boolean true
slapd slapd/dump_database select when needed
slapd slapd/purge_database boolean false
slapd slapd/no_configuration boolean false
slapd slapd/allow_ldap_v2 boolean false
EOF
sudo dpkg-reconfigure -f noninteractive slapd
实测回显(输出节选,实测首尾):
Backing up /etc/ldap/slapd.d in /var/backups/slapd-2.5.20+dfsg-0ubuntu0.22.04.1... done.
- directory unknown... done.
Creating initial configuration... done.
Creating LDAP directory... done.
5.3 重配后验证
重配会重建目录与配置,slapd 会按需重启。逐项验证:
systemctl is-active slapd
ldapwhoami -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4
sudo slapcat -b dc=lab,dc=local | grep '^dn:'
实测回显:
active
dn:cn=admin,dc=lab,dc=local
dn: dc=lab,dc=local
服务 active、新口令绑定成功、目录中已有根条目 dc=lab,dc=local,重配闭环完成。
六、方案对比与选择建议
| 维度 | 方案 A(预置 debconf 静默安装) | 方案 B(交互安装 / dpkg-reconfigure) |
|---|---|---|
| 适用 | 脚本、批量装机、Ansible/user-data | 单台手工装机、装错后改域改密码 |
| 域与密码设定 | 安装前预置,一次成型 | 向导逐屏回答 |
| 可重复性 | 完全可重复 | 依赖人工输入 |
| 失败风险 | 预置答案缺项时行为回退(见 11.1/11.2) | 选错「Move old database」撞库(见 11.2) |
选择建议:可自动化场景一律用方案 A;单台手工装或补救时用方案 B。两方案产物完全一致,可混用(先 A 装好后需要改域再走 B 的 dpkg-reconfigure)。
七、安装后配置说明
7.1 服务默认项 /etc/default/slapd
grep -vE '^#|^$' /etc/default/slapd
实测回显:
SLAPD_CONF=
SLAPD_USER="openldap"
SLAPD_GROUP="openldap"
SLAPD_PIDFILE=
SLAPD_SERVICES="ldap:/// ldapi:///"
SLAPD_SENTINEL_FILE=/etc/ldap/noslapd
SLAPD_OPTIONS=""
逐项解释:
SLAPD_CONF=:空=走 cn=config 在线配置(/etc/ldap/slapd.d/);填 /etc/ldap/slapd.conf 路径则切老式单文件配置,二选一(双口径,见 7.3);SLAPD_USER/GROUP:服务运行身份 openldap;SLAPD_SERVICES:监听 URL 列表。默认只有 ldap:///(389)与 ldapi:///(本地 socket),没有 ldaps:///(636)——TLS 章节要启用 636 必须在此加 ldaps:///(见 10.6);SLAPD_SENTINEL_FILE:存在 /etc/ldap/noslapd 文件时 init 脚本拒绝启动(判断文件存在性的保护开关)。
7.2 文件与目录布局
ls -la /etc/ldap/ && sudo ls /var/lib/ldap/
实测回显:
total 28
drwxr-xr-x 5 root root 4096 Oct 27 02:49 .
drwxr-xr-x 1 root root 4096 Oct 27 02:49 ..
-rw-r--r-- 1 root root 334 Sep 24 2025 ldap.conf
drwxr-xr-x 2 root root 4096 Sep 24 2025 sasl2
drwxr-xr-x 2 root root 4096 Oct 27 02:49 schema
drwxr-x--- 3 openldap openldap 4096 Oct 27 02:49 slapd.d
data.mdb
lock.mdb
/etc/ldap/ldap.conf:客户端全局配置(BASE/URI/TLS 信任),改它不影响服务端;/etc/ldap/schema/:schema 源文件(core/cosine/nis/inetorgperson 等);/etc/ldap/slapd.d/:cn=config 在线配置树(LDIF 文件形态),服务端配置真身;/var/lib/ldap/:mdb 数据库文件(data.mdb/lock.mdb);/var/backups/slapd-<版本>/:重配/升级时自动 dump 的备份(排障时注意它会被自动恢复,见 11.3)。
7.3 slapd.conf 与 cn=config 双口径
OpenLDAP 2.4 起提供两套配置机制:
- cn=config(推荐):配置是 LDAP 树(dn: cn=config),用 ldapmodify 在线改,
sudo slapcat -n 0导出全树;文件落在 /etc/ldap/slapd.d/ 但禁止手改(内部有 CRC 与序号约定,手改会丢失改动); - slapd.conf(老式):单文本文件,改完 systemctl restart slapd 生效;Ubuntu 默认不启用(SLAPD_CONF 为空),需要时填 /etc/default/slapd 的 SLAPD_CONF 切换。
本篇全部用 cn=config 口径;参数逐项修改-验证的完整详解见本专栏《OpenLDAP 2.5.20 配置参数详解》篇。
7.4 客户端全局配置 /etc/ldap/ldap.conf
服务器本机 ldap-utils 默认走 ldapi:/// 或显式 -H 参数,通常无需改。若想让本机命令默认连本目录,可设置:
sudo tee -a /etc/ldap/ldap.conf > /dev/null << "EOF"
BASE dc=lab,dc=local
URI ldap://ldap01.lab.local
TLS_CACERT /etc/ssl/certs/lab-ca.crt
EOF
追加三行后,ldapsearch -x uid=zhangsan 不再需要 -b/-H。本文为清晰起见,命令一律显式带参。
八、导入组织结构与用户
8.1 创建组织单元(ou)
规划两个组织单元:ou=people(用户)、ou=groups(组)。先写 LDIF:
sudo tee /root/ou.ldif > /dev/null << "EOF"
dn: ou=people,dc=lab,dc=local
objectClass: organizationalUnit
ou: people
dn: ou=groups,dc=lab,dc=local
objectClass: organizationalUnit
ou: groups
EOF
用 ldapadd 以管理员身份导入:
ldapadd -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -f /root/ou.ldif
实测回显:
adding new entry "ou=people,dc=lab,dc=local"
adding new entry "ou=groups,dc=lab,dc=local"
8.2 生成 SSHA 口令哈希
slappasswd 以随机盐生成 {SSHA} 哈希(盐随机,每次输出不同,属正常现象):
slappasswd -s q1w2e3r4
实测回显(本次实测输出,你的输出会不同):
{SSHA}PwLIYbldg1JnQCrMM4OY5D4XY/Ia0bti
8.3 导入用户与 posixGroup
sudo tee /root/users.ldif > /dev/null << "EOF"
dn: uid=zhangsan,ou=people,dc=lab,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: zhangsan
cn: Zhang San
sn: Zhang
givenName: San
userPassword: {SSHA}PwLIYbldg1JnQCrMM4OY5D4XY/Ia0bti
uidNumber: 10001
gidNumber: 20001
homeDirectory: /home/zhangsan
loginShell: /bin/bash
dn: uid=lisi,ou=people,dc=lab,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: lisi
cn: Li Si
sn: Li
givenName: Si
userPassword: {SSHA}PwLIYbldg1JnQCrMM4OY5D4XY/Ia0bti
uidNumber: 10002
gidNumber: 20001
homeDirectory: /home/lisi
loginShell: /bin/bash
dn: cn=developers,ou=groups,dc=lab,dc=local
objectClass: posixGroup
cn: developers
gidNumber: 20001
memberUid: zhangsan
memberUid: lisi
EOF
ldapadd -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -f /root/users.ldif
实测回显:
adding new entry "uid=zhangsan,ou=people,dc=lab,dc=local"
adding new entry "uid=lisi,ou=people,dc=lab,dc=local"
adding new entry "cn=developers,ou=groups,dc=lab,dc=local"
LDIF 要点:userPassword 直接填 {SSHA} 哈希值;inetOrgPerson 提供姓名属性、posixAccount/shadowAccount 提供类 Unix 账号属性(供 SSSD/NSS 取用)、posixGroup 的 memberUid 存成员 uid(注意它存的是 uid 而非 DN,与 groupOfNames 的 member 属性语义不同,memberof 反解的差异见《配置参数详解》)。
九、访问控制(ACL)与查询验证
9.1 默认 ACL 实测
Ubuntu 打包的默认 ACL(olcDatabase={1}mdb 的 olcAccess,三条):
ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=config '(olcDatabase={1}mdb)' olcAccess
实测回显(输出节选):
dn: olcDatabase={1}mdb,cn=config
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
语义逐条解读:
{0}:userPassword 属性——本人可写(by self write)、匿名只能用它做认证绑定(by anonymous auth,不能读出值)、其余人无权限;{1}:shadowLastChange——本人可写,所有人可读(配合密码过期策略);{2}:其余全部属性——所有人对全部条目可读(内网开放目录的常见默认,生产按需收紧)。
验证匿名搜索读不到密码哈希:
ldapsearch -x -H ldapi:/// -b dc=lab,dc=local '(uid=zhangsan)' uid cn userPassword
实测回显(输出节选):
dn: uid=zhangsan,ou=people,dc=lab,dc=local
uid: zhangsan
cn: Zhang San
匿名能查到 uid/cn,userPassword 整个属性被 ACL 隐藏(连空值都不返回),{0} 条生效。
9.2 收紧 ACL:禁止匿名读
生产建议把 {2} 从「人人可读」收紧为「认证用户可读」。用 ldapmodify 整体替换 olcAccess(olcAccess 为多值有序属性,先 delete 再 add):
sudo tee /root/acl.ldif > /dev/null << "EOF"
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by self write by users read by * none
EOF
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /root/acl.ldif
实测回显:
modifying entry "olcDatabase={1}mdb,cn=config"
-Q -Y EXTERNAL 走 ldapi socket 的 SASL EXTERNAL 认证,本地 root 等价 cn=config 管理员,无需密码(机制见《配置参数详解》 frontend 库一节)。
9.3 验证收紧效果
匿名再搜(预期被拒):
ldapsearch -x -H ldapi:/// -b dc=lab,dc=local '(uid=zhangsan)' dn 2>&1 | tail -4
实测回显:
search: 2
result: 32 No such object
认证用户再搜(预期可读):
ldapsearch -x -H ldapi:/// -D "uid=zhangsan,ou=people,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local '(uid=lisi)' dn | grep -c '^dn:'
实测回显:
1
⚠️ ACL 语义坑:匿名无权限时返回的不是 49(凭据错误)而是 32 No such object——LDAP 用「装作不存在」防信息泄露。排查「明明有条目却报 32」时先查 ACL 再怀疑数据。
9.4 全量条目验证
以管理员列出全目录 DN:
ldapsearch -LLL -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local '(objectClass=*)' dn
实测回显(输出节选):
dn: dc=lab,dc=local
dn: ou=people,dc=lab,dc=local
dn: ou=groups,dc=lab,dc=local
dn: uid=zhangsan,ou=people,dc=lab,dc=local
dn: uid=lisi,ou=people,dc=lab,dc=local
dn: cn=developers,ou=groups,dc=lab,dc=local
6 条条目齐整,目录结构与数据导入完成。
十、TLS 配置(自签证书)
10.1 生成自签 CA 与服务器证书
用 openssl 生成 10 年期自签 CA,再签发 ldap01 服务器证书(SAN 必须含服务器名,否则客户端校验不过):
sudo mkdir -p /etc/ldap/tls && cd /etc/ldap/tls
sudo openssl req -x509 -newkey rsa:2048 -keyout ca.key -out ca.crt -days 3650 -nodes -subj "/CN=Lab Root CA/O=Lab"
sudo openssl req -newkey rsa:2048 -keyout server.key -out server.csr -nodes -subj "/CN=ldap01.lab.local/O=Lab"
printf "subjectAltName=DNS:ldap01.lab.local,IP:10.89.63.2\n" | sudo tee ext.cnf > /dev/null
sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 825 -extfile ext.cnf
实测回显(输出节选):
Certificate request self-signature ok
subject=CN = ldap01.lab.local, O = Lab
查看签发结果:
sudo openssl x509 -in server.crt -noout -subject -dates -ext subjectAltName
实测回显:
subject=CN = ldap01.lab.local, O = Lab
notBefore=Oct 27 02:53:45 2026 GMT
notAfter=Jan 29 02:53:45 2029 GMT
X509v3 Subject Alternative Name:
DNS:ldap01.lab.local, IP Address:10.89.63.2
10.2 权限收敛
slapd 以 openldap 身份运行,私钥必须让 openldap 可读且他人不可读:
sudo chown openldap:openldap /etc/ldap/tls/server.key /etc/ldap/tls/server.crt
sudo chmod 640 /etc/ldap/tls/server.key
ls -l /etc/ldap/tls/
实测回显:
total 24
-rw-r--r-- 1 root root 1155 Oct 27 02:53 ca.crt
-rw------- 1 root root 1704 Oct 27 02:53 ca.key
-rw-r--r-- 1 root root 50 Oct 27 02:53 ext.cnf
-rw-r--r-- 1 openldap openldap 1188 Oct 27 02:53 server.crt
-rw-r--r-- 1 root root 920 Oct 27 02:53 server.csr
-rw-r----- 1 openldap openldap 1704 Oct 27 02:53 server.key
10.3 写入 cn=config 的 TLS 参数
sudo tee /root/tls.ldif > /dev/null << "EOF"
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/tls/ca.crt
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/tls/server.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/tls/server.key
-
add: olcTLSProtocolMin
olcTLSProtocolMin: 3.3
EOF
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /root/tls.ldif
实测回显:
modifying entry "cn=config"
olcTLSProtocolMin: 3.3 表示最低 TLS 1.2(3.3 是 OpenSSL 版本号记法)。
10.4 启用 636 监听(ldaps:///)
sudo sed -i 's|^SLAPD_SERVICES=.*|SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"|' /etc/default/slapd
grep '^SLAPD_SERVICES' /etc/default/slapd
sudo systemctl restart slapd
实测回显:
SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"
确认 389/636 双监听:
ss -ltn | grep -E ':389|:636'
实测回显:
LISTEN 0 2048 0.0.0.0:389 0.0.0.0:*
LISTEN 0 2048 0.0.0.0:636 0.0.0.0:*
LISTEN 0 2048 [::]:389 [::]:*
LISTEN 0 2048 [::]:636 [::]:*
10.5 本机验证 ldaps 与 StartTLS
ldaps(636 直连 TLS):
LDAPTLS_CACERT=/etc/ldap/tls/ca.crt ldapsearch -LLL -x -H ldaps://ldap01.lab.local -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local -s base dn
实测回显:
dn: dc=lab,dc=local
StartTLS(389 明文端口上升级 TLS,-ZZ 表示升级失败即报错):
LDAPTLS_CACERT=/etc/ldap/tls/ca.crt ldapsearch -LLL -x -ZZ -H ldap://ldap01.lab.local -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local -s base dn
实测回显:
dn: dc=lab,dc=local
两条通道都通。LDAPTLS_CACERT 指向自签 CA 让客户端信任服务器证书;不指定会因证书不受信而失败(远程实测见 10.6)。
10.6 远程客户端验证(第二台机器)
在一台同内网的客户端机器(Ubuntu 22.04,装好 ldap-utils)上,先写 hosts 解析并放 CA 证书:
echo "10.89.63.2 ldap01.lab.local" | sudo tee -a /etc/hosts
sudo cp lab-ca.crt /etc/ssl/certs/lab-ca.crt
ldaps 远程查询:
LDAPTLS_CACERT=/etc/ssl/certs/lab-ca.crt ldapsearch -LLL -x -H ldaps://ldap01.lab.local -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local -s base dn
实测回显:
dn: dc=lab,dc=local
StartTLS 远程查询:
LDAPTLS_CACERT=/etc/ssl/certs/lab-ca.crt ldapsearch -LLL -x -ZZ -H ldap://ldap01.lab.local -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local -s base dn
实测回显:
dn: dc=lab,dc=local
对照组:同一命令去掉 CA 信任(证书不受信):
ldapsearch -LLL -x -H ldaps://ldap01.lab.local -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local -s base dn
实测回显:
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
⚠️ 排障要点:-1 Can't contact LDAP server 不一定是网络不通。自签证书场景下「客户端不信任 CA」「证书 SAN 不含目标主机名」「服务端没监听 636(见 11.4)」都表现为 -1,按「网络 → 端口监听 → 证书信任链」顺序排查。
10.7 复制边界说明
OpenLDAP 的复制基于 syncprov overlay(RFC 4533 syncrepl),支持主从(refreshOnly/refreshAndPersist)与多主(mirrormode/multiprovider)。本篇为单机形态,不部署复制;模块加载与配置路径的实测演示见本专栏《OpenLDAP 2.5.20 配置参数详解》篇模块一节,多节点复制集群属于进阶形态,需按生产拓扑另行规划。
十一、常见问题(FAQ)
Q1:为什么安装完域不是我指定的,而是跟着主机名走?
slapd 的安装脚本在 debconf 未预置答案时,会用 hostname -f 推导默认域:主机名 ldap01.lab.local → 推导域 lab.local → dc=lab,dc=local;主机名不带域(如只叫 server01)时会得到 dc=nodomain。规避方法:要么主机名先改成目标域下的 FQDN 再装,要么按 4.2 预置 debconf 答案。重配按方案 B 走 dpkg-reconfigure。
Q2:dpkg-reconfigure 报 MDB_KEYEXIST: Key/data pair already exists 怎么办?
实测报错原文:
=> mdb_tool_entry_put: id2entry_add failed: err=-30799
=> mdb_tool_entry_put: txn_aborted! MDB_KEYEXIST: Key/data pair already exists (-30799)
slapadd: could not add entry dn="dc=lab,dc=local" (line=1): txn_aborted! MDB_KEYEXIST: Key/data pair already exists (-30799)
原因:重配向导的「Move old database?」答了 No(或预置 slapd/move_old_database 为 false),旧库未迁移走,新建目录时同一后缀的条目已存在导致 slapadd 撞主键。解决:重跑 dpkg-reconfigure,把 move_old_database 预置为 true 或交互时选 Yes。
Q3:重配完 ldapwhoami 还报 Invalid credentials (49)?
重配把 /var/lib/ldap 与 slapd.d 重建后,必须等 slapd 以新配置重启:确认 systemctl restart slapd 已执行且 systemctl is-active slapd 为 active 再验证。旧进程持有旧口令哈希是 49 的常见原因。
Q4:配了证书但 ldaps 连不上(-1),389 正常?
先看监听:ss -ltn | grep 636。实测发现 /etc/default/slapd 默认 SLAPD_SERVICES="ldap:/// ldapi:///" 不含 ldaps:///,636 根本没监听——配了 olcTLS* 也不会自动开 636。按 10.4 在 SLAPD_SERVICES 加入 ldaps:/// 后 restart,再用 ss 确认双监听。
Q5:客户端报 -1 但服务端看日志没有连接记录? TLS 握手失败发生在 LDAP 协议建立之前,服务端可能无任何应用层日志。按序核对:hosts/域名解析 → 证书 SAN 是否包含所连主机名 → 客户端 LDAPTLS_CACERT 或 TLS_CACERT 是否指向签发该证书的 CA → 证书是否过期(openssl x509 -noout -dates)。
Q6:安装/重配后 /var/backups 下出现 slapd-<版本> 目录是什么?
dump_database 策略(默认 when needed)在重配/升级前自动把旧配置与数据 dump 成 LDIF 备份。注意两点:它是回滚材料,别删;同时重装时若它存在且 move_old_database 为 true,会被用于自动恢复(这正是实测中「purge 重装后域还是 lab.local」的原因——备份自动回来了)。想要全新空目录装机,先 rm -rf /var/backups/slapd-* 再装。
Q7:ldapvi 能用吗?
Ubuntu 22.04 universe 仓库有 ldapvi 1.7-10build4(apt install ldapvi)。它是交互式编辑器,把搜索结果拉进终端编辑器改完批量回写。边界:必须有 TTY 与 TERM 环境,实测无终端环境时报 TERM environment variable not set. 直接退出;脚本/自动化场景一律用 ldapmodify(命令详解见本专栏《OpenLDAP 2.5.20 常用 CLI 命令详解》篇)。
十二、卸载与清理
彻底卸载 slapd 与 ldap-utils(保留备份目录):
sudo systemctl stop slapd
sudo apt-get purge -y slapd ldap-utils
实测回显(输出节选):
Removing ldap-utils (2.5.20+dfsg-0ubuntu0.22.04.1) ...
Purging configuration files for slapd (2.5.20+dfsg-0ubuntu0.22.04.1) ...
Removing slapd configuration... done.
连带清理数据目录、配置目录与 debconf 记录(如需彻底重来):
sudo rm -rf /var/lib/ldap /etc/ldap/slapd.d
echo PURGE | sudo debconf-communicate slapd
如需全新重装(不被旧备份恢复),先清备份:
sudo rm -rf /var/backups/slapd-*
清理自签证书目录(如不再用):
sudo rm -rf /etc/ldap/tls
之后按第四章重新安装即为全新目录。
十三、参考链接
- OpenLDAP 官方 2.6 Admin Guide(Quick Start):https://www.openldap.org/doc/admin26/quickstart.html
- OpenLDAP 官方下载页(版本与 GPG 签名):https://www.openldap.org/software/download/
- Ubuntu man 手册:slapd(8)、slapd-mdb(5)、ldapsearch(1)(本机
man slapd) - Ubuntu Server 文档(OpenLDAP 服务章节):https://documentation.ubuntu.com/server/
- 本专栏配套篇目:《OpenLDAP 2.7.1 介绍与选型指南》、《OpenLDAP 2.5.20 配置参数详解》、《OpenLDAP 2.5.20 常用 CLI 命令详解》。