OpenLDAP

From Secure Computing Wiki
Revision as of 17:46, 23 November 2010 by Esubiguxoc (Talk | contribs)

Jump to: navigation, search


This Page Is Currently Under Construction And Will Be Available Shortly, Please Visit Reserve Copy Page


CLICK HERE


So, at work, we've finally got enough systems and users that we're seriously considering an OpenLDAP server for authentication, as well as for our customer/client contact lists, etc. I've never before successfully rolled out an LDAP system, and I've for certain never rolled one out that does authentication for any systems.

This document aims to describe the installation of OpenLDAP 2.4.7 on a FreeBSD 6.x system. The vast majority of these steps are easily applied to Linux, Unix, and Mac OS X.

System Overview

As we're big fans of ezjail, we're going to install an LDAP system with one master server, and one slave. All of our email clients will be pointed to the slave for read operations, with that server redirecting any writes to the master server. With version 2.4.x of OpenLDAP, replication is implemented in a couple unique ways. [1] We're going to setup a system with one master and one slave, with all writes directed to the master.

To keep things simpler, I'm only going to cover setting up a single server on this page. For the replication portion, please see OpenLDAP/replication.

Installation

In our setup, we're going to have two OpenLDAP servers (one master, one slave). To begin, we install the following ports:

  • net/openldap-server24
    • enable SASL
    • other defaults should be fine

Configuration

/etc/rc.conf

Now that we have all the ports installed, edit /etc/rc.conf and add the following lines: <pre>slapd_enable="YES" </pre>

OpenLDAP Configuration

Now that we have openldap, php5 and apache22 installed, we need to setup our slapd.conf file. The first thing to take into consideration is the function of your directory. In our installation, we're going to use it for an address book and an authentication server. As such, we're going to need the following schemas:

  • core.schema
  • cosine.schema
  • inetorgperson.schema
  • nis.schema

You can look to ldap schemas for more information about the different types.

Our configuration file (/usr/local/etc/openldap/slapd.conf) looks like this, with explanation:

<pre>

    1. MASTER LDAP SERVER
  1. Specify the location of the file to append changes to.

</pre>

Here, we define our included schemas, as discussed above. <pre>

  1. Global Section

include /usr/local/etc/openldap/schema/core.schema include /usr/local/etc/openldap/schema/cosine.schema include /usr/local/etc/openldap/schema/inetorgperson.schema include /usr/local/etc/openldap/schema/nis.schema </pre>

OpenLDAP uses a bit-based method for determining log level. A value of 296 gives us good verbosity for testing and initial configuration. See the man page for more information on this value. <pre> loglevel 296 </pre>

Leave these at their default value. <pre> pidfile /var/run/openldap/slapd.pid argsfile /var/run/openldap/slapd.args </pre>

The SSHA password hash is default for OpenLDAP. We're going to use this in our setup. 3DES, DES, and MD5 are other valid options. <pre>

  1. Misc Security Settings

password-hash {SSHA} </pre>

We're using the Berkely Database engine, which is defined here. You can also use SQL and others. <pre>

  1. Load dynamic backend modules:

modulepath /usr/local/libexec/openldap moduleload back_bdb

  1. BDB database definitions

database bdb </pre>

Here, we need to define our directory root and our rootdn. <pre> suffix "dc=example,dc=com" rootdn "cn=root,dc=example,dc=com" </pre>

For the rootpw, you have a couple options for entering your password. For our demonstration, we're entering a clear-text password. In a production setup, you should run the slappasswd command, and enter your password. Assuming the password is secret, the output from slappasswd would be similar to: <pre># slappasswd <enter> New password: secret <enter> (text is echo off) Re-enter new password: secret <enter> (text is echo off) {SSHA}0H+zTv8o4MR4H43n03eCsvw1luG8LdB7</pre>

If we wanted a hashed version stored in our configuration file, we'd enter the text {SSHA}0H+zTv8o4MR4H43n03eCsvw1luG8LdB7 in place of secret below: <pre>

  1. Cleartext passwords, especially for the rootdn, should
  2. be avoid. See slappasswd(8) and slapd.conf(5) for details.
  3. Use of strong authentication encouraged.

rootpw secret </pre>

Create the directory you want your OpenLDAP directory stored in and set the permissions to 0600. <pre>

  1. The database directory MUST exist prior to running slapd AND
  2. should only be accessible by the slapd and slap tools.
  3. Mode 700 recommended.

directory /var/db/example.com mode 0600 </pre>

This section defines the fields we want to index. <pre>

  1. Indices to maintain

index objectClass eq index cn,sn,mail eq,sub index uidNumber eq index gidNumber eq </pre>

Our configuration is going to use TLS to encrypt the data between systems. We don't want user credentials flying around our network in clear text. See our page on OpenSSL for information on creating a root CA, and the associated certificates. <pre> TLSCipherSuite HIGH:MEDIUM:+SSLv2 TLSCACertificateFile /usr/local/etc/openldap/ca.crt TLSCertificateFile /usr/local/etc/openldap/client.crt TLSCertificateKeyFile /usr/local/etc/openldap/client.key

TLSVerifyClient demand </pre>

Access control lists are what defines what each authenticated or anonymous user is able to do within the directory. These should go at the end of the configuration file. Here, we have two access control lists. The first ACL states that access to the userPassword attribute, within ou=people,dc=example,dc=com is only writable by the owner, is available for authentication by anyone, and is writable by ou=admins,ou=staff,ou=people,dc=example,dc=com. The second ACL states that all fields a readable by anyone, including anonymous users. <pre>## ACLs

  1. Restrict userPassword to be used for authentication only,
  2. but allow users to update their own password.

access to dn.children="ou=people,dc=example,dc=com"

attrs=userPassword
by self write
by * auth
by dn.children="ou=admin,ou=staff,ou=people,dc=example,dc=com" write
  1. Read access to the world.

access to *

by * read

</pre>

The completed file, without comments, looks so: <pre>## MASTER LDAP SERVER

  1. Global Section

include /usr/local/etc/openldap/schema/core.schema include /usr/local/etc/openldap/schema/cosine.schema include /usr/local/etc/openldap/schema/inetorgperson.schema include /usr/local/etc/openldap/schema/nis.schema

loglevel 296

pidfile /var/run/openldap/slapd.pid argsfile /var/run/openldap/slapd.args

  1. Misc Security Settings

password-hash {SSHA}

  1. Load dynamic backend modules:

modulepath /usr/local/libexec/openldap moduleload back_bdb

  1. BDB database definitions

database bdb

suffix "dc=example,dc=com" rootdn "cn=root,dc=example,dc=com"

  1. Cleartext passwords, especially for the rootdn, should
  2. be avoid. See slappasswd(8) and slapd.conf(5) for details.
  3. Use of strong authentication encouraged.

rootpw secret

  1. The database directory MUST exist prior to running slapd AND
  2. should only be accessible by the slapd and slap tools.
  3. Mode 700 recommended.

directory /var/db/example.com mode 0600

  1. Indices to maintain

index objectClass eq index cn,sn,mail eq,sub index uidNumber eq index gidNumber eq

TLSCipherSuite HIGH:MEDIUM:+SSLv2 TLSCACertificateFile /usr/local/etc/openldap/ca.crt TLSCertificateFile /usr/local/etc/openldap/client.crt TLSCertificateKeyFile /usr/local/etc/openldap/client.key

TLCVerifyClient demand

    1. ACLs
  1. Restrict userPassword to be used for authentication only,
  2. but allow users to update their own password.

access to dn.children="ou=people,dc=example,dc=com"

attrs=userPassword
by self write
by * auth
by dn.children="ou=admin,ou=staff,ou=people,dc=example,dc=com" write
  1. Read access to the world.

access to *

by * read</pre>

Once we've got this file saved, create the directory you referenced for the database store, set permissions to 0600 and chown to your openldap users (ldap/ldap if you installed OpenLDAP from ports). Lastly, go ahead and try to start slapd from it's rc.d script: <pre># /usr/local/etc/rc.d/slapd start</pre> Check that it's running (sockstat | grep slapd is my method). If you do not see slapd listed as running, check your log files for any errors. If you've followed my directions up to this point, you should be good to go. At this point, stop slapd with the following command: <pre># /usr/local/etc/rc.d/slapd stop</pre> Slapd can't be running for our initial load of the database.

Initial Database Load

Our initial database load is going to define the structure of our directory tree. The following text should be saved somewhere as initial.ldif. I'm not going to describe it in detail, as this is supposed to be a quick how-to.

Our tree is going to follow the following structure:

Example.com OpenLDAP Tree Structure

<pre>

    1. Build the root node.

dn: dc=example,dc=com dc: example objectClass: dcObject objectClass: organizationalUnit ou: Example

    1. Build the people ou.

dn: ou=people,dc=example,dc=com ou: people objectClass: organizationalUnit

      1. Build the staff/people ou.

dn: ou=staff,ou=people,dc=example,dc=com ou: staff objectClass: organizationalUnit

        1. Build the admin/staff/people ou.

dn: ou=admin,ou=staff,ou=people,dc=example,dc=com ou: admin objectClass: organizationalUnit

      1. Build the users/staff/people ou.

dn: ou=users,ou=staff,ou=people,dc=example,dc=com ou: users objectClass: organizationalUnit

    1. Build the contacts/people ou.

dn: ou=contacts,ou=people,dc=example,dc=com ou: contacts objectClass: organizationalUnit

    1. Build the group/people ou.

dn: ou=group,ou=people,dc=example,dc=com ou: group objectClass: organizationalUnit

    1. Build the services ou.

dn: ou=services,dc=example,dc=com ou: services objectClass: organizationalUnit

    1. Build the hosts ou.

dn: ou=hosts,dc=example,dc=com ou: hosts objectClass: organizationalUnit </pre>

As was mentioned in the last section, slapd cannot be running for this initial load. That being said, run the following command, assuming the above configuration has been named ~/initial.ldif: <pre># slapadd -v -l ~/initial.ldif <enter> bdb_db_open: warning - no DB_CONFIG file found in directory /var/db/example.com: (2). Expect poor performance for suffix "dc=example,dc=com". added: "dc=example,dc=com" (00000001) added: "ou=people,dc=example,dc=com" (00000002) added: "ou=staff,ou=people,dc=example,dc=com" (00000003) added: "ou=admin,ou=staff,ou=people,dc=example,dc=com" (00000004) added: "ou=users,ou=staff,ou=people,dc=example,dc=com" (00000005) added: "ou=contacts,ou=people,dc=example,dc=com" (00000006) added: "ou=group,ou=people,dc=example,dc=com" (00000007) added: "ou=services,dc=example,dc=com" (00000008) added: "ou=hosts,dc=example,dc=com" (00000009)</pre>

If you got the error above that I did, you need to copy the file DB_CONFIG from /usr/local/etc/openldap/DB_CONFIG.example to the directory for your LDAP database. In our case, the following command will resolve this error: <pre># cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/example.com/DB_CONFIG</pre> This document doesn't discuss the purpose or use for this file. Please see OpenLDAP/DB_CONFIG for more information.

If you did the above as the root user, we need to chmod all of the files within the database directory to the ldap user. On my FreeBSD system, I would execute the following command: <pre># chown -R ldap:ldap /var/db/example.com</pre>

You can now start the slapd daemon: <pre># /usr/local/etc/rc.d/slapd start</pre>

Check your /var/log/all.log for any errors. If there aren't any errors, congratulations, you've got a running LDAP server! Now, we just need to add data. Also, from this point you should be able to log in via the phpldapadmin scripts on the web server we also configured. When asked for the username and password, use the entries you put in the slapd.conf file earlier. In our case, our user name would be cn=root,dc=example,dc=com and our password would be secret.

Adding Records

Once we have our core schema loaded, and the primary structure of our directory, we can add entries via a couple methods. While I'll briefly discuss adding LDAP entries via the phpldapadmin interface, my concentration is going to be with manual adds with text LDIF files.

Manual Adds

Manually adding an entry to your OpenLDAP directory is done by first creating an LDIF file with the entry data. Our example database has two purposes on our network.

  1. Server Authentication
  2. Company Address Book

LDIF File

First, we'll add an entry for the address book. I created a file called user.ldif containing the following information: <pre>## Test ldif for ecrist user dn: cn=Eric F Crist,ou=admin,ou=staff,ou=people,dc=example,dc=com cn: Eric F Crist sn: Crist mail: ecrist@foobeans.com mail: ecrist@secure-computing.net labeledURI: http://www.secure-computing.net departmentNumber: IT telephoneNumber: (411) 555-1212 mobile: (411) 555-0411 objectClass: inetOrgPerson</pre>

As you'll note, the format closely follows that of our initial database import. Also, you'll note that we can have more than one mail, phone, etc. Again, specific discussion of the various schema is beyond the scope of this document. You can have more than one entry per file, simply separate the two with an empty line.

Import

Since we started our LDAP server earlier, we're going to use the ldapadd program to add this entry to our database. Assuming your file name is user.ldif, as mine is above, running the following command should import your new entries into your database: <pre># ldapadd -D "cn=root,dc=example,dc=com" -w <password> -x -a -f user.ldif adding new entry "cn=Eric F Crist,ou=admin,ou=staff,ou=people,dc=example,dc=com"

</pre>

Related Topics

References