Ben Stienstra

Linux, Unix, network, radio and more...

User Tools

Site Tools


CentOS 7 - OpenLDAP 2.4 consumer (slave)

Install SSSd client

TLS Certificate

  • Create a certificate and sign with CA, valid for 3 years. You probably need to perform this step on the LDAP provider or CA system:
    # certutil -S -n 'OpenLDAP Consumer' -t ",," \
    -c LDAP-CA \
    -f /etc/openldap/certs/password \
    -d /etc/openldap/certs \
    -z /tmp/noise.txt \
    -s "CN=OpenLDAP Consumer,OU=IT,O=Company,L=City,ST=State,C=NL" \
    -8 "ldap.domain.tld,ldap.mgmt.domain.tld-example!" \
    -v 36 \
    -Z SHA256 \
    -g 4096
  • Export the signed certificate and key:
    # pk12util -d /etc/openldap/certs -o /root/consumer.p12 -n "OpenLDAP Consumer" -k /etc/openldap/certs/password 
    Enter password for PKCS12 file: ...
    Re-enter password: ...
  • Export the CA certificate:
    # certutil -L -d /etc/openldap/certs -n "LDAP-CA" -a > /tmp/ca.crt
  • On the consumer, create the certificate database directory, if it does not already exisist:
    # mkdir /etc/openldap/certs
  • Generate a secure password:
    # pwgen -sy 32 1 > /etc/openldap/certs/password
  • Create a new empty database, if it does not already exists:
    # certutil -d /etc/openldap/certs -N -f /etc/openldap/certs/password
  • Copy the file to the consumer and import it to the NSS database:
    # pk12util -d /etc/openldap/certs -i /tmp/consumer.p12 -k /etc/openldap/certs/password 
    Enter password for PKCS12 file: 
  • Import the CA certificate:
    # certutil -A -n "LDAP-CA" -t "TCu,Cu,Cu" -i /tmp/ca.crt -d /etc/openldap/certs
  • Modify rights so that LDAP can read the NSS database:
    # chmod 440 /etc/openldap/certs/password
    # chown ldap. /etc/openldap/certs/*


  • List all certificates:
    # certutil -L -d /etc/openldap/certs/
  • List all private keys in the database:
    # certutil -K -d /etc/openldap/certs/ -f /etc/openldap/certs/password
  • View certificate:
    # certutil -L -d /etc/openldap/certs/ -n "OpenLDAP Consumer"
  • Verify certificate:
    # certutil -V -d /etc/openldap/certs -n "OpenLDAP Consumer" -u C
    certutil: certificate is valid
  • You now have an encrypted private key and signed certificate for the consumer server.

Install and configure OpenLDAP

  • Install required packages:
    # yum install openldap-clients openldap-servers openldap pam_ldap nss-pam-ldapd pam_krb5 sssd migrationtools openldap-devel
  • Activate LDAPS (TLS), change ldap to ldaps, only start LDAPS and LDAPI (IPC socket):
    # vi /etc/sysconfig/slapd
    SLAPD_URLS="ldapi:/// ldaps:///"
    # Any custom options
    SLAPD_OPTIONS="-g ldap"
  • Modify /etc/openldap/ldap.conf:
    # vi /etc/openldap/ldap.conf
    BASE    dc=<domain>,dc=<tld>
    URI     ldaps://<FQDN>
    TLS_CACERTDIR  /etc/openldap/certs
    TLS_REQCERT demand
  • Use the DB config example. You can configure the DB_LOG_AUTOREMOVE directive in DB_CONFIG, but If the log files are removed automatically, recovery after a catastrophic failure is likely to be impossible.:
    # install -m 644 -o ldap -g ldap /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
  • Start OpenLDAP:
    slaptest -u
    systemctl start slapd
    systemctl enable slapd
  • Add required schema's:
    core.schema		OpenLDAP core (required)
    cosine.schema		Cosine and Internet X.500 (useful)
    inetorgperson.schema	InetOrgPerson (useful)
    nis.schema		Network Information Services (FYI)
    # ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
    # ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
    # ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
  • Generate an LDAP root password, you need this hash in the next steps:
    # slappasswd
    New password: <password>
    Re-enter new password: <password>
  • Export variables used in next steps:
    # export MYHASH="{SSHA}your-hash"
    # export MYDOMAIN=your-domain
    # export MYTLD=your-tld
  • olcDatabase={0}config: Add a root password, and modify the olcAccess in order to (at least) require a password using simple authentication
    # ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
    dn: olcDatabase={0}config,cn=config
    changetype: modify
    add: olcRootPW
    olcRootPW: ${MYHASH}
    replace: olcAccess
    olcAccess: {0}to * 
           by dn.base="cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" manage
           by * none
  • olcDatabase={1}monitor: Change the monitor ACL:
    # ldapmodify -H ldapi:/// -x -D "cn=config" -W <<EOF
    dn: olcDatabase={1}monitor,cn=config
    changetype: modify
    replace: olcAccess
    olcAccess: {0}to *
           by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
           by dn.base="cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" read
           by * none
  • olcDatabase={2}hdb: Change the standard DN suffix and root password
    # ldapmodify -H ldapi:/// -x -D "cn=config" -W <<EOF
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    replace: olcSuffix
    olcSuffix: dc=${MYDOMAIN},dc=${MYTLD}
    replace: olcRootDN
    olcRootDN: cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}
    add: olcRootPW
    olcRootPW: ${MYHASH}
  • olcDatabase={2}hdb: configure indexing:
    # ldapmodify -H ldapi:/// -x -D "cn=config" -W <<EOF
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    replace: olcDbIndex
    olcDbIndex: objectClass eq,pres
    olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
    olcDbIndex: uid,memberUid,gidNumber eq
  • Modify the TLS configuration. …the current implementation doesn't support encrypted keys so the key must not be encrypted and the file itself must be protected carefully.
    # ldapmodify -H ldapi:/// -x -D "cn=config" -W <<EOF
    dn: cn=config
    changetype: modify
    replace: olcTLSCertificateFile
    olcTLSCertificateFile: "OpenLDAP Consumer"
    replace: olcTLSCipherSuite
    olcTLSCipherSuite: HIGH
    replace: olcTLSProtocolMin
    olcTLSProtocolMin: 3.1
    replace: olcDisallows
    olcDisallows: bind_anon
    replace: olcIdleTimeout
    olcIdleTimeout: 120
  • olcDatabase={-1}frontend: Due to a bug i was not able to perform this step… I had to manually edit the olcDatabase={-1}frontend.ldif file and set olcDatabase to “olcDatabase: {-1}frontend”. Then restart slapd!
  • Set global options: Some backend types, such as frontend and monitor use a hard-coded suffix which may not be overridden in the configuration. Access controls defined in the frontend are appended to all other databases' controls. Configure password and require LDAPv3:
    # ldapmodify -H ldapi:/// -x -D "cn=config" -W <<EOF
    dn: olcDatabase={-1}frontend,cn=config
    changetype: modify
    add: olcPasswordHash
    olcPasswordHash: ${MYHASH}
    add: olcRequires
    olcRequires: LDAPv3 authc
  • Accept only TLS:
    # ldapmodify -H ldaps://<FQDN> -x -D "cn=config" -W <<EOF
    dn: cn=config
    changetype: modify
    add: olcSecurity
    olcSecurity: tls=1

Open firewall port

  • Open port 636:
    # firewall-cmd --permanent --zone public --add-service=ldaps
    # firewall-cmd --reload

Test and verify

  • Test server config, restart and test connectivity:
    # slaptest -u
    # systemctl restart slapd
    # openssl s_client -connect localhost:636 -showcerts -CAfile /etc/openldap/cacerts/ca.crt
        Verify return code: 0 (ok)
    # ldapwhoami -H ldaps://<FQDN> -x -D "cn=Manager,dc=<domain>,dc=<tld>" -W
    # ldapsearch -H ldaps://<FQDN> -x -D "cn=Manager,dc=<domain>,dc=<tld>" -W
    # ldapsearch -H ldap://<FQDN> -x -D "cn=Manager,dc=<domain>,dc=<tld>" -W
    ldap_bind: Confidentiality required (13)
    	additional info: TLS confidentiality required
    ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

Configure replication

  • On the provider (master): create a replicator user:
    # ldapadd -H ldaps://<FQDN> -x -D "cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" -W <<EOF
    dn: cn=replicator,dc=${MYDOMAIN},dc=${MYTLD}
    objectClass: simpleSecurityObject
    objectClass: organizationalRole
    cn: replicator
    userPassword: <your replicator password SSHA hash>
  • On the provider (master): create an ACL for the replicator user:
    # ldapadd -H ldaps://<FQDN> -x -D "cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" -W <<EOF
    dn: olcDatabase={2}bdb,cn=config
    changetype: modify
    replace: olcAccess
    olcAccess: {0}to attrs=userPassword,shadowLastChange
           by dn.exact="cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" write
           by dn.exact="cn=replicator,dc=polaire,dc=nl" read
           by self =xw
           by anonymous auth
           by * none
    olcAccess: {1}to *
           by dn.exact="cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" write
           by dn.exact="cn=replicator,dc=polaire,dc=nl" read
           by self read
           by users read
           by * none
  • On all servers (provider and consumers) install the syncprov module:
    # ldapadd -H ldaps://<FQDN> -x -D "cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" -W <<EOF
    dn: cn=module,cn=config
    objectClass: olcModuleList
    cn: module
    olcModulePath: /usr/lib64/openldap
  • On the provider configure the sync overlay:
    # ldapadd -H ldaps://<FQDN> -x -D "cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" -W <<EOF
    dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
    changetype: add
    objectClass: olcOverlayConfig
    objectClass: olcSyncProvConfig
    olcOverlay: syncprov
  • Configure slave:
    ldapadd -H ldaps://ldapconsumer.yourdomain.tld -x -D "cn=Manager,dc=${MYDOMAIN},dc=${MYTLD}" -W <<EOF
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    add: olcSyncrepl
    olcsyncrepl: {0}rid=014
      retry="5 5 300 +" 

Monitor replication state

  • contextCSN needs to be the same on provider and consumer:
    # ldapsearch -H ldaps://provider -x -D "cn=Manager,dc=<basedn>" -w <passwd> -s base contextcsn | grep contextCSN
    # ldapsearch -H ldaps://consumer -x -D "cn=Manager,dc=<basedn>" -w <passwd> -s base contextcsn | grep contextCSN
openldap_consumer.txt · Last modified: 2015/09/21 08:46 by admin