May 032012
 

This post will cover post-installation steps necessary to go from a completely unmanaged machine to a machine that is setup to be an LDAP server with a basic DIT. This will also setup phpldapadmin for web-based administration of your LDAP directory.

Note: I use nginx here simply because I find it easier to deal with. There’s no requirement for it and you may find it easier to use apache.

The post-install script used to setup the LDAP server is below. The reason this is used is because there are a lot of one time things that happen during the installation of an LDAP server and I have not yet been able to represent some of these events in bcfg2. The script below depends on some files that are hosted on another web server. I will provide the necessary files needed below.

The custom php packages are available from http://blog.famillecollet.com/pages/Config-en. The reason for using these packages is that php-fpm is not available from the stock RHEL repositories or from EPEL. Since I am already familiar with php-fpm and I prefer to use it, I decided to simply download only the necessary packages rather than use the entire repository.

#!/bin/bash

# ssl settings
WEBCERT="/etc/pki/tls/certs/phpldapadmin.crt"
WEBKEY="/etc/pki/tls/private/phpldapadmin.key"
SLAPDCERT="/etc/openldap/cacerts/slapd.crt"
SLAPDMASTERCERT="/etc/openldap/cacerts/slapd-master.crt"
SLAPDKEY="/etc/pki/tls/private/slapd.key"
SSLSUBJ="/C=Country Code/ST=Some State/L=City/O=Organization Name/OU=Organizational Unit Name/CN=${HOSTNAME}"

# misc settings
LDAPDIR="/root/ldap-setup"
HTTPDIR="http://web.server/ldap"
LDIFDIR="${HTTPDIR}/ldif"
RPMS="${HTTPDIR}/rpms/php-5.3.8-5.el6.remi.x86_64.rpm
${HTTPDIR}/rpms/php-cli-5.3.8-5.el6.remi.x86_64.rpm
${HTTPDIR}/rpms/php-common-5.3.8-5.el6.remi.x86_64.rpm
${HTTPDIR}/rpms/php-fpm-5.3.8-5.el6.remi.x86_64.rpm
${HTTPDIR}/rpms/php-ldap-5.3.8-5.el6.remi.x86_64.rpm
openldap-clients
openldap-servers
autofs"

PASSWD="changeme"
SLAPPASSWD=""
BCFG2PASSWD=""

selinux-disable()
{
    #FIXME: remove when bcfg2 selinux policy works properly
    setenforce 0
}

selinux-enable()
{
    #FIXME: remove when bcfg2 selinux policy works properly
    setenforce 1
}

inst-packages()
{
    echo -n "Installing custom php packages for phpldapadmin..."
    yum -y --nogpgcheck install ${RPMS} >/dev/null
    # FIXME: update the kernel (kernel panics when not done here)
    yum -y update kernel >/dev/null
    echo "done"
}

gen-ssl-certs()
{
    /usr/bin/openssl req -batch -new -x509 -nodes \
        -subj "${SSLSUBJ}" \
        -out ${WEBCERT} \
        -keyout ${WEBKEY} -days 3600 >/dev/null
    /usr/bin/openssl req -batch -new -x509 -nodes \
        -subj "${SSLSUBJ}" \
        -out ${SLAPDCERT} \
        -keyout ${SLAPDKEY} -days 3600 >/dev/null

    cacertdir_rehash /etc/openldap/cacerts
}

get-passwds()
{
    # setup ldap admin password
    echo -n "Please enter a new ldap admin password: "
    read -s PASSWD
    # get bcfg2 password
    echo -n "Please enter the bcfg2 password (can be found in /etc/bcfg2.conf on an existing client): "
    read -s BCFG2PASSWD
    echo
}

gen-slappasswd()
{
    if [ -x /usr/sbin/slappasswd ]
    then
        SLAPPASSWD=$(/usr/sbin/slappasswd -s ${PASSWD})
    else
        echo "Failed to find slappasswd. Aborting."
        exit 1
    fi
}

setup-ldap()
{
    /usr/bin/curl -o ${LDAPDIR}/fix-admin-account.ldif ${LDIFDIR}/fix-admin-account.ldif
    /usr/bin/curl -o ${LDAPDIR}/new-ldap-setup.ldif ${LDIFDIR}/new-ldap-setup.ldif
    /usr/bin/curl -o ${LDAPDIR}/base.ldif ${LDIFDIR}/base.ldif
    sed -i "s|PWREPLACE|${SLAPPASSWD}|" ${LDAPDIR}/fix-admin-account.ldif ${LDAPDIR}/new-ldap-setup.ldif
    # this seems wrong. if someone knows how to do this better, please inform me.
    echo "olcRootPW: ${SLAPPASSWD}" >> /etc/openldap/slapd.d/cn=config/olcDatabase={0}config.ldif
    /bin/cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
    chown -R ldap. /var/lib/ldap
    /sbin/service slapd start && sleep 1 # FIXME: how do you do this properly?
    ldapadd -w ${PASSWD} -x -D "cn=config" -f ${LDAPDIR}/fix-admin-account.ldif
    ldapadd -w ${PASSWD} -x -D "cn=admin,cn=config" -f ${LDAPDIR}/new-ldap-setup.ldif
    ldapadd -w ${PASSWD} -x -D "cn=Manager,dc=uh,dc=edu" -f ${LDAPDIR}/base.ldif
}

add-sudo()
{
    /usr/bin/curl -o ${LDAPDIR}/sudo-index.ldif ${LDIFDIR}/sudo-index.ldif
    cp /usr/share/doc/$(rpm -q sudo --qf "%{NAME}"-"%{VERSION}")/schema.OpenLDAP /etc/openldap/schema/sudo.schema
    restorecon -F -R -v /etc/openldap/schema
    mkdir ${LDAPDIR}/sudo-ldap
    echo "include /etc/openldap/schema/sudo.schema" > ${LDAPDIR}/sudo-ldap/sudoschema.conf
    slapcat -f ${LDAPDIR}/sudo-ldap/sudoschema.conf -F /tmp \
            -n0 -s "cn={0}sudo,cn=schema,cn=config" > ${LDAPDIR}/sudo-ldap/sudo-tmp.ldif
    sed -i 's/{0}sudo/sudo/' ${LDAPDIR}/sudo-ldap/sudo-tmp.ldif
    head -n-8 ${LDAPDIR}/sudo-ldap/sudo-tmp.ldif > ${LDAPDIR}/sudo-ldap/sudo.ldif
    echo -e "\n$(cat ${LDAPDIR}/sudo-index.ldif)" >> ${LDAPDIR}/sudo-ldap/sudo.ldif # add in our sudo index
    rm ${LDAPDIR}/sudo-index.ldif
    ldapadd -w ${PASSWD} -x -D "cn=admin,cn=config" -f ${LDAPDIR}/sudo-ldap/sudo.ldif
}

add-autofs()
{
    cp /usr/share/doc/$(rpm -q autofs --qf "%{NAME}"-"%{VERSION}")/autofs.schema /etc/openldap/schema/autofs.schema
    restorecon -F -R -v /etc/openldap/schema
    mkdir ${LDAPDIR}/autofs
    echo "include /etc/openldap/schema/core.schema" > ${LDAPDIR/autofs/autofs.conf
    echo "include /etc/openldap/schema/cosine.schema" >> ${LDAPDIR/autofs/autofs.conf
    echo "include /etc/openldap/schema/autofs.schema" >> ${LDAPDIR/autofs/autofs.conf
    slapcat -f ${LDAPDIR}/autofs/autofs.conf -F /tmp \
            -n0 -s "cn={2}autofs,cn=schema,cn=config" > ${LDAPDIR}/autofs/autofs-tmp.ldif
    sed -i 's/{2}autofs/autofs/' ${LDAPDIR}/autofs/autofs-tmp.ldif
    head -n-8 ${LDAPDIR}/autofs/autofs-tmp.ldif > ${LDAPDIR}/autofs/autofs.ldif
    ldapadd -w ${PASSWD} -x -D "cn=admin,cn=config" -f ${LDAPDIR}/autofs/autofs.ldif
}

import-db()
{
    while true; do
        echo -n "Is this machine a master or a slave? [m/s] "
        read status
        case $status in
            m*|M*)
                /usr/bin/curl -o ${LDAPDIR}/olcaccess.ldif ${LDIFDIR}/olcaccess.ldif
                /usr/bin/curl -o ${LDAPDIR}/syncprov-module.ldif ${LDIFDIR}/syncprov-module.ldif
                /usr/bin/curl -o ${LDAPDIR}/syncprov.ldif ${LDIFDIR}/syncprov.ldif
                ldapmodify -w ${PASSWD} -D "cn=admin,cn=config" -f ${LDAPDIR}/olcaccess.ldif
                ldapmodify -w ${PASSWD} -D "cn=admin,cn=config" -f ${LDAPDIR}/syncprov-module.ldif
                ldapadd -w ${PASSWD} -D "cn=admin,cn=config" -f ${LDAPDIR}/syncprov.ldif
                break
            ;;
            s*|S*)
                # grab master SSL certificate
                /usr/bin/curl -o ${SLAPDMASTERCERT} ${HTTPDIR}/slapd-master.crt
                cacertdir_rehash /etc/openldap/cacerts

                /usr/bin/curl -o ${LDAPDIR}/olcaccess-slave.ldif ${LDIFDIR}/olcaccess-slave.ldif
                /usr/bin/curl -o ${LDAPDIR}/syncrepl.ldif ${LDIFDIR}/syncrepl.ldif
                ldapmodify -w ${PASSWD} -D "cn=admin,cn=config" -f ${LDAPDIR}/olcaccess-slave.ldif
                ldapmodify -w ${PASSWD} -D "cn=admin,cn=config" -f ${LDAPDIR}/syncrepl.ldif
                break
            ;;
            *)
                echo "Invalid response."
            ;;
        esac
    done
}

run-bcfg2()
{
    /usr/sbin/bcfg2 -vqe -S https://bcfg2.server:6789 -x ${BCFG2PASSWD} --ca-cert=/etc/bcfg2.ca -r packages
    /usr/sbin/bcfg2 -vqer packages
}

selinux-disable
mkdir -p ${LDAPDIR}
get-passwds
inst-packages
gen-ssl-certs
gen-slappasswd
setup-ldap
add-sudo
import-db
run-bcfg2
selinux-enable
echo "Setup complete. Please reboot."

Here are the accompanying ldif files needed.

fix-admin-account.ldif

# Set password for cn=admin,cn=config
dn: olcDatabase={0}config,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: PWREPLACE
-
replace: olcRootDN
olcRootDN: cn=admin,cn=config

ldif/new-ldap-setup.ldif

# create modules area
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib64/openldap

# set access for the monitor db.
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="cn=Manager,dc=yourcompany,dc=com" read by * none

# change LDAP domain, password and access rights.
dn: olcDatabase={2}bdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=yourcompany,dc=com
-
replace: olcRootDN
olcRootDN: cn=Manager,dc=yourcompany,dc=com
-
replace: olcRootPW
olcRootPW: PWREPLACE

# setup SSL
dn: cn=config
changetype:modify
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/pki/tls/private/slapd.key
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/cacerts/slapd.crt
-
replace: olcTLSCipherSuite
olcTLSCipherSuite: HIGH:MEDIUM:-SSLv2

base.ldif

# setup basic tree
dn: dc=yourcompany,dc=com
dc: uh
objectClass: top
objectClass: domain

dn: ou=People,dc=yourcompany,dc=com
ou: People
objectClass: top
objectClass: organizationalUnit

dn: ou=Group,dc=yourcompany,dc=com
ou: Group
objectClass: top
objectClass: organizationalUnit

dn: cn=replicator,dc=yourcompany,dc=com
cn: replicator
objectClass: organizationalRole
objectClass: simpleSecurityObject
objectClass: top
description: LDAP replication user
userPassword: changeme

ldif/sudo-index.ldif

# add sudo index
dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: sudoUser eq

These can be changed to match your needs. In this case, anyone in the group cn=ldapadmin,ou=yourorganizationalunit,dc=yourcompany,dc=com is given full access to the LDAP directory (UPDATE: Please note that the ldapadmin cn is a groupOfNames objectClass [_not_ a posixGroup]).
ldif/olcaccess.ldif

dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to * by dn.base="cn=replicator,dc=yourcompany,dc=com" read by * break
olcAccess: {1}to * by group.exact="cn=ldapadmin,ou=yourorganizationalunit,dc=yourcompany,dc=com" write by * break
olcAccess: {2}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {3}to attrs=shadowLastChange by self write by * read
olcAccess: {4}to * by * read
-

ldif/syncprov-module.ldif

# setup syncprov module
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: {1}syncprov

You will want to modify these settings according to your replication needs.

ldif/syncprov.ldif

dn: olcOverlay={0}syncprov,olcDatabase={2}bdb,cn=config
objectClass: olcSyncProvConfig
olcOverlay: {0}syncprov
olcSpCheckpoint: 100 10
olcSpSessionlog: 100

ldif/olcaccess-slave.ldif

dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to * by group.exact="cn=ldapadmin,ou=yourorganizationalunit,dc=yourcompany,dc=com" write by * break
olcAccess: {1}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {2}to * by * read
-

ldif/syncrepl.ldif

dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcSyncrepl
olcSyncrepl: {0}rid=000 provider=ldaps://ldap-master-server searchbase=dc=yourcompany,dc=com type=refreshAndPersist retry="5 5 300 +" bindmethod=simple binddn="cn=re
plicator,dc=yourcompany,dc=com" credentials="changeme" tls_cacertdir=/etc/openldap/cacerts                                                                              -

Here are the relevant bits from the ldap bundle in the bcfg2 repository

<Bundle name='ldap'>
        <Group name='ldap-server'>
                <BoundPath name='/etc/openldap/cacerts/slapd.crt' type='permissions' owner='ldap' group='ldap' perms='0600'/>
                <BoundPath name='/etc/pki/tls/private/slapd.key' type='permissions' owner='ldap' group='ldap' perms='0600'/>
                <Package name='ldapvi'/>
                <Package name='openldap-clients'/>
                <Package name='openldap-servers'/>
                        <Path name='/etc/sysconfig/ldap'/>
                        <BoundPath name='/etc/openldap/slapd.d' type='directory' owner='ldap' group='ldap' perms='0700'/>

                <Service name='slapd'/>

                <!-- phpLDAPadmin settings -->
                <Package name='php'/>
                        <BoundPath name='/var/lib/php/session' type='directory' owner='root' group='nginx' perms='0770'/>
                <Package name='php-fpm'/>
                        <Path name='/etc/php-fpm.d/www.conf'/>
                <Package name='php-ldap'/>
                <Package name='nginx'/>
                <Package name='phpldapadmin'/>
                <Service name='php-fpm'/>
                <Service name='nginx'/>
                <Path name='/etc/nginx/conf.d/phpldapadmin.conf'/>
                <Path name='/etc/openldap/ldap.conf'/>
                <Path name='/etc/phpldapadmin/config.php'/>
                <BoundPath name='/var/www/html/phpldapadmin' type='symlink' to='/usr/share/phpldapadmin/htdocs'/>
                <Path name='/usr/share/phpldapadmin/templates/creation/custom_uh.xml'/>
        </Group>
</Bundle>

The /etc/sysconfig/ldap file needs to be modified to allow LDAPS by uncommenting SLAPD_LDAPS=yes. In /etc/php-fpm.d/www.conf, you need to make sure the user/group are set to nginx (if you are using nginx as your web server).

My nginx configuration for /etc/nginx/conf.d/phpldapadmin.conf looks like this.

server {
        listen          80;
        server_name     ldap-server-hostname;
        rewrite         ^/(.*) https://ldap-server-hostname/$1 permanent;
}

server {
        listen                  443; # listen also for IPv4 traffic on "regular" IPv4 sockets
        server_name             ldap-server-hostname;
        access_log              /var/log/nginx/ssl-access.log;
        error_log               /var/log/nginx/ssl-error.log;
        root                    /var/www/html/phpldapadmin;

        ssl                     on;
        ssl_certificate         /etc/pki/tls/certs/phpldapadmin.crt;
        ssl_certificate_key     /etc/pki/tls/private/phpldapadmin.key;

        index           index.php index.html;

        location ~ \.php$ {
                fastcgi_pass    localhost:9000;
                fastcgi_index   index.php;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include         fastcgi_params;
                fastcgi_param   HTTPS on;
        }
}

I needed the following lines in /etc/openldap/ldap.conf to get phpldapadmin working properly.

URI             ldaps://localhost/
TLS_CACERTDIR   /etc/openldap/cacerts
TLS_REQCERT     never

Lastly, you will need to modify /etc/phpldapadmin/config.php with appropriate values for your site.

 Posted by at 13:16

  One Response to “Installing OpenLDAP on RHEL6”

  1. […] now the last part is to give this person sudo access. My sudo configuration resides in LDAP. Therefore, I will need to add 2 new sudoOptions in order to allow my user to transition properly […]

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*