Installing OpenDJ

This is a brief article on how OpenDJ gets installed around here.

NOTE: The order of operations described below IS significant.

Introduction

NOTE: Latest version of OpenDJ available is OpenDJ 2.6.0. It incorporates many bug fixes and improvements that are highly recommended.

This page will document a standard build of the OpenDJ LDAP directory server on Red Hat Enterprise Linux (RHEL) 6.

This procedure was developed from material contained in the OpenDJ Installation Guide.

Standard practice for most organizations is to run directory servers on port 389. This practice will be followed below with a twist: the server itself will run as a non-root user on ports above 1000, but the local server firewall (in Linux, iptables) will be used to redirect traffic coming in on standard ports 389 {for LDAP) and 636 (for LDAPS, or LDAP over SSL). Read about how to set that up here.

Standard file system layouts are specified below. These should be followed to avoid the necessity of customizing maintenance scripts (and documented procedures) to accommodate serendipitous installations. Use of the volume name “/opt/” is for illustrative purposes only. For example, you could substitute “/u01/” if your shop is married to that convention.

Note that because OpenDJ is a Java application it cannot be started as a non-privileged user if it is to listen on the standard LDAP/LDAPS ports 389/636. To run on ports lower than 1000, it must be owned by, and run as, root. The trick of using port redirection referred to above is used to get around this limitation.

The steps described here must be performed on all nodes unless otherwise noted.

Preparation

Create auxiliary directories:

/data/install/opendj

OpenDJ version 2.6.0 works with either Java 1.6 or 1.7, but 1.7 is recommended. The standard RHEL OpenJDK is preferred. Version 1.7 is not set as the default java by default on RHEL 6. You must use “/sbin/alternatives –configure” to do this.

Check that “$JAVA_HOME/bin/java -version” returns the correct version and platform.

Create application group and user opendj as root:

groupadd -g 2017 opendj
useradd -g opendj -u 2017 -c "OpenDJ Application User" opendj

(note that the group and user id should always be the same on all servers for interoperability and recovery purposes)

Set opendj’s password.

Create the backup directory and make opendj the owner:

mkdir /data/backup/ldap
chown opendj:opendj /data/backup/ldap

Create directory structure for application:

/opt/opendj

Download

Download software from ForgeRock.

Current version file is OpenDJ-2.6.0.zip.

Setup

Unzip OpenDJ distribution into /opt/opendj. Rename to type of directory server being configured, for a user store:

/opt/opendj/ds-user1

or an application configuration store:

/opt/opendj/ds-app1

Change ownership recursively on the unzipped distribution for a user store:

chown -R opendj:opendj ds-user1

Set permissions recursively on the installation directory:

chmod -R g+rw ds-user1

Create an .env file for the instance (e.g. ds-user1.env or ds-app1.env) in opendj’s home:

JAVA_HOME=/usr/lib/jvm/java
DSHOME=/opt/opendj/ds-user1
PATH=$DSHOME/bin:$JAVA_HOME/bin:$PATH
export JAVA_HOME DSHOME PATH

echo "$DSHOME environment set"

The above assumes use of the default RHEL 6 system java. To use the 3rd party Sun/Oracle Java “JAVA_HOME” would be set to “/usr/java/default”.

Note that the below example shows the setup of a user directory. The two main differences between this and the setup of a configuration directory is that the latter: (a) will be run as opendj, not root and; (b) configuration directories are not set up to do TLS or LDAPS.

Source this environment and then change directory into $DSHOME/bin. Run the setup routine in command line mode (“setup –cli”):

[opendj@testhost ds-user1]$ ./setup --cli

OpenDJ 2.6.0
Please wait while the setup program initializes...

What would you like to use as the initial root user DN for the Directory
Server? [cn=Directory Manager]: 
Please provide the password to use for the initial root user: 
Please re-enter the password for confirmation: 

On which port would you like the Directory Server to accept connections from
LDAP clients? [1389]: 1389

On which port would you like the Administration Connector to accept
connections? [4444]: 5444
Do you want to create base DNs in the server? (yes / no) [yes]: 

Provide the base DN for the directory data: [dc=example,dc=com]: dc=bigcorp,dc=com
Options for populating the database:

    1)  Only create the base entry
    2)  Leave the database empty
    3)  Import data from an LDIF file
    4)  Load automatically-generated sample data

Enter choice [1]: 

Do you want to enable SSL? (yes / no) [no]: yes
On which port would you like the Directory Server to accept connections from
LDAPS clients? [1636]: 1636

Do you want to enable Start TLS? (yes / no) [no]: yes
Certificate server options:

    1)  Generate self-signed certificate (recommended for testing purposes
        only)
    2)  Use an existing certificate located on a Java Key Store (JKS)
    3)  Use an existing certificate located on a JCEKS key store
    4)  Use an existing certificate located on a PKCS#12 key store
    5)  Use an existing certificate on a PKCS#11 token

Enter choice [1]: 
Provide the fully-qualified host name or IP address that will be used to
generate the self-signed certificate [ldap1.example.com]: 

Do you want to start the server when the configuration is completed? (yes /
no) [yes]: 


Setup Summary
=============
LDAP Listener Port:            1389
Administration Connector Port: 5444
LDAP Secure Access:            Enable StartTLS
                               Enable SSL on LDAP Port 1636
                               Create a new Self-Signed Certificate
Root User DN:                  cn=Directory Manager
Directory Data:                Create New Base DN dc=bigcorp,dc=com.
Base DN Data: Only Create Base Entry (dc=bigcorp,dc=com)

Start Server when the configuration is completed


What would you like to do?

    1)  Set up the server with the parameters above
    2)  Provide the setup parameters again
    3)  Print equivalent non-interactive command-line
    4)  Cancel and exit

Enter choice [1]: 

No protocol specified
See /tmp/opends-setup-7070027805426919888.log for a detailed log of this operation.

Configuring Directory Server ..... Done.
Configuring Certificates ..... Done.
Creating Base Entry dc=bigcorp,dc=com ..... Done.
Starting Directory Server ...... Done.

To see basic server configuration status and configuration you can launch /opt/opendj/ds-user1/bin/status
[root@philx ds-user1]# 

Configuration

Check the [[OpenDJ Cheat Sheet]] for more details on performing the procedures described here.

NOTE: The following assumes the target directory is owned by root and listening on port 389, requiring that many commands be run sudo root. If directory is listening on a port higher than 1000 and the owner is the opendj system user you may dispense with using sudo.

Create and deploy init script

su -
. /home/opendj/ds-user1.env
cd $DSHOME/bin
./create-rc-script 
-j /usr/lib/jvm/java 
-u opendj
-f /etc/init.d/ds-user1

Deploy Initial Configuration

1. Load opendj-initial-config.ldif using ldapmodify.

ldapmodify -h localhost -p 1389 -D "cn=directory manager" 
-w [password] -c -f opendj-initial-config.ldif

2. Rebuild indexes.

sudo $DSHOME/bin/rebuild-index 
-p 5444 -X 
-j /home/opendj/etc/pwd.txt 
-b dc=bigcorp,dc=com 
--rebuildAll 
-t 0

Add Custom Schema

Add any 99-user.ldif custom schema to directory.

1. Shut down server.

sudo $DSHOME/bin/stop-ds

2. Copy 99-user.ldif to $DSHOME/config/schema.

3. Start server.

sudo $DSHOME/bin/start-ds

Modify default access controls

Load new-access-control-handler.ldif using ldapmodify.

ldapmodify -h localhost -p 1389 -D "cn=directory manager" 
-w [password] -c -f new-access-control-handler.ldif

Add skeleton data

Add entries in tree.ldif using ldapmodify.

ldapmodify -a -h localhost -D "cn=directory manager" 
-w [password] -c -f tree.ldif

Create and modify indexes

1. Run user1-setindexes.sh to create indexes for custom attributes and modify existing indexes.

NOTE: The user1-setindexes.sh file uses sudo root to execute the dsconfig command. If your directory is running on a port above 1000 and not owned by root you should search and delete the “sudo ” command from those lines where it exists in this file.

sh user1-setindexes.sh

2. Wait five minutes after script exists and then Rebuild indexes.

sudo $DSHOME/bin/rebuild-index 
-p 5444 -X 
-j /home/opendj/etc/pwd.txt 
-b dc=bigcorp,dc=com 
--rebuildAll 
-t 0

3. Check index status (all indexes should show “true” in the “Index Valid” column):

sudo $DSHOME/bin/dbtest list-index-status 
-n userRoot -b dc=bigcorp,dc=com

Java Version and Options

To reconfigure the Java version used by OpenDJ, open up $DSHOME/config/java.properies and modify the path set in “default.java-home=”. For example:

default.java-home=/usr/lib/jvm/java

which will set it to whatever the default configured with alternatives is.

Be sure to modify any .env and init scripts to use the same path.

Set the java options in the java.properties file to something reasonable, for example:

start-ds.java-args=-server -Xms256m -Xmx2048m -XX:+UseG1GC -Dcom.sun.management.jmxremote

Then run the dsjavaproperties utility (found under $DSOME/bin) that will reconfigure the server to use whatever parameters you specify in the $DSHOME/config/java.properties.

Importing data from an existing OpenDJ directory

NOTE: This step is not required if the target will be the second node of a multi-master pair. That second node will be populated with data later as part of the initialization process.

Use off line or on line method. To do off line stop directory before performing operations and start up after completed. Examples use off line method as it is the fastest.

1. Export data from existing directory on existing host using export-ldif.

$DSHOME/bin/stop-ds

$DSHOME/bin/export-ldif
-b dc=bigcorp,dc=com 
-n userRoot 
-l /data/backup/ldap/big.ldif

sudo $DSHOME/bin/start-ds

2. Copy LDIF file from existing host to new host.

cd /data/backup/big.ldif
scp big.ldif host2:/data/backup/ldap/

3. Use import-ldif to load data into new directory on new host.

sudo $DSHOME/bin/stop-ds

sudo $DSHOME/bin/import-ldif
-b dc=bigcorp,dc=com 
-n userRoot 
-l /data/backup/ldap/big.ldif

sudo $DSHOME/bin/start-ds

Creating data from an existing directory or scratch

NOTE: This step is not required if the target will be the second node of a multi-master pair.

Prerequisites

Before creating new user or other entries in a new directory the following should already be in place:

1. Access control instructions.

2. Privilege assignment entries.

See the following articles for detailed information on the above:

OpenDJ Cheat Sheet, Setting up access control instructions

OpenDJ_Privileges, Creating privilege assignment entries

It is highly recommended that a separate file be created for the new acis and privileges assignment entries.

Creating LDIF data from an existing directory

LDIF data can be created from entries on an existing non-OpenDJ directory using the ldapsearch utility.

ldapsearch -h [sourcedirectoryhost] -D "cn=directory manager" 
-w [sourcedirectorypass] -b "[basedn]" -s sub "(objectclass=*)" 
>big.ldif

Use a “>>” to append data to an existing LDIF file if building a file from multiple basedn’s. For example:

ldapsearch -h [sourcedirectoryhost] -D "cn=directory manager" 
-w [sourcedirectorypass] -b "dc=bigcorp,dc=com" -s one "(objectclass=*)" 
>big.ldif

ldapsearch -h [sourcedirectoryhost] -D "cn=directory manager" 
-w [sourcedirectorypass] -b "ou=americas,ou=people,dc=bigcorp, 
dc=com" -s one "(objectclass=*)" >>big.ldif

Use the scope (“-s”) definition to tell ldapsearch whether to search one or more levels down. To go one level use “one”, for more than one use “sub”.

Creating LDIF data from scratch

If creating LDIF data completely from scratch pay close attention to these points:

1. LDAP directories are hierarchical in nature and are best organized like an inverted tree. A typical LDAP directory tree would look like this:

dn: dc=bigcorp,dc=com
objectclass: top
objectclass: domain
dc: bigcorp

dn: ou=people,dc=bigcorp,dc=com
objectclass: top
objectclass: organizationalunit
ou: people

dn: ou=groups,dc=bigcorp,dc=com
objectclass: top
objectclass: organizationalunit
ou: groups

dn: ou=special users,dc=bigcorp,dc=com
objectclass: top
objectclass: organizationalunit
ou: special users

2. Every LDAP entry in an LDIF needs a dn (distinguished name) and the objectclasses appropriate to the type of object it is.

Enable Multi-master replication

If target will be part of a multi-master pair, follow these instructions for enabling replication on both nodes and initializing the second node in the pair.

To enable replication, execute the following commands on the first node host:

. /home/opendj/ds-user1.env
$DSHOME/bin/dsreplication enable 
--adminUID admin 
--adminPassword [admin password] 
--baseDN "dc=bigcorp,dc=com" 
--host1 [first node fqdn - e.g. usmlrs1115.arrow.com] 
--port1 5444 
--bindDN1 "cn=directory manager" 
--bindPassword1 [directory manager pass] 
--replicationPort1 8989 
--host2 [second node fdqn] 
--port2 5444 
--bindDN2 "cn=directory manager" 
--bindPassword2 [directory manager pass] 
--replicationPort2 8989 
--trustAll 
--no-prompt
. /home/opendj/ds-user1.env
$DSHOME/bin/dsreplication initialize-all 
--adminUID admin 
--adminPassword [admin password] 
--baseDN "dc=bigcorp,dc=com" 
--hostname [first node fdqn] 
--port 5444 
--trustAll 
--no-prompt

Perform Final Configuration

Load opendj-final-config.ldif using ldapmodify. This must be done on all nodes.

ldapmodify -h localhost -p 1389 -D "cn=directory manager" 
-w [password] -c -f opendj-final-config.ldif

Restart directory server:

sudo $DSHOME/bin/stop-ds
sudo $DSHOME/bin/start-ds

Install Backup Script

1. Create /data/backup/ldap directory for backups. Make opendj user and group owner.

mkdir -p /data/backup/ldap
chown opendj:opendj /data/backup/ldap

2. Install a standard OpenDJ Backup Script, opendjbak.sh to /usr/local/bin. Make sure is executable.

3. Schedule script to run every night in cron.

0 1 * * * /usr/local/bin/opendjbak.sh > /dev/null 2>&1