From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a work in progress by Onkobu (talk | contribs). Treat its contents with caution.

OpenLDAP is a free LDAP server implementation offering a directory based data structure. Many hosts, services and users in a computer network can be managed. The directory service enables user or service lookup, permission management, centralized login, key infrastructure and much more.


USE flags

USE flags for net-nds/openldap LDAP suite of application and development tools

argon2 Enable password hashing algorithm from app-crypt/argon2
autoca Automatic Certificate Authority overlay
cleartext Enable use of cleartext passwords
crypt Add support for encryption -- using mcrypt or gpg where applicable
cxx Build support for C++ (bindings, extra libraries, code generation, ...)
debug Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see
experimental Enable experimental backend options
gnutls Prefer net-libs/gnutls as SSL/TLS provider (ineffective with USE=-ssl)
iodbc Add support for iODBC library
ipv6 Add support for IP version 6
kerberos Add kerberos support
kinit Enable support for kerberos init
minimal Build libraries & userspace tools only. Does not install any server code
odbc Enable ODBC and SQL backend options
overlays Enable contributed OpenLDAP overlays
pbkdf2 Enable support for pbkdf2 passwords
perl Add optional support/bindings for the Perl language
samba Add support for SAMBA (Windows File and Printer sharing)
sasl Add support for the Simple Authentication and Security Layer
selinux !!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur
sha2 Enable support for pw-sha2 password hashes
smbkrb5passwd Enable overlay for syncing ldap, unix and lanman passwords
ssl Add support for SSL/TLS connections (Secure Socket Layer / Transport Layer Security)
static-libs Build static versions of dynamic libraries as well
syslog Enable support for syslog
systemd Enable use of systemd-specific libraries and features like socket activation or session tracking
tcpd Add support for TCP wrappers
test Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently)


Preferrably enable USE flags:

  • crypt to provide encryption
  • sasl to bootstrap configuration through Simple Authentication and Security Layer
  • ssl to encrypt all traffic over the network so that passwords stay safe
  • syslog to be able to process events further, e.g. failed login attempts


  • pbkdf2 for password encryption with this algorithm
  • overlays if you really need them (see Advanced configuration below)
root #emerge --ask net-nds/openldap


OCL-only, distinguish between slapadd, ldapadd with Manager role


LDAP in general is a mature and therefore complex topic. This section will not go into the details but only introduce the terms. Either look them up in the documentation or get a good book explaining directory storages. Keep in mind that the term database is used in the broadest possible definition. Do not expect the various databases mentioned in the following paragraphs to behave like relational ones.

First it is necessary to configure the slapd service runtime before any database can be accessed. This starts with environment variables to limit access to either TLS or local Unix socket. Non-TLS access over the network must be disabled to prevent package sniffing of sensitive data. OpenLDAP supports STARTTLS as well as TLS. The latter will be configured.

If the host is further secured by a firewall open ports for LDAP accordingly. With multiple network adapters think about binding only to the necessary IPs. None of the topics is covered here.

To safely run a directory service accessed through LDAP OpenLDAP offers two default databases and a third database is going to be added. It will hold user accounts and related data. All references require a distinguished name (DN) for everything from the database down to attributes of entities. For the third database the DN will be dc=genfic,dc=org. It looks like a domain name, feel free to adjust to your needs. All three databases:

  • dn: olcDatabase=frontend,cn=config – frontend holds global values/ defaults
  • dn: olcDatabase=config,cn=config – configuration database
  • dc=genfic,dc=org – syntactically correct DN would be dn: olcDatabase={1}mdb,cn=config

Queries will hit dc=genfic,dc=org first. Because the other two are sort of system databases and hold sensitive information only a manager role should be allowed to read and modify. In addition this manager should invoke commands only from the host running OpenLDAP using OpenLDAP's Unix socket and not the network. This leads to the following roles and accounts:

  • root, recognized by uid=gid=0, through SASL and Unix socket, general access
  • cn=Manager,dc=genfic,dc=org, through TLS, create, delete and edit entries in dc=genfic,dc=org
  • cn=ldapreader,dc=genfic,dc=org, through TLS, read only

As a third aspect a LDAP directory supports schema definitions. For example the schema posixAccount defines which attributes, types and rules belong to a POSIX user account. In combination with the schema posixGroup it is possible to express membership relations so that a POSIX group holds none or many users.

A directory service in general and schemas in detail hold attributes. Attributes are treated as relationships but they are neither traversable nor queryable. You can not query a user of type posixAccount and the groups the user belongs to. Instead all groups must be queried to find those of type posixGroup with an attribute memberUID with the uid-value of the particular user.

To conclude this section:

  • OpenLDAP is configured below the databases (TLS, protocols, disable deprecated configuration)
  • frontend and config will be populated with schema and access configuration
  • slapd can be started
  • the third database dc=genfic,dc=org will be filled with groups and users

The last three steps use LDIF as format. This is the current and preferred way of configuring OpenLDAP. Choose file names that imply an order. Also write sufficient comments and explanations into your personal setup. If such a setup finally works for 2 years or longer you will not remember the details.

Non goals

  • DNS setup, expected to evaluate to the host running OpenLDAP
  • details of LDIF
  • syslog configuration
  • firewall configuration
  • schema editing

Configuration files

  • /etc/conf.d/slapd
  • /etc/openldap/ssl
  • /var/.../openldap-data
  • /etc/openldap/slapd.d


Server authenticity is asserted right from the start. This makes man-in-the-middle or spoofing attacks much harder. Some use cases could require a first query without TLS to let a client discover such a capability first. This approach is not covered here. And it still requires checking the server's authenticity.

frontend and config

  • mkdir -p /etc/openldap/slapd.d
  • slappasswd for manager, insert in script, olcRootPW

Save the following file and install with slapadd -F /etc/openldap/slapd.d -n 0 -l /etc/openldap/00_slapd.ldif.

FILE /etc/openldap/00_slapd.ldif
dn: cn=config
objectClass: olcGlobal
cn: config

olcArgsFile: /run/openldap/slapd.args
olcPidFile: /run/openldap/
olcTLSCertificateFile: /etc/openldap/ssl/ldap.cer
olcTLSCertificateKeyFile: /etc/openldap/ssl/ldap.key

dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath:	/usr/lib64/openldap/openldap

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

include: file:///etc/openldap/schema/core.ldif
include: file:///etc/openldap/schema/cosine.ldif
include: file:///etc/openldap/schema/inetorgperson.ldif
include: file:///etc/openldap/schema/nis.ldif
include: file:///etc/openldap/schema/misc.ldif

# Default ACL
dn: olcDatabase=frontend,cn=config
objectClass: olcDatabaseConfig
olcDatabase: frontend
olcAccess: to dn.base="cn=Subschema" by * read
olcAccess: to *
    by self write
    by users read
    by anonymous auth

# SASL, root user becomes manager of config database
dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: {0}to *  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage  by * none
olcAddContentAcl: TRUE
olcLastMod: TRUE
olcMaxDerefDepth: 15
olcReadOnly: FALSE
olcRootDN: cn=config
olcSyncUseSubentry: FALSE
olcMonitoring: FALSE

# Database holding the DIT
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcSuffix: dc=genfic,dc=org
olcRootDN: cn=Manager,dc=genfic,dc=org
# Cleartext passwords, especially for the rootdn, are
# insecure.  See slappasswd(8) and slapd-config(5) for details.
# Use of strong authentication encouraged.
olcRootPW: {SSHA}jZghO...6+Mm+3/IrEIZfAr+uu
# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
olcDbDirectory:	/var/lib/openldap-data
# Indices to maintain
olcDbIndex: objectClass eq 

  • chown -R ldap slapd.d
  • start slapd
  • query config database


Many explanations suggest to sort groups and users under so called organizational units (ou=...) This example omits OUs completely. For a small directory this has absolutely no downside. Large directories of 10.000 entities suffer from such a grouping by type. Organizational units must be treated by their nature as true subsets set apart from each other by a reason. For example a query to login a user and determine group assignments should not load all groups with all their memberUID-attributes of the entire directory[1]. It is much safer and much faster to first find the right organizational unit and traverse only its limited set of entities.
  • generate groups from any host/ extract with a script
  • ldapreader as simpleUserObject, representing a system account
  • Bert Ram, sample user
  • Manager role already defined by rootdn/ in config database


  • Basic setup of frontend and config db
  • base DN + read-user, prohobit anonymous reads
  • import user groups
  • sample user
  • sample query

Advanced configuration

Monitoring with Icinga2

  • Icinga2
  • either net-analyzer/nagios-plugins with USE=ldap
  • or small script that tries local bind without password and checks for error code 53 (server responds but unwilling to proceed without password)
  • scripts normally executed as user icinga/ daemon user, set permissions accordingly
  • like ACL for root on config similar ACL for icinga on DIT of, ldapsearch -Y EXTERNAL -H ldapi:/// – most secure (Unix-socket)

Overlay memberOf

  • overlay memberOf for reverse group assignment
  • not really useful but an example of the forward-only-nature of membership
  • attribute must be selected explicitly when queried


This entire page does not provide a very secure LDAP service. It sets the bar quite high. Test the setup thoroughly for vulnerabilities. Enable close monitoring and alerting. If LDAP is used for centralized login all hosts could be affected. A security flaw could grant access unrecognized and in the entire network.
  • access control and directory information tree could enable at least guessing entries by receiving different error codes (not found vs. invalid privileges) even without proper authentication or permission
  • ACLs allow to hide attributes, mind the defaults that often allow unauthenticated world readable attributes, sometimes they are omitted in simple queries but are visible if selected explicitely
  • unique identifiers must be really unique, never re-assigned, unrelated to a real person's personal data and immutable over the entire lifespan, last names not only change but names in general are not limited to 2 words containing only US-ASCII characters[2]
  • make regular backups and check their usability


  • kill -INT `cat /run/openldap/` – Graceful shutdown if regular service script fails or a daemonized test run does not stop[3]

See also

Packages supporting LDAP-authentication/ user management:

  1. [1] groups are bad
  2. [2]Best Practices For Unique Identifiers
  3. [3]OpenLDAP Software 2.6 Administrator's Guide