Centralized authentication with OpenLDAP

Setting up a Certificate Authority

On a separate server, preferably isolated from the network and physically secured, create the Certificate Authority that will generate all the certificates for TLS encryption:

[root@host]# yum install openssl openssl-devel

[root@host]# vi /etc/pki/tls/openssl.cnf

[root@host]# cd /etc/pki/tls/misc

[root@host]# ./CA -newca

note: The common name field must be the machine's hostname!

This process does the following:

1. Creates the directory /etc/pki/CA (by default), which contains files necessary for the operation of a certificate authority

2. Creates a public-private key pair for the CA in the file /etc/pki/CA/private/cakey.pem. The private key must be kept private in order to ensure the security of the certificates the CA will later sign.

3. Signs the public key (using the corresponding private key, in a process called self-signing) to create the CA certificate, which is then stored in /etc/pki/CA/cacert.pem.

Creating a certificate for the LDAP server

Change into the CA certificate directory.

[root@host]# cd /etc/pki/tls/certs

Generate a key pair for the LDAP server, ldapserverkey.pem is the private key.

[root@host]# openssl genrsa -out ldapserverkey.pem 2048 

Generate a certificate signing request (CSR) for the CA to sign.

[root@host]# openssl req -new -key ldapserverkey.pem -out ldapserver.csr

Sign the ldapserver.csr request, which will produce the server certificate. It will ask for a password, it's the same as when the CA cerificate was created

[root@host]# openssl ca -in ldapserver.csr -out ldapservercert.pem

How TLS Communication Works

There is a sequence of events that occur prior to the creation of an LDAP communication session using TLS. These include the following steps:

1. Both the LDAP server and client need to be configured with a shared copy of a CA certificate beforehand.

2. When the TLS LDAP connection is made, the client and server negotiate their SSL encryption scheme.

3. The LDAP server then sends its public encryption key and its server certificate (the certificate contains the public key).

4. The LDAP client inspects the server certificate to make sure that it hasn't expired and takes note of the name and key ID of the CA server that issued it. It then checks this CA information with all the CA certificates in its database to determine whether the server certificate should be trusted.

5. If everything is valid, the LDAP client then creates a random "premaster" secret encryption key that it encrypts with the LDAP server's public key. It then sends the encrypted encryption key to the LDAP server.

6. When public keys are created, a special "private" key is also simultaneously created. Anything encrypted with the public key can only be decrypted with the private key and vice versa. The server then uses its private key to extract the premaster key.

7. The client and server then use the premaster key to generate a master secret that will be the same for both, but will never be transmitted so that a third-party cannot intercept it.

8. The master secret key is then used to create session keys that will be used to encrypt all future communication between client and server for the duration of the TLS session.

Installing the Certificate on the LDAP Server

Create the PKI directory for LDAP certificates if it does not already exist

[root@host]# mkdir /etc/pki/tls/ldap

[root@host]# chown root:root /etc/pki/tls/ldap

[root@host]# chmod 755 /etc/pki/tls/ldap

Copy the private key and the certificate from the CA server

[root@host]# scp -r caserver:/etc/pki/tls/certs/ldapserverkey.pem /etc/pki/tls/ldap/serverkey.pem 

[root@host]# scp -r caserver:/etc/pki/tls/certs/ldapservercert.pem /etc/pki/tls/ldap/servercert.pem

Verify the ownership and permissions of these files

[root@host]# chown root:ldap /etc/pki/tls/ldap/serverkey.pem

[root@host]# chown root:ldap /etc/pki/tls/ldap/servercert.pem

[root@host]# chmod 640 /etc/pki/tls/ldap/serverkey.pem

[root@host]# chmod 640 /etc/pki/tls/ldap/servercert.pem

Copy the CA's public certificate from the CA server residing in /etc/pki/CA/cacert.pem to the LDAP server

[root@host]# mkdir /etc/pki/tls/CA 

[root@host]# scp -r caserver:/etc/pki/CA/cacert.pem /etc/pki/tls/CA/

[root@host]# chown root:root /etc/pki/tls/CA/cacert.pem

[root@host]# chmod 644 /etc/pki/tls/CA/cacert.pem

To test the TLS connectivity run

[root@host]# openssl s_client -connect cybervirt1:636 -showcerts

Installing CA's public certificate from the CA server residing in /etc/pki/CA/cacert.pem to the LDAP clients

On all clients run

[root@host]# scp -r caserver:/etc/pki/CA/cacert.pem /etc/pki/tls/CA/

Installing OpenLDAP

You can either download OpenLDAP source and compile it after you install BerkeleyDB

[root@host]# cd /usr/src

[root@host]# wget http://freshmeat.net/urls/1835e002467534891ad4a4c6158963c7

[root@host]# cd /usr/src/db-4.7.25/build_unix

[root@host]# ../dist/configure

[root@host]# make; make install

[root@host]# cd /usr/src

[root@host]#  wget ftp://ftp.openldap.org/pub/OpenLDAP/openldap-stable/openldap-stable-20080813.tgz

[root@host]# tar zxfv openldap-stable-20080813.tgz

[root@host]# cd openldap-2.4.11

[root@host]# CPPFLAGS="-I/usr/local/BerkeleyDB.4.7/include"

[root@host]# export CPPFLAGS

[root@host]# LDFLAGS="-L/usr/local/lib -L/usr/local/BerkeleyDB.4.7/lib -R/usr/local/BerkeleyDB.4.7/lib"

[root@host]# export LDFLAGS

[root@host]# LD_LIBRARY_PATH="/usr/local/BerkeleyDB.4.7/lib"

[root@host]# export LD_LIBRARY_PATH

[root@host]# ./configure;make;make intstall

Or you can install it with yum

[root@host]# yum install -y openldap openldap-devel openldap-servers openldap-clients

Starting OpenLDAP server

For different versions of ldap (from source or rpm) make sure /usr/local/etc/openldap/ldap.conf is the same as /etc/openldap/ldap.conf or there will be CA error.

[root@host]# /usr/local/libexec/slapd -f /usr/local/etc/openldap/slapd.conf -d255 -h 'ldap:/// ldaps:///'

Migrating all user accounts in to OpenLDAP

Install the perl migration tool and migrate all files (passwd, groups, network, etc) by change the domain in the file bellow to yourdomain.com

[root@host]# wget http://www.padl.com/download/MigrationTools.tgz

[root@host]# tar zxfv MigrationTools.tgz

[root@host]# vi /usr/share/openldap/migration/migrate_common.ph

[root@host]# /usr/share/openldap/migration/migrate_all_offline.sh

Changing the authentication method

Two files need to be changed for an ssh client to authenticate to OpenLDAP - /etc/pam.d/system-auth-ac and /etc/nsswitch. You can do that manually or by running authconfig

[root@host]# authconfig --disableldap --enableldapauth --ldapserver=ldap.planetdiscover.com --ldapbasedn="dc=planetdiscover,dc=com" --disableldaptls --update

[root@host]# vi /etc/pam.d/system-auth-ac

auth        required      pam_env.so

auth        sufficient    pam_unix.so nullok try_first_pass

auth        requisite     pam_succeed_if.so uid >= 500 quiet

auth        sufficient pam_ldap.so use_first_pass

auth        required      pam_deny.so

account     required      pam_unix.so broken_shadow

account     sufficient    pam_succeed_if.so uid < 500 quiet  account     [default=bad success=ok user_unknown=ignore] pam_ldap.so  account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3

password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok

password    sufficient pam_ldap.so use_authtok

password    required      pam_deny.so

session     optional      pam_keyinit.so revoke

session     required      pam_limits.so

session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid

session     required      pam_unix.so

session     optional      pam_ldap.so

session     optional      /lib/security/$ISA/pam_ldap.so

[root@host]# vi /etc/nsswitch

passwd:     files ldap

shadow:     files ldap

group:      files ldap

automount:  files ldap

Configuring OpenLDAP server and clients

Here's how /etc/openldap/slapd.conf and /usr/local/etc/openldap/slapd.conf server config files should look like

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

pidfile         /usr/local/var/run/slapd.pid

argsfile        /usr/local/var/run/slapd.args

access to attr=userPassword

by anonymous auth

by self write

by * none

access to attrs=shadowLastChange

by self write

by * read

access to * by * read

database        bdb

suffix          "dc=planetdiscover,dc=com"

rootdn          "cn=Manager,dc=planetdiscover,dc=com"

rootpw          {MD5}Tw4es8U1dRL2oLhM58ZBhA==

directory       /usr/local/var/openldap-data

index   objectClass     eq

TLSCACertificateFile /etc/pki/tls/CA/cacert.pem

TLSCertificateFile /etc/pki/tls/ldap/servercert.pem

TLSCertificateKeyFile /etc/pki/tls/ldap/serverkey.pem

security simple_bind=128

loglevel stats2

The client config file in /etc/ldap.conf

base dc=planetdiscover,dc=com

uri ldap://cybervirt1.planetdiscover.com/

timelimit 120

bind_timelimit 120

idle_timelimit 3600

nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd,news,mailman

pam_password md5

ssl start_tls

tls_checkpeer yes

tls_cacertdir /etc/pki/tls/CA

tls_cacertfile /etc/pki/tls/CA/cacert.pem

The /etc/openldap/ldap.conf and /usr/local/etc/openldap/ldap.conf client config files

BASE    dc=planetdiscover, dc=com

URI     ldap://cybervirt1.planetdiscover.com

TLS_CACERTDIR /etc/pki/tls/CA

TLS_CACERT /etc/pki/tls/CA/cacert.pem

Various OpenLDAP operations and examples

### Define the top-level organization unit ###

## Build the root node.

dn: dc=planetdiscover,dc=com

dc: planetdiscover

objectClass: dcObject

objectClass: organizationalUnit

ou: planetdiscover Dot Org

## Build the people ou container.

dn: ou=people,dc=planetdiscover,dc=com

ou: people

objectClass: organizationalUnit

## Build the group ou container.

dn: ou=group,dc=planetdiscover,dc=com

ou: group

objectclass: organizationalUnit

## Add the records offline

[root@host]# slapadd -v -l /tmp/top.ldif

## Add a user LDIF entry for Jerry Carter. cn is the mandatory attribute for this objectclass

dn: cn=Jerry Carter,ou=people,dc=planetdiscover,dc=com

cn: Jerry Carter

sn: Carter

mail: carter@nowhere.net

telephoneNumber: 555-123-1234

objectclass: inetOrgPerson

## Add a user LDIF entry for root. uid is the mandatory attribute in this case

dn: uid=root,ou=People,dc=planetdiscover,dc=com

uid: root

cn: root

objectClass: account

objectClass: posixAccount

objectClass: top

objectClass: shadowAccount

userPassword: {crypt}$1$Kp8hx.m0$Y1Aw37IStTqU8UU5kLgbq.

shadowLastChange: 13692

shadowMax: 99999

shadowWarning: 7

loginShell: /bin/bash

uidNumber: 0

gidNumber: 0

homeDirectory: /root

gecos: root

[root@host]# ldapmodify -D "cn=Manager,dc=planetdiscover,dc=com" -w secret -x -a -f /tmp/users.ldif

## Modify. Add a web page location to Jerry Carter.

dn: cn=Jerry Carter,ou=people,dc=planetdiscover,dc=com

changetype: modify

add: labeledURI

labeledURI: http://www.planetdiscover.org/~jerry/

## Modify. Remove an email address from Gerald W. Carter.

dn: cn=Gerald W. Carter,ou=people,dc=planetdiscover,dc=com

changetype: modify

delete: mail

mail: gcarter@valinux.com

## Modify. Remove the entire entry for Peabody Soup.

dn: cn=Peabody Soup,ou=people,dc=planetdiscover,dc=com

changetype: delete

[root@host]# ldapmodify -D "cn=Manager,dc=planetdiscover,dc=com" -w secret -x -v -f /tmp/update.ldif

## Delete dn root.

[root@host]# ldapdelete -D "cn=Manager,dc=planetdiscover,dc=com" -w secret -x -r -v "uid=root,ou=People,dc=planetdiscover,dc=com"

## Delete the entire dn ou=people subtree.

[root@host]# ldapdelete -D "cn=Manager,dc=planetdiscover,dc=com" -w secret -x -r -v "ou=people,dc=planetdiscover,dc=com"

## Search for uid cybergod record

[root@host]# ldapsearch -x -b "dc=planetdiscover,dc=com" "(uid=cybergod)"

# -b can be omited it's from where to start the search

[root@host]# ldapsearch -x  -W -D cn="Manager,dc=planetdiscover,dc=com"  "(uid=cybergod)" -Z 

# -Z is for Using TLS it goes with -W for the Manager password

## Search for all objectclass records

[root@host]# ldapsearch -x -b "dc=planetdiscover,dc=com" "(objectclass=*)"

## Search using SASL DIGEST-MD5

[root@host]# ldapsearch -U admin@ldap.planetdiscover.com -b "dc=planetdiscover,dc=com" "(objectclass=*)" -Y DIGEST-MD5

## Changing users password to "test" online through TLS

[root@host]# ldappasswd -s test -x -W -D cn="Manager,dc=planetdiscover,dc=com" "uid=cybergod,ou=People,dc=planetdiscover,dc=com" -Z

## Show ldap information

[root@host]# ldapsearch -x -s base -b "" "(objectclass=*)" + 

[root@host]# ldapsearch -h localhost -p 389 -x -b "" -s base -LLL supportedSASLMechanisms

## Generate ssha password to use in slapd.conf

[root@host]# slappasswd