Abstract : in some cases, it is interesting to have multiples instances of OpenLDAP running on the same machine. This could be used to separate data, test replication on the same server, or whatever you want.
This note will explain how to do this.
In a standard GNU/Linux OpenLDAP install (Red Hat or Debian based), there are several files or directories used to set up OpenLDAP instance and data :
Whenever you start the instance, using :
/etc/init.d/slapd start
this will retrieve data from default setup (ie : /etc/sysconfig/ldap and /etc/init.d/slapd.d directory).
Then, you can see what is running with ps -ef command :
ps -ef
...
ldap 17233 1 0 18:13 ? 00:00:00 /usr/sbin/slapd -h ldap:/// ldaps:/// ldapi:/// -u ldap
...
This is the default setup. If we look at the file /etc/sysconfig/ldap, we see that it defines several variables :
# Options of slapd (see man slapd)
#SLAPD_OPTIONS=
# At least one of SLAPD_LDAP, SLAPD_LDAPI and SLAPD_LDAPS must be set to 'yes'!
#
# Run slapd with -h "... ldap:/// ..."
# yes/no, default: yes
SLAPD_LDAP=yes
# Run slapd with -h "... ldapi:/// ..."
# yes/no, default: yes
SLAPD_LDAPI=yes
# Run slapd with -h "... ldaps:/// ..."
# yes/no, default: no
SLAPD_LDAPS=yes
# Run slapd with -h "... $SLAPD_URLS ..."
# This option could be used instead of previous three ones, but:
# - it doesn't overwrite settings of $SLAPD_LDAP, $SLAPD_LDAPS and $SLAPD_LDAPI options
# - it isn't overwritten by settings of $SLAPD_LDAP, $SLAPD_LDAPS and $SLAPD_LDAPI options
# example: SLAPD_URLS="ldapi:///var/lib/ldap_root/ldapi ldapi:/// ldaps:///"
# default: empty
SLAPD_URLS=
Then we can use the SLAPD_URLS variable to set ports for ldap, ldaps and so on.
Note : if you use this variable, you must not use the other one (SLAPD_LDAP, SLAPD_LDAPS), because the start script uses the full URL and also separate variables.
For example, with such a configuration file :
#SLAPD_LDAP=yes
#SLAPD_LDAPI=yes
#SLAPD_LDAPS=yes
SLAPD_URLS="ldap://:1389/ ldapi:/// ldaps://:1636/"
If we start the slapd process with /etc/init.d/slapd start, the result is :
ps -ef
ldap 17176 1 0 18:11 ? 00:00:00 /usr/sbin/slapd -h ldap://:1389/ ldapi:/// ldaps://:1636/ -u ldap
We have been able to change the port. This gives a pretty good idea of what needs to be done to run multiple instances.
The man slapd command reveals also some interesting options :
slapd [-4|-6] [-T {acl|a[dd]|auth|c[at]| d[n]|i[ndex]|p[asswd]|s[chema]|t[est]}] [-d debug-level] [-f slapd-
config-file] [-F slapd-config-directory] [-h URLs] [-n service-name] [-s syslog-level] [-l syslog-local-user]
[-o option[=value]] [-r directory] [-u user] [-g group] [-c cookie]
If we want to have mutliple instances on the same server, we must define :
Let's imagine a scenario where we will have 3 separate instances on the same server, which can be used to test replication in a master/master + slave configuration.
We will name those instances master1, master2 and slave1
In this scenario, we use several partitions to dispatch data on the server :
I think that the best option is to make a copy of the initial slapd.d directory.
So, once openldap is installed, we will copy the configuration. We will name each directory with a suffix '.d', just to mimic slapd.d configuration name
yum install openldap openldap-servers openldap-clients
# create the main configuration directory
mkdir /srv/conf/openldap
cp -R /etc/openldap/slapd.d /srv/conf/openldap/master1.d
cp -R /etc/openldap/slapd.d /srv/conf/openldap/master2.d
cp -R /etc/openldap/slapd.d /srv/conf/openldap/slave1.d
Let's check the content of /srv/conf/openldap/master1.d directory :
ls -R /srv/conf/openldap/master1.d
/srv/conf/openldap/master1.d:
cn=config cn=config.ldif
/srv/conf/openldap/master1.d/cn=config:
cn=schema cn=schema.ldif olcDatabase={0}config.ldif olcDatabase={-1}frontend.ldif olcDatabase={1}monitor.ldif olcDatabase={2}bdb.ldif
/srv/conf/openldap/master1.d/cn=config/cn=schema:
cn={0}corba.ldif cn={11}collective.ldif cn={2}cosine.ldif cn={4}dyngroup.ldif cn={6}java.ldif cn={8}nis.ldif
cn={10}ppolicy.ldif cn={1}core.ldif cn={3}duaconf.ldif cn={5}inetorgperson.ldif cn={7}misc.ldif cn={9}openldap.ldif
Note : in fact it will be more interesting to setup the first master configuration, which declares the root suffix, data and so on, and the duplicate this first directory.
Some configuration files include elements of structure. Therefore, these files must be updated to reflect the new setup.
The file LDAP.D/cn=config.ldif contains several references to directories.
These attributes should be changed accordingly (in this example, we update data for master1 instance):
In your database definition file olcDatabase={2}bdb.ldif, change the data directory (olcDbDirectory attribute).
Here again, we will create one sub-directory for each instance.
mkdir -p /srv/data/openldap
mkdir /srv/data/master1
mkdir /srv/data/master2
mkdir /srv/data/slave1
These directories contains the transaction log files, which are used by OpenLDAP.
In recent versions, OpenLDAP "technical" logging is using syslog mechanism.
Then, you must create a startup script for each instance, which will start with the correct parameters.
A very simple script could use the configuration in code :
#!/bin/bash
#
# Startup script for master1
#
SLAPD_URLS="ldap://:2389/ ldapi://var%2Frun%2Fopenldap%2Fldap-master1 ldaps://:2636/"
SLAPD_CONFDIR=/srv/conf/openldap/master1.d
SLAPD_NAME=master1
SLAPD_USER=ldap
SLAPD_GROUP=ldap
#
echo "Starting ${SLAPD_NAME} instance..."
/usr/sbin/slapd -h "${SLAPD_URLS}" -g ${SLAPD_GROUP} -u ${SLAPD_USER} -F ${SLAPD_CONFDIR} -n ${SLAPD_NAME}
Note : the URL for ldapi should be encoded as an URL, with '/' replaced by '%2F', as specified in the "man slapd" command.
In order to keep everything quite simple, we can add a file in the configuration directory, that will "emulate" the default /etc/sysconfig/ldap file.
For example, let's create a file /srv/conf/openldap/master1.d/config.ldap which contains :
SLAPD_URLS="ldap://:2389/ ldapi://var%2Frun%2Fopenldap%2Fldap-master1 ldaps://:2636/"
SLAPD_SHUTDOWN_TIMEOUT=3
SLAPD_NAME=master1
SLAPD_USER=ldap
SLAPD_GROUP=ldap
Then, our start script could be located in /srv/bin/openldap/slapd. It will be run with these options :
/srv/bin/openldap/slapd [start|stop|status] <INSTANCE_NAME>
For example, to start the instance master1, we should run :
/srv/bin/openldap/slapd start master1
Our startup script should then test if the configuration file exists, and then source this file to define the parameters.
Then, this will run the command :
CONF_BASE=/srv/conf/openldap
source ${CONF_BASE}/${INSTANCE}.d/config.ldap
pidfile=/var/run/slapd.${INSTANCE}
/usr/sbin/slapd -h "${SLAPD_URLS}" -g ${SLAPD_GROUP} -u ${SLAPD_USER} -F ${CONF_BASE}/${INSTANCE}.d -n ${INSTANCE
Our complete startup script would be this one :
#!/bin/bash
#
# ---------------------------------------------------------------------
SLAPD=/usr/sbin/slapd
CONF_BASE=/srv/conf/openldap
if [ -z "$2" ] ; then
echo -n "LDAP Instance : "
read INSTANCE
else
INSTANCE=$2
fi
if [ -f ${CONF_BASE}/${INSTANCE}.d/config.ldap ] ; then
source ${CONF_BASE}/${INSTANCE}.d/config.ldap
else
echo "Configuration file ${CONF_BASE}/${INSTANCE}.d/config.ldap not found"
echo "Exiting..."
exit 1
fi
pidfile=/var/run/slapd.${INSTANCE}
start_ldap() {
echo "Starting LDAP Instance ${INSTANCE}"
${SLAPD} -h "${SLAPD_URLS}" -g ${SLAPD_GROUP} -u ${SLAPD_USER} -F ${CONF_BASE}/${INSTANCE}.d -n ${INSTANCE}
}
# Stop slapd daemon
stop_ldap() {
echo "Stop LDAP instance ${INSTANCE}"
SLAPPID=$(ps -fe|grep ${INSTANCE}.d|grep -v grep|awk '{print $2}' )
kill $SLAPPID
}
case "$1" in
start)
start_ldap ;;
stop)
stop_ldap ;;
restart|force-reload)
stop_ldap
start_ldap
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload}"
exit 1
;;
esac