Install and Setup OpenLDAP on Rocky Linux 9

|
Last Updated:
|
|

In this guide, we provide a step by step tutorial on how to install and setup OpenLDAP on Rocky Linux 9.

Installing OpenLDAP on Rocky Linux 9

Rocky Linux 9 repositories do not have the latest release versions of OpenLDAP as of this writing.

As a result, you have two options to install OpenLDAP on Rocky Linux 9;

  1. Compile and install from the source
  2. Install (not so recent version) from the EPEL repositories.

Compile and Install OpenLDAP on Rocky Linux 9

To get the latest version with bug fixes, you need to build it from the source as described in this guide.

However, building OpenLDAP version 2.6.5, which is the current release version as of this writing, causes a version mismatch issues with the default openldap library package (version 2.6.2), which also required by sudo package. This causes any command that uses Python to fail with such an error as;


Traceback (most recent call last):
  File "/usr/bin/dnf", line 61, in 
    from dnf.cli import main
  File "/usr/lib/python3.9/site-packages/dnf/__init__.py", line 30, in 
    import dnf.base
  File "/usr/lib/python3.9/site-packages/dnf/base.py", line 29, in 
    import libdnf.transaction
  File "/usr/lib64/python3.9/site-packages/libdnf/__init__.py", line 12, in 
    from . import conf
  File "/usr/lib64/python3.9/site-packages/libdnf/conf.py", line 13, in 
    from . import _conf
ImportError: /lib64/libldap.so.2: undefined symbol: ber_sockbuf_io_udp, version OPENLDAP_2.200

So, if you want to compile and install OpenLDAP server on Rocky Linux 9, then maybe try the same version of the OpenLDAP server and the default openldap library package installed.

Install OpenLDAP from EPEL Repos on Rocky Linux 9

Kindly note that,the latest available version of OpenLDAP server on EPEL repos is OpenLDAP 2.6.2.

Install EPEL Repositories on Rocky Linux 9

Execute the command below to install EPEL repos on Rocky Linux 9

dnf install epel-release

Looks like it is also recommended to enable CRB repository. “Many EPEL packages require the CodeReady Builder (CRB) repository. It is recommended that you run /usr/bin/crb enable to enable the CRB repository“.

/usr/bin/crb enable

Install OpenLDAP server on Rocky Linux 9

You can install OpenLDAP server and clients packages using the command below;

dnf install openldap-{servers,clients}

OpenLDAP configuration files are now installed on /etc/openldap.

ls -1 /etc/openldap/

certs
check_password.conf
ldap.conf
schema
slapd.d

The libraries are installed under /usr/lib64/openldap/.

The data directory is /var/lib/ldap/.

Similarly, OpenLDAP system/service account is created;

getent passwd ldap
ldap:x:55:55:OpenLDAP server:/var/lib/ldap:/sbin/nologin

Configuring OpenLDAP on Rocky Linux 9

Now that the installation of OpenLDAP is complete, proceed to configure it.

As much as some default configs are put in place after installation, let’s make out own custom configurations.

Backup default database directory;

mv /etc/openldap/slapd.d{,.original}

Create new database directory;

mkdir /etc/openldap/slapd.d

Set the proper ownership and permissions on OpenLDAP directories and configuration files.

chown -R ldap:ldap /var/lib/ldap
chown root:ldap /etc/openldap/ldap.conf
chmod 640 /etc/openldap/ldap.conf

Create OpenLDAP Systemd Service

In order to run OpenLDAP as a service, you need to create a systemd service file as shown below.

cat > /etc/systemd/system/slapd.service << 'EOL'
[Unit]
Description=OpenLDAP Server Daemon
After=syslog.target network-online.target
Documentation=man:slapd
Documentation=man:slapd-mdb

[Service]
Type=forking
PIDFile=/var/lib/ldap/slapd.pid
Environment="SLAPD_URLS=ldap:/// ldapi:/// ldaps:///"
Environment="SLAPD_OPTIONS=-F /etc/openldap/slapd.d"
ExecStart=/usr/sbin/slapd -u ldap -g ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS

[Install]
WantedBy=multi-user.target
EOL

Save and quit the service file. Do not run/start the service yet.

Create OpenLDAP SUDO Schema

To configure LDAP with support sudo, first, check if your version of installed sudo supports LDAP.

sudo -V |  grep -i "ldap"

If sudo supports LDAP, you should see the lines below;

...
ldap.conf path: /etc/sudo-ldap.conf
ldap.secret path: /etc/ldap.secret

Check if LDAP sudo schema is available.

rpm -ql sudo |  grep -i schema.openldap
/usr/share/doc/sudo/schema.OpenLDAP

Copy the schema.OpenLDAP to the schema directory.

cp /usr/share/doc/sudo/schema.OpenLDAP  /etc/openldap/schema/sudo.schema

Create sudo schema ldif file. You can copy the default ldif file from /usr/share/doc/sudo/schema.olcSudo and just modified it.


cat << 'EOL' > /etc/openldap/schema/sudo.ldif
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 caseExactMatch
    SUBSTR caseExactSubstringsMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
#
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 caseExactMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
#
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.7
    NAME 'sudoRunAsGroup'
    DESC 'Group(s) impersonated by sudo'
    EQUALITY caseExactMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
#
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.8
    NAME 'sudoNotBefore'
    DESC 'Start of time interval for which the entry is valid'
    EQUALITY generalizedTimeMatch
    ORDERING generalizedTimeOrderingMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
#
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.9
    NAME 'sudoNotAfter'
    DESC 'End of time interval for which the entry is valid'
    EQUALITY generalizedTimeMatch
    ORDERING generalizedTimeOrderingMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
#
olcattributeTypes: ( 1.3.6.1.4.1.15953.9.1.10
    NAME 'sudoOrder'
    DESC 'an integer to order the sudoRole entries'
    EQUALITY integerMatch
    ORDERING integerOrderingMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
#
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 $ sudoOrder $ sudoNotBefore $ sudoNotAfter $
        description )
    )
EOL

Update OpenLDAP SLAPD Database

Create and LDIF file with database updates, /etc/openldap/slapd.ldif, as follows;

Modify it to suit your needs.

cat > /etc/openldap/slapd.ldif << 'EOL'
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/lib/ldap/slapd.args
olcPidFile: /var/lib/ldap/slapd.pid

dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema

dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib64/openldap
olcModuleload: back_mdb.la

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
#include: file:///etc/openldap/schema/ppolicy.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
EOL
  • To update the SLAPD database from the information provided on the SLAPD LDIF file above, use slapadd command with the option -n 0 which creates the first database.
  • To specify the configuration directory, /etc/openldap/slapd.d, use option -F and option -l to specify location of the LDIF file above.

Before you can write the changes to the database, perform a dry run to see what would happen. Pass -u option to slapadd command.

slapadd -n 0 -F /etc/openldap/slapd.d -l /etc/openldap/slapd.ldif -u

Then implement the changes if all is well.

slapadd -n 0 -F /etc/openldap/slapd.d -l /etc/openldap/slapd.ldif

This command creates slapd database configurations under /etc/openldap/slapd.d directory.

ls /etc/openldap/slapd.d
'cn=config'  'cn=config.ldif'

Set the user and group ownership of the /etc/openldap/slapd.d directory and the files in it to ldap user.

chown -R ldap:ldap /etc/openldap/slapd.d

Running SLAPD Service

Reload systemd configurations and start and enable OpenLDAP service to run on boot.

systemctl daemon-reload
systemctl enable --now slapd

Check the status;

systemctl status slapd
● slapd.service - OpenLDAP Server Daemon
   Loaded: loaded (/etc/systemd/system/slapd.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2021-06-19 12:17:43 EAT; 19s ago
     Docs: man:slapd
           man:slapd-mdb
  Process: 153713 ExecStart=/usr/libexec/slapd -u ldap -g ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 153714 (slapd)
    Tasks: 2 (limit: 11389)
   Memory: 3.0M
   CGroup: /system.slice/slapd.service
           └─153714 /usr/libexec/slapd -u ldap -g ldap -h ldap:/// ldapi:/// ldaps:/// -F /etc/openldap/slapd.d

Jun 19 12:17:43 localhost.localdomain systemd[1]: Starting OpenLDAP Server Daemon...
Jun 19 12:17:43 localhost.localdomain slapd[153713]: @(#) $OpenLDAP: slapd 2.5.5 (Jun 19 2021 11:30:55) $
                                                             [email protected]:/root/openldap-2.5.5/servers/slapd
Jun 19 12:17:43 localhost.localdomain slapd[153714]: slapd starting
Jun 19 12:17:43 localhost.localdomain systemd[1]: Started OpenLDAP Server Daemon.

If the service fails to start with the error;

slapd.service: Can't convert PID files /var/lib/ldap/slapd.pid O_PATH file descriptor to proper file descriptor: Permission denied

The check SELinux if it is enforcing;

sestatus | grep mode

If it is enforcing;

Current mode:                   enforcing

Confirm the same;

grep denied /var/log/audit/audit.log

Sample output;


type=AVC msg=audit(1691005748.605:250): avc:  denied  { read } for  pid=1 comm="systemd" name="slapd.pid" dev="dm-0" ino=16780213 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:slapd_db_t:s0 tclass=file permissive=0
type=AVC msg=audit(1691005748.605:251): avc:  denied  { read } for  pid=1 comm="systemd" name="slapd.pid" dev="dm-0" ino=16780213 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:slapd_db_t:s0 tclass=file permissive=0
type=AVC msg=audit(1691005748.605:252): avc:  denied  { read } for  pid=1 comm="systemd" name="slapd.pid" dev="dm-0" ino=16780213 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:slapd_db_t:s0 tclass=file permissive=0

You can choose to deal with SELinux to sort the permissions or set it to permission mode (SELinux prints warnings instead of enforcing);

setenforce 0
sed -i '/^SELINUX=/s/enforcing/permissive/' /etc/selinux/config

Restart the service;

systemctl restart slapd

Configure OpenLDAP Logging on Rocky Linux 9

To enable OpenLDAP to log connections, operations, results statistics, create and ldif file and update the database as follows. Such OpenLDAP logging is enabled on log level 256 with keyword stats by modifying the olcLogLevel attribute as shown below.

cd ~

cat > enable-openldap-log.ldif << 'EOL'
dn: cn=config
changeType: modify
replace: olcLogLevel
olcLogLevel: stats
EOL
ldapmodify -Y external -H ldapi:/// -f enable-openldap-log.ldif
ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config "(objectClass=olcGlobal)" olcLogLevel -LLL -Q
dn: cn=config
olcLogLevel: stats

Configure Rsyslog to enable OpenLDAP to log to a specific file. By default, OpenLDAP logs to local4 facility.

echo "local4.* /var/log/slapd.log" >> /etc/rsyslog.conf

Restart Rsyslog

systemctl restart rsyslog

You should now be able to read the LDAP logs on, /var/log/slapd.log.

Create OpenLDAP Default Root DN

Next, create MDB database defining the root DN as well as the access control lists.

First, generate the root DN password.

slappasswd
New password: ENTER PASSWORD
Re-enter new password: RE-ENTER PASSWORD
{SSHA}/23W0+GeW28iXwW986RpuSVEHESSvtlO

Paste the password hash generated above as the value of olcRootPW in the Root DN ldif file below.

Replace the domain components, dc=ldapmaster,dc=kifarunix-demo,dc=com with your appropriate names.


cat > rootdn.ldif << 'EOL'
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcDbMaxSize: 42949672960
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=ldapmaster,dc=kifarunix-demo,dc=com
olcRootDN: cn=admin,dc=ldapmaster,dc=kifarunix-demo,dc=com
olcRootPW: {SSHA}/23W0+GeW28iXwW986RpuSVEHESSvtlO
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=ldapmaster,dc=kifarunix-demo,dc=com" read
  by * none
olcAccess: to dn.subtree="ou=system,dc=ldapmaster,dc=kifarunix-demo,dc=com" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * none
olcAccess: to dn.subtree="dc=ldapmaster,dc=kifarunix-demo,dc=com" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by users read 
  by * none
EOL

Read more about ACL on OpenLDAP Access Control.

Updated the slapd database with the content above;

ldapadd -Y EXTERNAL -H ldapi:/// -f rootdn.ldif

Sample command output;

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"

Configure OpenLDAP with SSL/TLS

To secure OpenLDAP communication between the client and the server, configured it to use SSL/TLS certificates.

In this guide, we are self-signed certificates. You can choose to obtain the commercially signed and trusted certificates from your preferred CAs, for production environments.

openssl req -x509 \
-nodes \
-days 3650 \
-newkey rsa:2048 -keyout \
/etc/pki/tls/ldapserver.key \
-out /etc/pki/tls/ldapserver.crt
chown ldap:ldap /etc/pki/tls/{ldapserver.crt,ldapserver.key}

Update the OpenLDAP Server TLS certificates attributes.


cat > add-tls.ldif << 'EOL'
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
EOL

Note that we have used self-signed certificate as both the certificate and the CA certificate.

ldapadd -Y EXTERNAL -H ldapi:/// -f add-tls.ldif

You can confirm this by running;

slapcat -b "cn=config" | grep olcTLS
olcTLSCACertificateFile: /etc/pki/tls/ldapserver.crt
olcTLSCertificateKeyFile: /etc/pki/tls/ldapserver.key
olcTLSCertificateFile: /etc/pki/tls/ldapserver.crt

Change the location of the CA certificate on /etc/openldap/ldap.conf.

vim /etc/openldap/ldap.conf
...
#TLS_CACERT     /etc/pki/tls/cert.pem
TLS_CACERT     /etc/pki/tls/ldapserver.crt

Create OpenLDAP Base DN

Next, create your base DN or search base to define your organization structure and directory.

Replace the domain components and organization units accordingly.

cat > basedn.ldif << 'EOL'
dn: dc=ldapmaster,dc=kifarunix-demo,dc=com
objectClass: dcObject
objectClass: organization
objectClass: top
o: Kifarunix-demo
dc: ldapmaster

dn: ou=groups,dc=ldapmaster,dc=kifarunix-demo,dc=com
objectClass: organizationalUnit
objectClass: top
ou: groups

dn: ou=people,dc=ldapmaster,dc=kifarunix-demo,dc=com
objectClass: organizationalUnit
objectClass: top
ou: people
EOL
ldapadd -Y EXTERNAL -H ldapi:/// -f basedn.ldif

Create OpenLDAP User Accounts

You can add users to your OpenLDAP server. Create an ldif file to define your users as follows.


cat > users.ldif << 'EOL'
dn: uid=johndoe,ou=people,dc=ldapmaster,dc=kifarunix-demo,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: johndoe
cn: John
sn: Doe
loginShell: /bin/bash
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/johndoe
shadowMax: 60
shadowMin: 1
shadowWarning: 7
shadowInactive: 7
shadowLastChange: 0

dn: cn=johndoe,ou=groups,dc=ldapmaster,dc=kifarunix-demo,dc=com
objectClass: posixGroup
cn: johndoe
gidNumber: 10000
memberUid: johndoe
EOL

Add the user to the OpenLDAP database.

ldapadd -Y EXTERNAL -H ldapi:/// -f users.ldif

Setting password for LDAP User

To set the password for user above, run the command below;

ldappasswd -H ldapi:/// -Y EXTERNAL \
-S "uid=johndoe,ou=people,dc=ldapmaster,dc=kifarunix-demo,dc=com"

Create OpenLDAP Bind DN and Bind DN User

Bind DN user is used for performing LDAP operations such as resolving User IDs and group IDs. In this guide, we create a bind DN ou called system. Note the access controls associated with this ou as defined on the root DN above.

List the Access control lists on the database;

ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// \
-b cn=config '(olcDatabase={1}mdb)' olcAccess

Create the BindDN user password.

slappasswd
New password: Password
Re-enter new password: Password
{SSHA}q3hP3Vfr+4PgF6TE70MPy2yNrEDbGZvs

Paste the password hash value above as the value of userPassword attribute in the file below;


cat > bindDNuser.ldif << 'EOL'
dn: ou=system,dc=ldapmaster,dc=kifarunix-demo,dc=com
objectClass: organizationalUnit
objectClass: top
ou: system

dn: cn=readonly,ou=system,dc=ldapmaster,dc=kifarunix-demo,dc=com
objectClass: organizationalRole
objectClass: simpleSecurityObject
cn: readonly
userPassword: {SSHA}q3hP3Vfr+4PgF6TE70MPy2yNrEDbGZvs
description: Bind DN user for LDAP Operations
EOL
ldapadd -Y EXTERNAL -H ldapi:/// -f bindDNuser.ldif

Allow OpenLDAP Service on Firewall

To allow remote clients to query OpenLDAP server, allow the ldap (389 UDP/TCP) and ldaps (636 UDP/TCP) service on firewall.

firewall-cmd --add-service={ldap,ldaps} --permanent
firewall-cmd --reload

Testing OpenLDAP Authentication

Well, there you go. You have learnt how to install and setup OpenLDAP server on Rocky Linux 9.

To verify that users can actually connect to the systems via the OpenLDAP server, you need to configure OpenLDAP clients on the remote systems.

See the guide below;

Configure SSSD for LDAP Authentication on Rocky Linux 8

Other Tutorials

Configure Squid Proxy OpenLDAP Authentication on pfSense

Configure OpenLDAP Password Expiry Email Notification

Configure OpenVPN LDAP Based Authentication

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
Kifarunix
Linux Certified Engineer, with a passion for open-source technology and a strong understanding of Linux systems. With experience in system administration, troubleshooting, and automation, I am skilled in maintaining and optimizing Linux infrastructure.

Leave a Comment