Installing & Configuring OpenLDAP Server On CentOS 6.4
— ny_wk

To install and configure an OpenLDAP server on CentOS, install the openldap-servers package, set a base DN and a root DN with an slappasswd-hashed password through the cn=config runtime backend, load the core schemas, then load your organization, OU, and user entries from an LDIF file with ldapadd. This guide walks through a production-grade build on a modern RHEL-family system and verifies everything with ldapsearch before locking it down with TLS.
An OpenLDAP server on CentOS gives you a single, centralized directory for user accounts, groups, and other directory-like data that many machines and applications can share. Instead of copying /etc/passwd entries across dozens of hosts, you maintain one authoritative directory and point everything at it. LDAP (Lightweight Directory Access Protocol) is purpose-built for this kind of workload: fast, indexed reads and relatively infrequent writes, perfect for authentication, address books, certificate lookups, and single sign-on.
The Problem: Scattered Accounts, No Single Source of Truth
Without a directory service, every server keeps its own local users. Onboarding someone means touching every box; offboarding means hoping you found them all. Passwords drift, UIDs collide, and an audit becomes a nightmare. LDAP solves this by storing identities in a hierarchical tree (the Directory Information Tree, or DIT) that clients query over the network. OpenLDAP is the dominant open-source implementation, and its server daemon is called slapd.
The directory model is deliberately optimized for reads. Entries are heavily indexed, so filtered searches such as "return the email and title of every person in a given department" come back almost instantly, while writes are comparatively rare. That read-heavy profile is exactly why LDAP underpins so much infrastructure: Linux login (via sssd), mail server address lookups, VPN and Wi-Fi authentication, certificate distribution, and single sign-on portals can all point at the same directory. Get one OpenLDAP server right and dozens of downstream systems inherit a consistent, centrally managed identity source.
Before you start, you should understand three terms that drive the entire configuration:
- Base DN (suffix): the root of your tree, usually derived from a domain, e.g.
dc=example,dc=com. - Root DN (rootdn): a privileged "superuser" entry that bypasses access controls, typically
cn=Manager,dc=example,dc=com. - Schema: the rules that define valid object classes and attributes (such as
inetOrgPersonorposixAccount).
A Note on Versions: Old CentOS vs. the Modern Approach
The classic walkthroughs for this task target CentOS 6, which is long past end-of-life. The original SysVinit service (service ldap start), the iptables firewall, and especially the flat /etc/openldap/slapd.conf file are all legacy. On any current system you should use one of the supported RHEL rebuilds and the modern tooling:
- Distribution: CentOS Stream 9, AlmaLinux, or Rocky Linux instead of EOL CentOS 6/7.
- Configuration: the dynamic
cn=configbackend (also called OLC, On-Line Configuration). Settings live as LDIF entries under/etc/openldap/slapd.d/and are changed live withldapmodify— no daemon restart, no editingslapd.confby hand. - Service manager:
systemctlinstead ofservice/chkconfig. - Firewall:
firewalldinstead of rawiptables. - Backend: the
mdb(LMDB) backend has replaced the olderbdbBerkeley DB backend, removing the need to hand-tuneDB_CONFIG.
This walkthrough teaches the durable concepts and shows the modern commands, while flagging the older equivalents so you can read legacy docs without confusion.
Prerequisites
- A minimal CentOS/AlmaLinux/Rocky install with root (or
sudo) access. - A working DNS resolution or correct
/etc/hostsentries so the server's FQDN (e.g.ldap1.example.com) resolves. - Time synced with chronyd/NTP — TLS and replication are sensitive to clock skew.
- A plan for SELinux: leave it enforcing and use the correct contexts (recommended), or set it permissive while testing.
Step-by-Step: Build the OpenLDAP Server
- Install the server and client packages.
On EOL CentOS 6/7 this was a single
yumcommand. On modern systems the server package moved out of the base repos; enable the appropriate stream first.Modern (CentOS Stream / AlmaLinux / Rocky 9):
dnf install openldap openldap-clients openldap-serversLegacy CentOS 6/7:
yum install openldap openldap-servers openldap-clients -y - Start slapd and enable it at boot.
Modern systems ship a ready-to-run
cn=configtree, so you simply start the service:systemctl enable --now slapdsystemctl status slapdOn legacy CentOS 6 the equivalents were
service slapd startandchkconfig slapd on. - Generate a hashed password for the root DN.
Never store cleartext admin passwords. Generate a salted SHA hash:
slappasswdIt prompts twice and prints a string such as
{SSHA}GtG8bcLGeN/rf1iStKFK2pu0C2EZf/RX. Copy that value — you will paste it into an LDIF in the next step. - Set the root DN and password via cn=config (the modern way).
Rather than editing
slapd.conf, write the change as LDIF and apply it withldapmodifyover the local socket as the root operating-system user (authenticated with SASL EXTERNAL). Createrootdn.ldif:dn: olcDatabase={2}mdb,cn=configchangetype: modifyreplace: olcSuffixolcSuffix: dc=example,dc=com-replace: olcRootDNolcRootDN: cn=Manager,dc=example,dc=com-replace: olcRootPWolcRootPW: {SSHA}GtG8bcLGeN/rf1iStKFK2pu0C2EZf/RXApply it:
ldapmodify -Y EXTERNAL -H ldapi:/// -f rootdn.ldifThe database index number (
{2}mdb) can vary; confirm yours withldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config dn. On a legacyslapd.confsystem you would instead edit thesuffix,rootdn, androotpwlines directly. - Load the standard schemas.
Out of the box only the core schema is active. To create real users you need
cosine,nis, andinetorgperson. Import the bundled LDIF schemas:ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldifldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldifldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldifOn legacy
slapd.confsetups these wereincludelines pointing at the*.schemafiles (e.g.core.schema,cosine.schema,inetorgperson.schema,nis.schema) before converting the file withslaptest. - Create the base of the tree and your OUs.
Now populate the DIT. Create
base.ldifdefining the domain root plus organizational units for users and groups:dn: dc=example,dc=comobjectClass: topobjectClass: dcObjectobjectClass: organizationo: Example Organizationdc: exampledn: ou=Users,dc=example,dc=comobjectClass: organizationalUnitou: Usersdn: ou=Groups,dc=example,dc=comobjectClass: organizationalUnitou: GroupsLoad it by binding as the root DN you configured:
ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f base.ldif - Add users and a group.
Generate a hash for each user's password with
slappasswd, then createusers.ldif. A POSIX-capable account needs bothposixAccountandinetOrgPersonobject classes:dn: uid=student1,ou=Users,dc=example,dc=comobjectClass: topobjectClass: posixAccountobjectClass: inetOrgPersonuid: student1cn: Student Onesn: OneloginShell: /bin/bashhomeDirectory: /home/student1uidNumber: 15000gidNumber: 10000mail: student1@example.comuserPassword: {SSHA}CQG5KHc6b1ii+qopaVCsNa14v9+r14r5dn: cn=ldapusers,ou=Groups,dc=example,dc=comobjectClass: topobjectClass: posixGroupcn: ldapusersgidNumber: 10000memberUid: student1Load it:
ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f users.ldifTo modify or delete entries later, use
ldapmodifyandldapdeletewith the same bind options — never edit the database files on disk directly. - Open the firewall.
LDAP listens on TCP 389 (plain/STARTTLS) and LDAPS on TCP 636. With firewalld:
firewall-cmd --permanent --add-service=ldapfirewall-cmd --permanent --add-service=ldapsfirewall-cmd --reloadThe legacy CentOS 6 equivalent was a set of
iptables -I INPUT ... --dport 389/636 -j ACCEPTrules followed byservice iptables save.
Enable TLS for Encrypted Connections
By default, binds and queries travel in cleartext — anyone with a packet sniffer can read passwords and directory data. Always enable TLS before going to production.
- Create a certificate and key. For a lab you can self-sign; in production use a CA-issued certificate. The Common Name must match the server FQDN:
openssl req -newkey rsa:2048 -x509 -nodes -days 3650 -keyout /etc/openldap/certs/ldap1_key.pem -out /etc/openldap/certs/ldap1_cert.pem - Fix ownership so the
ldapuser can read the key:chown ldap:ldap /etc/openldap/certs/ldap1_*.pemchmod 600 /etc/openldap/certs/ldap1_key.pem - Point cn=config at the certificate. Create
tls.ldif:dn: cn=configchangetype: modifyreplace: olcTLSCertificateFileolcTLSCertificateFile: /etc/openldap/certs/ldap1_cert.pem-replace: olcTLSCertificateKeyFileolcTLSCertificateKeyFile: /etc/openldap/certs/ldap1_key.pemApply it:
ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif - Enable the LDAPS listener. Edit
/etc/sysconfig/slapdand addldaps:///to the URLs line:SLAPD_URLS="ldapi:/// ldap:/// ldaps:///"Then restart:
systemctl restart slapd. Verify both ports are listening withss -ntlup | grep slapd(look for 389 and 636).
Common Pitfalls
| Symptom | Cause & Fix |
slapd won't start; id2entry / data.mdb errors | The database directory /var/lib/ldap is missing or wrong-owned. Ensure it exists and run chown -R ldap:ldap /var/lib/ldap. |
Changes saved with slapadd but the daemon can't read them | slapadd runs as root and creates root-owned files. Always follow with chown -R ldap:ldap /var/lib/ldap. |
Legacy bdb backend complains about DB_CONFIG | Copy cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG before loading data. The modern mdb backend does not need this. |
Insufficient access or operations silently fail under SELinux | Custom cert/db paths need correct contexts. Restore with restorecon -Rv /etc/openldap /var/lib/ldap, or set setenforce 0 while testing. |
| TLS handshake fails on clients | Self-signed cert or CN/FQDN mismatch. Set TLS_REQCERT allow in /etc/openldap/ldap.conf for testing, or distribute the CA cert to clients. |
Verification with ldapsearch
Confirm the directory answers queries. An anonymous subtree search should return your base, OUs, users, and group:
ldapsearch -x -b "dc=example,dc=com" -H ldap://ldap1.example.com "(objectClass=*)"
Test an authenticated bind as the root DN (it will prompt for the password):
ldapsearch -x -D "cn=Manager,dc=example,dc=com" -W -b "dc=example,dc=com" "(uid=student1)"
Test that TLS works end to end over LDAPS:
ldapsearch -x -H ldaps://ldap1.example.com -b "dc=example,dc=com" "(objectClass=organizationalUnit)"
A clean run ends with result: 0 Success. If you see entries returned with the expected DNs, your OpenLDAP server on CentOS is operational. Note that password attributes come back Base64-encoded (lines ending in ::) because they contain binary hash data — this is expected, not a corruption. From here you can point clients at it using sssd with authselect (the modern replacement for authconfig) to enable centralized login.
For ongoing operations it is worth wiring up logging so you can troubleshoot binds and search activity. Set olcLogLevel in cn=config and route the local4 syslog facility to a dedicated file (for example, add local4.* /var/log/slapd.log to your rsyslog configuration and restart the service). Watching that log while a client authenticates is the fastest way to diagnose access-control, schema, or TLS problems in production.
Key Takeaways
- Use the dynamic
cn=configbackend, not the obsoleteslapd.conf— configure withldapmodify/ldapaddoverldapi:///using SASL EXTERNAL. - Plan your DNs first: a base DN (suffix), a root DN, and the OU structure determine everything else.
- Hash every password with
slappasswd({SSHA}) and never commit cleartext to LDIF. - Load schemas before users —
posixAccountandinetOrgPersonrequirecosine,nis, andinetorgperson. - Enable TLS and the firewall before production, and remember the golden rule of pitfalls: fix ownership with
chown -R ldap:ldap /var/lib/ldap.
Frequently Asked Questions
What is the difference between slapd.conf and cn=config?
slapd.conf is the legacy static text file that required a daemon restart for every change. cn=config (OLC) stores configuration as LDIF entries under /etc/openldap/slapd.d/ and is modified live with standard LDAP tools — no restart needed. Modern OpenLDAP installs ship with cn=config by default.
Why does ldapadd fail with "Insufficient access"?
You are likely binding anonymously or with the wrong DN. Configuration changes need SASL EXTERNAL over the local socket (-Y EXTERNAL -H ldapi:/// as root), while data changes need a bind as your root DN (-x -D "cn=Manager,dc=example,dc=com" -W). SELinux or file ownership can also block writes.
Do I still need DB_CONFIG?
Only with the old Berkeley DB (bdb/hdb) backend. Current OpenLDAP uses the LMDB (mdb) backend, which needs no DB_CONFIG tuning — just a correctly owned /var/lib/ldap directory.
How do I let Linux clients log in with LDAP accounts?
Install sssd and openldap-clients, point /etc/sssd/sssd.conf at ldaps://your-server, distribute the CA certificate, then run authselect select sssd with-mkhomedir (modern) or the older authconfig. Verify with getent passwd username and id username.
Found this useful? Subscribe to @explorenystream on YouTube for more Linux and sysadmin tutorials.