OpenLDAP

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

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.

Installation

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 https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces
experimental Enable experimental backend options
gnutls Prefer net-libs/gnutls as SSL/TLS provider (ineffective with USE=-ssl)
iodbc Add support for iODBC library
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)

Emerge

Recommended USE flags:

  • any of argon2, pbkdf2, or sha2 to provide modern algorithms for secure hashing of passwords.
  • sasl to bootstrap configuration through Simple Authentication and Security Layer.
  • ssl to encrypt traffic over the network so that passwords stay safe.
  • syslog to log events, e.g. failed login attempts.
  • debug to enable use of -d flag.


Important
The utilities installed by OpenLDAP do not always provide helpful error messages. It is strongly recommended that the debug USE flag is enabled during the initial setup. Later, it can be disabled and OpenLDAP rebuilt without it, if desired.


root #emerge --ask net-nds/openldap


In addition to the Standalone LDAP Daemon (slapd), OpenLDAP installs two sets of utilities. Those prefixed with ldap (ldapadd, ldapmodify, ldapsearch, ...) and those prefixed with slap (slapadd, slapmodify, slaptest, ...).

  • The ldap* commands open a connection to a running ldap server (slapd or otherwise) and perform LDAP operations. They cannot be used if the LDAP server is not running.
  • The slap* commands operate on an OpenLDAP database stored somewhere on the filesystem. They should not be used to modify a database that is in use by a running instance of slapd. Even though the slap* commands may appear to succeed if they are run on a live database, they can actually interfere with normal slapd operation and potentially cause data corruption!

Configuration

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

Goal

LDAP in general is a mature and therefore complex topic. This section will not go into the details but only introduce the most important 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.

Note
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 and can be chosen freely. Feel free to adjust to your needs. All three databases (named with DN used later):

  • dn: olcDatabase=frontend,cn=config – frontend holds global values/ defaults, all entries not found the the other databases are answered here (always index -1 and not really a database)
  • dn: olcDatabase=config,cn=config – configuration database, holds all the configuration entries (always index 0)
  • dc=genfic,dc=org – the directory itself, mdb backend, syntactically correct DN would be dn: olcDatabase={1}mdb,cn=config (index 1, database backend mdb)

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 (Simple Authentication and Security Layer) 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. A schema sets up validation rules for entries. This includes attributes of an entry, their format as well as rules for auto generation, default values and so on. 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. When a new group is to be created the schema posixGroup determines the numerical value (and identifier) if none is given, e.g. numerical gid must be greater than 1000. After the setup only existing schemas are imported.

Note
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. Keep in mind that a directory service is not a relational database. Yet OpenLDAP supports advanced features to track such back references. See the advanced configuration for a simple group membership setup.

To conclude this section with the following steps:

  • OpenLDAP is configured in general (TLS, protocols, disable deprecated configuration), no databases involved
  • 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 and the so called on-line config (OLC) with zero downtime. This is the current and preferred way of configuring OpenLDAP. That means a running slapd instance receives add and modify requests. All changes will be stored in files first. This ensures low restore times. They are pushed as the root user on the LDAP host through command line into slapd.

Next the manager role is used and can be invoked theoretically from any host that is allowed to connect. Finally the general reader role is used for testing. Use this role and the commands from another host to assert access is working correctly.

In case your host is lost these LDIF (LDAP Data Interchange Format) files ensure low restore times. Keep those files in a safe place and security related ones containing passwords read protected or best stored offline. Choose file names that imply an order as order is important. The example start the file names with a two digit number leaving gaps of 10 for later improvements. Also write sufficient comments and explanations into your personal setup files. If such a setup finally works for 2 years or longer you will not remember the details.

Note
UIs will not work yet as there is no configuration. There are no roles the UI could connect to OpenLDAP and there is no schema that enforces structures. Setup external tools after the basic schema is up and running and for example POSIX groups queryable.
Note
Scripting the setup process is an advantage but not a must. Creating directories, fixing permissions and interleaving copy- or data extraction commands is error prone when done by hand repeatedly.

Non goals

DNS setup is not covered by this guide. All examples expect the LDAP host name is ldap.genfic.org. Technically it is not necessary to correlate the LDAP host's name with the directory structure.

The details of LDIF in general and schema editing must be read elsewhere. Some comments in the samples below outline the basic principles. Details cannot be covered here.

Finally embedding the service into your particular environment with an appropriate logging configuration or how to setup your firewall is not covered. The latter is explained in the Security Handbook.

Configuration files

  • /etc/conf.d/slapd – general options, allowed connection methods
  • /etc/openldap/ldap.conf – world readable LDAP defaults, not exclusively used by OpenLDAP but other programs as well
  • /etc/openldap/ssl – TLS configuration, keys/ certificates
  • /etc/openldap/slapd.d – location of config database, only experts should edit here directly (holds everything that was contained in /etc/openldap/slapd.conf)
  • /var/.../openldap-data – database location, perferrably on /var, only experts should edit here directly
Warning
It is still possible to configure OpenLDAP with /etc/openldap/slapd.conf. This guide uses the OLC approach and configuration under /etc/openldap/slapd.d. Both variants must not be mixed nevertheless slapd.conf must be available but has to be empty in turn. It is absolutely valid to copy slapd.d (recusively) before applying changes. In case something breaks or doesn't turn out right it is not necessary to write delete statements but restore the copy. Shutdown slapd before deleting/ restoring in the file system.

TLS

With TLS server authenticity is asserted right from the start. This makes man-in-the-middle or spoofing attacks much harder. Some use cases could require an initial 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. Since you already plan to setup a directory service and share it with other hosts in a small network become your own certificate authority. Self signed certificates are feasible for test setups. Free services like Let's Encrypt require reverse access to verify valid requests. See Certificates/Become your own CA for details.

If you plan to setup LDAP for centralized authentication do not skip this step. A service of uncertain authenticity with unencrypted communication leaks credentials on the wire. Avoid this security concern.

Create a private key for the LDAP service first. This step is necessary only once. Change parameters for most recent and secure key algorithm and key size like elliptic curve cryptography. Use a password protected key. This in turn requires password input everytime the service is (re-) started.

root #openssl genrsa -aes256 -out /etc/openldap/ssl/ldap.genfic.org.key 2048

And create a certificate signing request based on the key:

root #openssl req -new -key /etc/openldap/ssl/ldap.genfic.org.key -out ldap.genfic.org.csr

Finally the CA signs the CSR which yields a certificate:

root #openssl x509 -req -in ldap.genfic.org.csr -out ldap.genfic.org.cer -CA CA.cer -CAkey CA.key -sha256 -CAcreateserial

Copy the certificate file to /etc/openldap/ssl which will contain at least two files: the private key and the certificate file. The CSR is not necessary to run slapd.

Note
Adjust ownership and permissions so that only slapd is able to read both files but not write them.

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/slapd.pid
# TLS
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
olcModuleload:	back_mdb.so

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

dc=genfic,dc=org

Note
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

Steps

  • 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 genfic.org, 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

Security

Warning
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

Troubleshooting

  • kill -INT `cat /run/openldap/slapd.pid` – 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