1. Install required packages
The first step is to install the OpenLDAP software packages.
# yum install openldap-servers openldap-clients
2. Copy default DB_CONFIG
OpenLDAP typically defaults to using one of two varieties of the Berkeley DB storage format. The standard Berkeley DB format is indicated by “bdb”. A more recent version tuned for hierarchical databases like LDAP is known as “hdb”. CentOS/RHEL automatically creates an initial database with the hdb format.
The BDB derivatives are very tunable to a level to which most people will not be interested. The tuning is set in a file called DB_CONFIG which resides in the same directory as the database files (/var/lib/ldap). CentOS/RHEL offers a default tuning file and I generally use it unchanged which is located at:
/usr/share/openldap-servers/DB_CONFIG.example
First step is to copy this default file to the production directory:
# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
At this point you can start and enable de slapd service:
# systemctl start slapd
# systemctl enable slapd
3. Loading the standarnd schemas
An LDAP service is a database in one traditional sense. Each of the data objects is defined in a schema which describes the attributes of the object. The schema must be loaded into the configuration database before the objects they define can be used in the user database.
The standard schema are provided as LDIF files which can be loaded using the ldapadd command. The call is similar to the ldapsearch command above:
# ldapadd -Q -Y -H ldapi:/// -f filename;
One CentOS/RHEL systems, the stock schema files are located in /etc/openldap/schema. Each one is offered in both the original LDAP schema form and in LDIF. Most LDAP databases will use three standard schema to start:
- core
- cosine
- inetorgperson
These three define the basic objects and attributes needed to describe a typical organization: people, groups, rooms etc. Loading these three would look like this.
# ldapadd -Q -Y -H ldapi:/// -f /etc/openldap/schema/core.ldif
# ldapadd -Q -Y -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
# ldapadd -Q -Y -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
4. Set the Database Suffix
Let’s say our company’s DN is:
dc=example,dc=local
Changes made using ldapadd or ldapmodify are defined using LDIF in the same way that the output of ldapsearch is expressed in LDIF. We have to craft a change query for the olcSuffix of olcDatabase={2}hdb,cn=config and replace the existing value with our new one. Here’s what that looks like:
# ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=example,dc=local
EOF
modifying entry "olcDatabase={2}hdb,cn=config"
The ldapadd and ldapmodify commands expect a stream of LDIF on stdin unless an input file is indicated with the -f option. I provided the update stream as a shell HERE document indicated by the EOF markers.
5. Set the Root DN
Now that we’ve set the suffix for our database we need to update the DN of the user who will be able to make changes (who is not the root user on the LDAP server host).
User names in LDAP are Distinguished Names of objects stored within the database, the same as any other record. We might want to keep the (common) name “Manager” but we need to place it within the proper hierarchy for our database. Since our database is now dc=example,dc=local then the manager really must be cn=Manager,dc=example,dc=local. We’ll update that in the same way that we did the suffix.
# ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=example,dc=local
EOF
modifying entry "olcDatabase={2}hdb,cn=config"
6. Set the root password
The final step of the stock LDAP service set up is to create a database user password which can be used to make queries and changes without requiring the system root user to do it. The attribute for this password is olcRootPW. (it goes with the olcRootDN set above). If the RootPW is unset then the RootDN cannot log in. When you add this attribute, you are opening up access to the database a bit, but securing the system by allowing the DB admin to work without needing system root access.
The OpenLDAP service can store passwords in clear text (bad idea) or using one of several one-way hash algorithms. You can create a new password hash using the slappasswd command. The default hash is currently SHA1, which is better than all of the others but still not 100% secure.
# slappasswd
New password:
Re-enter new password:
{SSHA}hashstringgenerated
The generated hash string will be placed as the value of the olcRootPW attribute.
# ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}hashstringgenerated
EOF
modifying entry "olcDatabase={2}hdb,cn=config"
7. Create the top object in the database
Most organizations use their domain name as the pattern for the top DN and use an LDAP “organization” object for that top object. An organization object is a container. It is meant to have children of arbitrary types. This allows for the creation of any desired structure for the database. Because the suffix is a domain name, The object must also be a Domain Component object. Domain Components are not top level or container objects. They must have a parent. By combining the organization and domain component classes we create a top level object that can have the name we want.
Organization objects have only one required attribute. the o value is a string which is the organization’s name. It may also have a description attribute.
# ldapadd -x -w secret -D cn=Manager,dc=example,dc=local -H ldapi:/// <<EOF
dn: dc=example,dc=local
objectClass: dcObject
objectClass: organization
dc: example
o: example
structuralObjectClass: organization
EOF