OpenLDAP is an open-source implementation of the Lightweight Directory Access Protocol (LDAP) that provides centralized authentication and directory services for Linux environments. It stores user accounts, groups, and organizational data in a hierarchical directory – similar to Microsoft Active Directory but built for Linux and Unix systems.
This guide walks through installing OpenLDAP 2.6.13 from source on Rocky Linux 10 and AlmaLinux 10, configuring the cn=config (slapd.d) backend, setting up a base DN with organizational units, adding users, enabling TLS/SSL encryption, and opening firewall ports. All commands are tested against RHEL 10-family distributions. For official release details, see the OpenLDAP download page.
Prerequisites
- A server running Rocky Linux 10 or AlmaLinux 10 with at least 2GB RAM
- Root or sudo access
- A fully qualified domain name (FQDN) configured on the server
- Ports 389 (LDAP) and 636 (LDAPS) available
- Internet access to download OpenLDAP source
Step 1: Update the System
Start by updating all installed packages to the latest versions.
sudo dnf update -y
Reboot if kernel or core libraries were updated.
sudo reboot
Step 2: Install Required Build Dependencies
OpenLDAP is compiled from source since RHEL 10-family distributions do not ship the slapd server package. Install the compiler toolchain and development libraries needed for the build.
sudo dnf groupinstall "Development Tools" -y
Install additional required development packages.
sudo dnf install wget vim cyrus-sasl-devel libtool-ltdl-devel openssl-devel libdb-devel make libtool autoconf tar gcc perl perl-devel groff -y
Step 3: Create the LDAP System Account
Create a dedicated non-privileged system user that the OpenLDAP daemon runs as. This limits the damage if the service is ever compromised.
sudo useradd -r -M -d /var/lib/openldap -u 55 -s /usr/sbin/nologin ldap
Verify the user was created.
$ id ldap
uid=55(ldap) gid=55(ldap) groups=55(ldap)
Step 4: Download and Extract OpenLDAP Source
Download the latest stable release from the official OpenLDAP release page.
VER=2.6.13
wget https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-${VER}.tgz
Extract and move the source tree to /opt.
tar xzf openldap-${VER}.tgz
sudo mv openldap-${VER} /opt/openldap-${VER}
Step 5: Compile and Install OpenLDAP on Rocky Linux 10 / AlmaLinux 10
Change into the source directory and run the configure script with TLS and module support enabled.
cd /opt/openldap-${VER}
Run the configure script.
sudo ./configure --prefix=/usr --sysconfdir=/etc \
--enable-debug --with-tls=openssl --with-cyrus-sasl --enable-dynamic \
--enable-crypt --enable-spasswd --enable-slapd --enable-modules \
--enable-rlookups
A successful configure ends with: “Please run make depend to build dependencies”. Build the dependencies, compile, and install.
sudo make depend
sudo make
sudo make install
Verify the installation by checking the slapd binary version.
$ /usr/libexec/slapd -VV
@(#) $OpenLDAP: slapd 2.6.13 (Mar 21 2026)
Confirm the configuration files exist.
$ ls /etc/openldap/
certs ldap.conf ldap.conf.default schema slapd.conf slapd.conf.default slapd.ldif slapd.ldif.default
Step 6: Configure OpenLDAP with cn=config (slapd.d)
OpenLDAP uses the cn=config dynamic configuration backend stored under /etc/openldap/slapd.d. This approach allows runtime configuration changes via LDAP operations without restarting the service.
Create the required directories.
sudo mkdir -p /var/lib/openldap /etc/openldap/slapd.d
Set proper ownership and permissions on key files.
sudo chown -R ldap:ldap /var/lib/openldap
sudo chown root:ldap /etc/openldap/slapd.conf
sudo chmod 640 /etc/openldap/slapd.conf
Create the SUDO Schema
The sudo LDAP schema allows managing sudoers rules through the directory. Check if your system’s sudo supports LDAP.
$ sudo -V | grep -i "ldap"
ldap.conf path: /etc/sudo-ldap.conf
ldap.secret path: /etc/ldap.secret
Locate the sudo schema file.
$ rpm -ql sudo | grep -i schema.openldap
/usr/share/doc/sudo/schema.OpenLDAP
Copy it to the OpenLDAP schema directory.
sudo cp /usr/share/doc/sudo/schema.OpenLDAP /etc/openldap/schema/sudo.schema
Create the sudo schema in LDIF format. Open the file for editing.
sudo vi /etc/openldap/schema/sudo.ldif
Add the following content.
dn: cn=sudo,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: sudo
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcObjectClasses: ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL DESC 'Sudoer Entries' MUST ( cn ) MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ description ) )
Configure the slapd.ldif Database
Back up the default slapd.ldif and create a new one with the MDB backend and required schemas.
sudo mv /etc/openldap/slapd.ldif /etc/openldap/slapd.ldif.bak
Open the new file for editing.
sudo vi /etc/openldap/slapd.ldif
Add the following configuration. This sets up the global config, loads the MDB backend module, and includes the required schemas.
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/lib/openldap/slapd.args
olcPidFile: /var/lib/openldap/slapd.pid
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/libexec/openldap
olcModuleload: back_mdb.la
# Include schemas
include: file:///etc/openldap/schema/core.ldif
include: file:///etc/openldap/schema/cosine.ldif
include: file:///etc/openldap/schema/nis.ldif
include: file:///etc/openldap/schema/inetorgperson.ldif
include: file:///etc/openldap/schema/sudo.ldif
dn: olcDatabase=frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: frontend
olcAccess: to dn.base="cn=Subschema" by * read
olcAccess: to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by * none
dn: olcDatabase=config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: config
olcRootDN: cn=config
olcAccess: to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by * none
Run a dry-run to validate the configuration before applying it.
$ sudo slapadd -n 0 -F /etc/openldap/slapd.d -l /etc/openldap/slapd.ldif -u
Closing DB...
If the dry run succeeds with no errors, apply the configuration.
sudo slapadd -n 0 -F /etc/openldap/slapd.d -l /etc/openldap/slapd.ldif
Verify the slapd.d directory structure was created.
$ ls /etc/openldap/slapd.d/
'cn=config' 'cn=config.ldif'
Set ownership on the configuration directory.
sudo chown -R ldap:ldap /etc/openldap/slapd.d
Step 7: Create the Systemd Service and Start slapd
Since OpenLDAP was installed from source, create a systemd unit file manually. If you need a refresher on managing services, see our guide on configuring firewalld on RHEL/CentOS/Rocky.
sudo vi /etc/systemd/system/slapd.service
Add the following service definition.
[Unit]
Description=OpenLDAP Server Daemon
After=syslog.target network-online.target
Documentation=man:slapd
Documentation=man:slapd-mdb
[Service]
Type=forking
PIDFile=/var/lib/openldap/slapd.pid
Environment="SLAPD_URLS=ldap:/// ldapi:/// ldaps:///"
Environment="SLAPD_OPTIONS=-F /etc/openldap/slapd.d"
ExecStart=/usr/libexec/slapd -u ldap -g ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS
[Install]
WantedBy=multi-user.target
Reload the systemd daemon and start the service.
sudo systemctl daemon-reload
sudo systemctl enable --now slapd
Verify slapd is running.
$ systemctl status slapd
● slapd.service - OpenLDAP Server Daemon
Loaded: loaded (/etc/systemd/system/slapd.service; enabled; preset: disabled)
Active: active (running) since Fri 2026-03-21 10:15:30 UTC; 5s ago
Docs: man:slapd
man:slapd-mdb
Main PID: 12345 (slapd)
Tasks: 2 (limit: 22612)
Memory: 3.0M
CGroup: /system.slice/slapd.service
└─12345 /usr/libexec/slapd -u ldap -g ldap -h ldap:/// ldapi:/// ldaps:/// -F /etc/openldap/slapd.d
Step 8: Configure the Root DN and MDB Database
With slapd running, add the MDB database backend that holds your directory data. First, generate a hashed password for the root DN (directory administrator).
$ sudo slappasswd
New password:
Re-enter new password:
{SSHA}MnsvmiMXvuXOHjDJi/rrqYra/1qo+hHE
Copy the hashed password – you will need it in the next file. Create the root DN configuration LDIF.
vi rootdn.ldif
Add the following content. Replace dc=example,dc=com with your actual domain components, and paste your hashed password at olcRootPW.
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcDbMaxSize: 42949672960
olcDbDirectory: /var/lib/openldap
olcSuffix: dc=example,dc=com
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: {SSHA}MnsvmiMXvuXOHjDJi/rrqYra/1qo+hHE
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn pres,eq,approx,sub
olcDbIndex: mail pres,eq,sub
olcDbIndex: objectClass pres,eq
olcDbIndex: loginShell pres,eq
olcDbIndex: sudoUser,sudoHost pres,eq
olcAccess: to attrs=userPassword,shadowLastChange,shadowExpire
by self write
by anonymous auth
by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by dn.subtree="ou=system,dc=example,dc=com" read
by * none
olcAccess: to dn.subtree="ou=system,dc=example,dc=com" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by * none
olcAccess: to dn.subtree="dc=example,dc=com" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by users read
by * none
Apply the root DN configuration to the running slapd instance.
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f rootdn.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "olcDatabase=mdb,cn=config"
Step 9: Add Base DN and Organizational Units
Define the organization structure with a base DN and the standard people and groups organizational units.
vi basedn.ldif
Add the following content, replacing the domain components with your own.
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
objectClass: top
o: Example Organization
dc: example
dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: groups
dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: people
Import the base DN into the directory.
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f basedn.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "dc=example,dc=com"
adding new entry "ou=groups,dc=example,dc=com"
adding new entry "ou=people,dc=example,dc=com"
Step 10: Add LDAP Users
Create an LDIF file with user entries. Each user needs both a posixAccount entry under ou=people and a corresponding posixGroup entry under ou=groups.
vi users.ldif
Add user definitions. Adjust the uid, cn, sn, uidNumber, and gidNumber values as needed.
dn: uid=jdoe,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: jdoe
cn: John
sn: Doe
loginShell: /bin/bash
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/jdoe
shadowMax: 60
shadowMin: 1
shadowWarning: 7
shadowInactive: 7
shadowLastChange: 0
dn: cn=jdoe,ou=groups,dc=example,dc=com
objectClass: posixGroup
cn: jdoe
gidNumber: 10000
memberUid: jdoe
Import the users into the directory.
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f users.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "uid=jdoe,ou=people,dc=example,dc=com"
adding new entry "cn=jdoe,ou=groups,dc=example,dc=com"
Set a password for the new user.
sudo ldappasswd -H ldapi:/// -Y EXTERNAL -S "uid=jdoe,ou=people,dc=example,dc=com"
You will be prompted to enter and confirm the new password.
New password:
Re-enter new password:
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
Create a Bind DN User
A bind DN user is a service account used by LDAP clients for lookups – resolving user IDs, group memberships, and similar read-only operations. Generate a password hash for it first.
$ sudo slappasswd
New password:
Re-enter new password:
{SSHA}YPkUdvnqpYcHM5mMKH6YWMb0AY36OJCd
Create the bind DN LDIF file.
vi bindDNuser.ldif
Add the system OU and the readonly bind user. Replace the hashed password and domain components.
dn: ou=system,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: system
dn: cn=readonly,ou=system,dc=example,dc=com
objectClass: organizationalRole
objectClass: simpleSecurityObject
cn: readonly
userPassword: {SSHA}YPkUdvnqpYcHM5mMKH6YWMb0AY36OJCd
description: Bind DN user for LDAP Operations
Import the bind DN user.
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f bindDNuser.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "ou=system,dc=example,dc=com"
adding new entry "cn=readonly,ou=system,dc=example,dc=com"
Step 11: Configure TLS/SSL for OpenLDAP
Encrypting LDAP traffic with TLS prevents credentials from being transmitted in plain text. This section uses a self-signed certificate – for production environments, use a certificate from a trusted CA or Let’s Encrypt.
Generate a self-signed certificate and private key.
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/pki/tls/ldapserver.key \
-out /etc/pki/tls/ldapserver.crt
Set proper ownership so the ldap user can read the certificate files.
sudo chown ldap:ldap /etc/pki/tls/{ldapserver.crt,ldapserver.key}
Create an LDIF file to add the TLS configuration to slapd.
sudo vi add-tls.ldif
Add the following TLS directives pointing to your certificate and key files.
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/pki/tls/ldapserver.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/pki/tls/ldapserver.key
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/pki/tls/ldapserver.crt
Apply the TLS configuration.
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f add-tls.ldif
Update the LDAP client configuration to trust the certificate. Open the config file.
sudo vi /etc/openldap/ldap.conf
Find the TLS_CACERT line and update it to point to your certificate.
#TLS_CACERT /etc/pki/tls/cert.pem
TLS_CACERT /etc/pki/tls/ldapserver.crt
Restart slapd to activate TLS on port 636.
sudo systemctl restart slapd
Verify slapd is listening on both LDAP and LDAPS ports.
$ ss -tlnp | grep slapd
LISTEN 0 2048 *:389 *:* users:(("slapd",pid=12345,fd=8))
LISTEN 0 2048 *:636 *:* users:(("slapd",pid=12345,fd=10))
Step 12: Configure Firewall for OpenLDAP
Open both LDAP (389/TCP) and LDAPS (636/TCP) ports in firewalld to allow client connections.
sudo firewall-cmd --add-service={ldap,ldaps} --permanent
sudo firewall-cmd --reload
Verify the firewall rules are active.
$ sudo firewall-cmd --list-services
cockpit dhcpv6-client ldap ldaps ssh
Step 13: Test OpenLDAP with ldapsearch
Verify the directory is working by running ldapsearch queries against it.
Search for the base DN and all entries using the EXTERNAL SASL mechanism (as root via Unix socket).
$ sudo ldapsearch -H ldapi:/// -Y EXTERNAL -b "dc=example,dc=com" -LLL
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
objectClass: top
o: Example Organization
dc: example
dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: groups
dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: people
dn: uid=jdoe,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: jdoe
cn: John
sn: Doe
loginShell: /bin/bash
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/jdoe
Test authentication with the bind DN user over LDAP.
ldapsearch -x -H ldap://127.0.0.1 -D "cn=readonly,ou=system,dc=example,dc=com" -W -b "ou=people,dc=example,dc=com"
Test LDAPS (encrypted) connectivity.
ldapsearch -x -H ldaps://127.0.0.1 -D "cn=readonly,ou=system,dc=example,dc=com" -W -b "ou=people,dc=example,dc=com"
Both commands should return the user entries when you provide the correct bind DN password.
Port Reference Table
| Port | Protocol | Description |
|---|---|---|
| 389 | TCP | LDAP (unencrypted or STARTTLS) |
| 636 | TCP | LDAPS (LDAP over TLS/SSL) |
Conclusion
OpenLDAP 2.6.13 is now installed and configured on Rocky Linux 10 / AlmaLinux 10 with the cn=config dynamic backend, organizational units, user entries, TLS encryption, and firewall rules in place. From here, configure LDAP clients on your systems to authenticate against this server. For high availability, set up OpenLDAP multi-master replication or provider-consumer replication, and consider deploying a web management interface like LDAP Account Manager for easier administration.