Openldap and Multi-Master Replication in FreeBSD – Part V: TLS/SSL to secure OpenLDAP Data

openldap logo

Using TLS/SSL to secure OpenLDAP Data:

With the advent of NSA snooping, corporate espionage, and general employee mischief, it’s time to start utilizing encryption to snoop-proof data streams emanating from corporate networks.  LDAP is but one of many protocols in which encryption is necessary – see flowchart below.  This article will focus on using TLS/SSL on the interconnected streams of data originating from and to an OpenLDAP Server and its dependent services.  It will not contain much in the area of OpenLDAP ACL’s as a means to segregate different users and data with differing levels of encryption, nor will it focus on SASL and Kerberos as a means to secure data.  Again, these topics will present themselves in a future related article.

 

ssl-layers image from www.zytrax.com
www.zytrax.com

 

Goals:

  • Generate Certificate Authority Key, Certificate Signing Request and Client Certificate
  • Configure the following daemon’s and files for TLS/SSL:
    • slapd.conf including syncrepl
    • ldap.conf
    • nslcd.conf
    • phpLDAPadmin config.php
    • rc.conf
  • Test configuration change

 

At the heart of the matter is a desire to ensure all data links whether they originate from the OpenLDAP Server itself, from clients, processes or from LDAP tools such as browsers and editors are encrypted.  The below figure represents this issue clearly.

 

ldap security overview flowchart
www.zytrx.com

 

Certificates:

For the purposes of securing OpenLDAP data, self-signed certificates are used in lieu of commercially available certificates.

 

Step 1 – Generate Certificate Authority Key:

Before generating certificates, the correct directory location is essential:

# cd /usr/local/etc/openldap
# mkdir sslcerts
# cd /usr/local/etc/openldap/sslcerts
# mkdir ldapcerts
# cd /usr/local/etc/openldap/sslcerts/ldapcerts

 

Note: Prepend ca to your domain as CN – ca.loga.us

# openssl genrsa -out cakey.pem 2048
# chmod 600 cakey.pem
# openssl req -new -x509 -days 3650 -key cakey.pem -out cacert.pem

 

Generate Server 1 Key and CSR:

Note: Use IP or FQDN of the LDAP server as CN – ldap1.loga.us

# openssl genrsa -out ldap1key.pem 2048
# chown ldap:ldap ldap1key.pem
# chmod 600 ldap1key.pem
# openssl req -new -key ldap1key.pem -out ldap1csr.pem
# openssl x509 -req -days 3650 -in ldap1csr.pem -CA cacert.pem -CAkey cakey.pem -set_serial 01 -out ldap1cert.pem

 

Generate Server 2 Key and CSR:

Note: Use IP or FQDN of the LDAP server as CN – ldap2.loga.us

# openssl genrsa -out ldap2key.pem 2048
# chown ldap:ldap ldap2key.pem
# chmod 600 ldap2key.pem
# openssl req -new -key ldap2key.pem -out ldap2csr.pem
# openssl x509 -req -days 3650 -in ldap2csr.pem -CA cacert.pem -CAkey cakey.pem -set_serial 02 -out ldap2cert.pem

 

List of Certificate Files:

Certificate file location /usr/local/etc/sslcerts/ldapcerts:

-rw-r--r--  1 ldap  ldap  1415 Aug 23 05:21 cacert.pem
-rw-------  1 ldap  ldap  1675 Aug 23 05:18 cakey.pem
-rw-r--r--  1 ldap  ldap  1289 Aug 23 05:29 ldap1cert.pem
-rw-r-----  1 ldap  ldap  1054 Aug 23 05:26 ldap1csr.pem
-rw-------  1 ldap  ldap   1679 Aug 23 05:23 ldap1key.pem
-rw-r--r--  1 ldap  ldap  1289 Aug 23 05:33 ldap2cert.pem
-rw-r-----  1 ldap  ldap  1054 Aug 23 05:32 ldap2csr.pem
-rw-------  1 ldap  ldap   1679 Aug 23 05:30 ldap2key.pem

Change the permissions as indicated above.

 

slapd.conf:

 

Settings for Server 1:

Below is the /usr/local/etc/openldap/slapd.conf file for server ldap1.loga.us:

 

#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
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

# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
# referral ldap://root.openldap.org

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

# Load dynamic backend modules:

modulepath /usr/local/libexec/openldap
#moduleload back_bdb
moduleload back_mdb
# moduleload back_hdb
# moduleload back_ldap

# Security - TLS Section
TLSCACertificateFile /usr/local/etc/sslcerts/ldapcerts/cacert.pem
TLSCertificateFile /usr/local/etc/sslcerts/ldapcerts/ldap1cert.pem
TLSCertificateKeyFile /usr/local/etc/sslcerts/ldapcerts/ldap1key.pem
TLSCipherSuite TLSv1+RSA:!NULL
security ssf=128

serverID 001

allow bind_v2

# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64

# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!

#######################################################################
# BDB database definitions
#######################################################################

database mdb 

suffix "dc=loga,dc=us"
rootdn "cn=Manager,dc=loga,dc=us"

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

rootpw {SSHA}A6ia1SPQlY4J5qWBUkPg1qqiwZHrL0mb 
password-hash {SSHA}

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

directory /var/db/openldap-data
maxsize 1073741824

syncrepl rid=000
 provider=ldap://ldap2.loga.us
 type=refreshAndPersist
 starttls=yes
 retry="5 5 300 +"
 searchbase="dc=loga,dc=us"
 attrs="*,+"
 bindmethod=simple
 binddn="cn=Manager,dc=loga,dc=us"
 credentials=secret
 tls_cacert=/usr/local/etc/sslcerts/ldapcerts/cacert.pem
 tls_reqcert=demand

# Indices to maintain
index default pres,eq
index uid,memberUid,gidNumber

# Create indexes for attribute cn (commonname) and givenName
# EQUALITY, SUBSTR searches and provides optimization
# for sc=a* type searches
index cn,givenName eq,sub,subinitial

# Create indexes for sn (surname) on
# EQUALITY and SUBSTR searches
index sn eq,sub

# Creates indexes for attribute mail on
# presence, EQUALITY and SUBSTR
index mail pres,eq,sub

# Optimises searches of form objectclass=person
index objectclass eq

# Syncprov indexes
index entryCSN eq
index entryUUID eq

# Mirror mode essential to allow writes
# and must appear after all syncrepl directives
mirrormode TRUE

# Define the provider to use the syncprov overlay
# (last directives in database section)
overlay syncprov

# contextCSN saved to database every 100 updates or 10 mins.
syncprov-checkpoint 100 10
syncprov-sessionlog 100

 

Settings for Server 2:

Below is the /usr/local/etc/openldap/slapd.conf file for server ldap2.loga.us:

 

#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
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

# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org

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

loglevel 256

# Load dynamic backend modules:
modulepath /usr/local/libexec/openldap
#moduleload back_bdb
moduleload back_mdb
# moduleload back_hdb
# moduleload back_ldap

# Security - TLS Section
TLSCACertificateFile /usr/local/etc/sslcerts/ldapcerts/cacert.pem
TLSCertificateFile /usr/local/etc/sslcerts/ldapcerts/ldap2cert.pem
TLSCertificateKeyFile /usr/local/etc/sslcerts/ldapcerts/ldap2key.pem
TLSCipherSuite TLSv1+RSA:!NULL
security ssf=128

serverID 002

allow bind_v2

# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64

# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!

#######################################################################
# BDB database definitions
#######################################################################

database mdb

suffix "dc=loga,dc=us"
rootdn "cn=Manager,dc=loga,dc=us"

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

rootpw {SSHA}GgBPwusIQQpVPoT3Ycsalhwocqbfk+Lp
password-hash {SSHA}

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

directory /var/db/openldap-data
maxsize 10737441824

syncrepl rid=000
 provider=ldap://ldap1.loga.us
 type=refreshAndPersist
 starttls=yes
 retry="5 5 300 +"
 searchbase="dc=loga,dc=us"
 attrs="*,+"
 bindmethod=simple
 binddn="cn=Manager,dc=loga,dc=us"
 credentials=secret
 tls_cacert=/usr/local/etc/sslcerts/ldapcerts/cacert.pem
 tls_reqcert=demand

# Indices to maintain
index default pres,eq
index uid,memberUid,gidNumber

# Create indexes for attribute cn (commonname) and givenName
# EQUALITY, SUBSTR searches and provides optimization
# for sc=a* type searches
index cn,givenName eq,sub,subinitial

# Create indexes for sn (surname) on
# EQUALITY and SUBSTR searches
index sn eq,sub

# Creates indexes for attribute mail on
# presence, EQUALITY and SUBSTR
index mail pres,eq,sub

# Optimises searches of form objectclass=person
index objectclass eq

# Syncprov Indexes
index entryCSN eq
index entryUUID eq

# Mirror mode essential to allow writes 
# and must appear after all syncrepl directives 
mirrormode TRUE 

# Define the provider to use the syncprov overlay 
# (last directives in database section) 
overlay syncprov 

# contextCSN saved to database every 100 updates or 10 mins. 
syncprov-checkpoint 100 10 
syncprov-sessionlog 100

 

 

ldap.conf:

 

Settings for Server 1:

Below is the /usr/local/etc/openldap/ldap.conf file for server ldap1.loga.us:

Note: URI has changed from the first article in this series in order to reflect using certificates with matching URI names.

 

#
# LDAP Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

BASE dc=loga,dc=us
URI ldap://ldap1.loga.us

ssl start_tls

TLS_CACERT /usr/local/etc/sslcerts/ldapcerts/cacert.pem
TLS_REQCERT demand

# SIZELIMIT 0 indicates unlimited search size

SIZELIMIT 0 
TIMELIMIT 15
DEREF never

 

Settings for Server 2:

Below is the /usr/local/etc/openldap/ldap.conf file for server ldap2.loga.us:

Note: URI has changed from the first article in this series in order to reflect using certificates with matching URI names.

 

#
# LDAP Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

BASE dc=loga,dc=us
URI ldap://ldap2.loga.us

ssl start_tls

TLS_CACERT /usr/local/etc/sslcerts/ldapcerts/cacert.pem
TLS_REQCERT demand

# SIZELIMIT 0 indicates unlimited search size

SIZELIMIT 0 
TIMELIMIT 15
DEREF never

 

 

nscld.conf:

 

Settings for Server 1:

Below is the /usr/local/etc/nscld.conf file for server ldap1.loga.us:

 

# This is the configuration file for the LDAP nameservice
# switch library's nslcd daemon. It configures the mapping
# between NSS names (see /etc/nsswitch.conf) and LDAP
# information in the directory.
# See the manual page nslcd.conf(5) for more information.

# The user and group nslcd should run as.
uid nslcd
gid nslcd

# The uri pointing to the LDAP server to use for name lookups.
# Multiple entries may be specified. The address that is used
# here should be resolvable without using LDAP (obviously).
#uri ldap://127.0.0.1/
#uri ldaps://127.0.0.1/
#uri ldapi://%2fvar%2frun%2fldapi_sock/
# Note: %2f encodes the '/' used as directory separator
uri ldap://ldap1.loga.us/

# The LDAP version to use (defaults to 3
# if supported by client library)
ldap_version 3

# The distinguished name of the search base.
base dc=loga,dc=us

# The distinguished name to bind to the server with.
# Optional: default is to bind anonymously.
#binddn cn=proxyuser,dc=example,dc=com

# The credentials to bind with.
# Optional: default is no credentials.
# Note that if you set a bindpw you should check the permissions of this file.
#bindpw secret

# The distinguished name to perform password modifications by root by.
#rootpwmoddn cn=admin,dc=example,dc=com

# The default search scope.
scope sub
#scope one
#scope base

# Customize certain database lookups.
base group ou=Groups,dc=loga,dc=us
base passwd ou=People,dc=loga,dc=us
base shadow ou=People,dc=loga,dc=us
#scope group onelevel
#scope hosts sub

# Bind/connect timelimit.
bind_timelimit 30

# Search timelimit.
timelimit 30

# Idle timelimit. nslcd will close connections if the
# server has not been contacted for the number of seconds.
idle_timelimit 3600

# Use StartTLS without verifying the server certificate.
ssl start_tls
tls_reqcert demand

# CA certificates for server certificate verification
#tls_cacertdir /etc/ssl/certs
tls_cacertfile /usr/local/etc/sslcerts/ldapcerts/cacert.pem

# Seed the PRNG if /dev/urandom is not provided
#tls_randfile /var/run/egd-pool

# SSL cipher suite
# See man ciphers for syntax
tls_ciphers TLSv1

# Client certificate and key
# Use these, if your server requires client authentication.
#tls_cert
#tls_key

# Mappings for Services for UNIX 3.5
#filter passwd (objectClass=User)
#map passwd uid msSFU30Name
#map passwd userPassword msSFU30Password
#map passwd homeDirectory msSFU30HomeDirectory
#map passwd homeDirectory msSFUHomeDirectory
#filter shadow (objectClass=User)
#map shadow uid msSFU30Name
#map shadow userPassword msSFU30Password
#filter group (objectClass=Group)
#map group member msSFU30PosixMember

# Mappings for Services for UNIX 2.0
#filter passwd (objectClass=User)
#map passwd uid msSFUName
#map passwd userPassword msSFUPassword
#map passwd homeDirectory msSFUHomeDirectory
#map passwd gecos msSFUName
#filter shadow (objectClass=User)
#map shadow uid msSFUName
#map shadow userPassword msSFUPassword
#map shadow shadowLastChange pwdLastSet
#filter group (objectClass=Group)
#map group member posixMember

# Mappings for Active Directory
#pagesize 1000
#referrals off
#idle_timelimit 800
#filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHo
meDirectory=*))
#map passwd uid sAMAccountName
#map passwd homeDirectory unixHomeDirectory
#map passwd gecos displayName
#filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHo
meDirectory=*))
#map shadow uid sAMAccountName
#map shadow shadowLastChange pwdLastSet
#filter group (objectClass=group)

# Alternative mappings for Active Directory
# (replace the SIDs in the objectSid mappings with the value for your domain)
#pagesize 1000
#referrals off
#idle_timelimit 800
#filter passwd (&(objectClass=user)(objectClass=person)(!(objectClass=computer))
)
#map passwd uid cn
#map passwd uidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820
#map passwd gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820
#map passwd homeDirectory "/home/$cn"
#map passwd gecos displayName
#map passwd loginShell "/bin/bash"
#filter group (|(objectClass=group)(objectClass=person))
#map group gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820

# Mappings for AIX SecureWay
#filter passwd (objectClass=aixAccount)
#map passwd uid userName
#map passwd userPassword passwordChar
#map passwd uidNumber uid
#map passwd gidNumber gid
#filter group (objectClass=aixAccessGroup)
#map group cn groupName
#map group gidNumber gid

nss_initgroups_ignoreusers ALLLOCAL

 

Settings for Server 2:

Below is the /usr/local/etc/nscld.conf file for server ldap2.loga.us:

 

# This is the configuration file for the LDAP nameservice
# switch library's nslcd daemon. It configures the mapping
# between NSS names (see /etc/nsswitch.conf) and LDAP
# information in the directory.
# See the manual page nslcd.conf(5) for more information.

# The user and group nslcd should run as.
uid nslcd
gid nslcd

# The uri pointing to the LDAP server to use for name lookups.
# Multiple entries may be specified. The address that is used
# here should be resolvable without using LDAP (obviously).
#uri ldap://127.0.0.1/
#uri ldaps://127.0.0.1/
#uri ldapi://%2fvar%2frun%2fldapi_sock/
# Note: %2f encodes the '/' used as directory separator
uri ldap://ldap2.loga.us/

# The LDAP version to use (defaults to 3
# if supported by client library)
ldap_version 3

# The distinguished name of the search base.
base dc=loga,dc=us

# The distinguished name to bind to the server with.
# Optional: default is to bind anonymously.
#binddn cn=proxyuser,dc=example,dc=com

# The credentials to bind with.
# Optional: default is no credentials.
# Note that if you set a bindpw you should check the permissions of this file.
#bindpw secret

# The distinguished name to perform password modifications by root by.
#rootpwmoddn cn=admin,dc=example,dc=com

# The default search scope.
scope sub
#scope one
#scope base

# Customize certain database lookups.
base group ou=Groups,dc=loga,dc=us
base passwd ou=People,dc=loga,dc=us
base shadow ou=People,dc=loga,dc=us
#scope group onelevel
#scope hosts sub

# Bind/connect timelimit.
bind_timelimit 30

# Search timelimit.
timelimit 30

# Idle timelimit. nslcd will close connections if the
# server has not been contacted for the number of seconds.
idle_timelimit 3600

# Use StartTLS without verifying the server certificate.
ssl start_tls
tls_reqcert demand

# CA certificates for server certificate verification
#tls_cacertdir /etc/ssl/certs
tls_cacertfile /usr/local/etc/sslcerts/ldapcerts/cacert.pem

# Seed the PRNG if /dev/urandom is not provided
#tls_randfile /var/run/egd-pool

# SSL cipher suite
# See man ciphers for syntax
tls_ciphers TLSv1

# Client certificate and key
# Use these, if your server requires client authentication.
#tls_cert
#tls_key

# Mappings for Services for UNIX 3.5
#filter passwd (objectClass=User)
#map passwd uid msSFU30Name
#map passwd userPassword msSFU30Password
#map passwd homeDirectory msSFU30HomeDirectory
#map passwd homeDirectory msSFUHomeDirectory
#filter shadow (objectClass=User)
#map shadow uid msSFU30Name
#map shadow userPassword msSFU30Password
#filter group (objectClass=Group)
#map group member msSFU30PosixMember

# Mappings for Services for UNIX 2.0
#filter passwd (objectClass=User)
#map passwd uid msSFUName
#map passwd userPassword msSFUPassword
#map passwd homeDirectory msSFUHomeDirectory
#map passwd gecos msSFUName
#filter shadow (objectClass=User)
#map shadow uid msSFUName
#map shadow userPassword msSFUPassword
#map shadow shadowLastChange pwdLastSet
#filter group (objectClass=Group)
#map group member posixMember

# Mappings for Active Directory
#pagesize 1000
#referrals off
#idle_timelimit 800
#filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHo
meDirectory=*))
#map passwd uid sAMAccountName
#map passwd homeDirectory unixHomeDirectory
#map passwd gecos displayName
#filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHo
meDirectory=*))
#map shadow uid sAMAccountName
#map shadow shadowLastChange pwdLastSet
#filter group (objectClass=group)

# Alternative mappings for Active Directory
# (replace the SIDs in the objectSid mappings with the value for your domain)
#pagesize 1000
#referrals off
#idle_timelimit 800
#filter passwd (&(objectClass=user)(objectClass=person)(!(objectClass=computer))
)
#map passwd uid cn
#map passwd uidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820
#map passwd gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820
#map passwd homeDirectory "/home/$cn"
#map passwd gecos displayName
#map passwd loginShell "/bin/bash"
#filter group (|(objectClass=group)(objectClass=person))
#map group gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820

# Mappings for AIX SecureWay
#filter passwd (objectClass=aixAccount)
#map passwd uid userName
#map passwd userPassword passwordChar
#map passwd uidNumber uid
#map passwd gidNumber gid
#filter group (objectClass=aixAccessGroup)
#map group cn groupName
#map group gidNumber gid

nss_initgroups_ignoreusers ALLLOCAL

 

 

config.php – phpLDAPadmin:

 

Settings for Server 1:

Below is the /usr/local/www/phpldapadmin/config/config.php file for server ldap1.loga.us:

 

/*********************************************
 * Define your LDAP servers in this section *
 *********************************************/

$servers = new Datastore();

/* $servers->NewServer('ldap_pla') must be called before each new LDAP server
 declaration. */
$servers->newServer('ldap_pla');

/* A convenient name that will appear in the tree viewer and throughout
 phpLDAPadmin to identify this LDAP server to users. */
$servers->setValue('server','name','My LDAP Server');

/* Examples:
 'ldap.example.com',
 'ldaps://ldap.example.com/',
 'ldapi://%2fusr%local%2fvar%2frun%2fldapi'
 (Unix socket at /usr/local/var/run/ldap) */
$servers->setValue('server','host','ldap://ldap1.loga.us');

/* The port your LDAP server listens on (no quotes). 389 is standard. */
$servers->setValue('server','port',389);

/* Array of base DNs of your LDAP server. Leave this blank to have phpLDAPadmin
 auto-detect it for you. */
// $servers->setValue('server','base',array(''));

/* Five options for auth_type:
 1. 'cookie': you will login via a web form, and a client-side cookie will
 store your login dn and password.
 2. 'session': same as cookie but your login dn and password are stored on the
 web server in a persistent session variable.
 3. 'http': same as session but your login dn and password are retrieved via
 HTTP authentication.
 4. 'config': specify your login dn and password here in this config file. No
 login will be required to use phpLDAPadmin for this server.
 5. 'sasl': login will be taken from the webserver's kerberos authentication.
 Currently only GSSAPI has been tested (using mod_auth_kerb).

 Choose wisely to protect your authentication information appropriately for
 your situation. If you choose 'cookie', your cookie contents will be
 encrypted using blowfish and the secret your specify above as
 session['blowfish']. */
$servers->setValue('login','auth_type','session');

/* The DN of the user for phpLDAPadmin to bind with. For anonymous binds or
 'cookie','session' or 'sasl' auth_types, LEAVE THE LOGIN_DN AND LOGIN_PASS
 BLANK. If you specify a login_attr in conjunction with a cookie or session
 auth_type, then you can also specify the bind_id/bind_pass here for searching
 the directory for users (ie, if your LDAP server does not allow anonymous
 binds. */
// $servers->setValue('login','bind_id','');
# $servers->setValue('login','bind_id','cn=Manager,dc=example,dc=com');

/* Your LDAP password. If you specified an empty bind_id above, this MUST also
 be blank. */
// $servers->setValue('login','bind_pass','');
# $servers->setValue('login','bind_pass','secret');

/* Use TLS (Transport Layer Security) to connect to the LDAP server. */
   $servers->setValue('server','tls',true);

 

Settings for Server 2:

Below is the /usr/local/www/phpldapadmin/config/config.php file for server ldap2.loga.us:

 

/*********************************************
 * Define your LDAP servers in this section *
 *********************************************/

$servers = new Datastore();

/* $servers->NewServer('ldap_pla') must be called before each new LDAP server
 declaration. */
$servers->newServer('ldap_pla');

/* A convenient name that will appear in the tree viewer and throughout
 phpLDAPadmin to identify this LDAP server to users. */
$servers->setValue('server','name','My LDAP Server');

/* Examples:
 'ldap.example.com',
 'ldaps://ldap.example.com/',
 'ldapi://%2fusr%local%2fvar%2frun%2fldapi'
 (Unix socket at /usr/local/var/run/ldap) */
$servers->setValue('server','host','ldap://ldap1.loga.us');

/* The port your LDAP server listens on (no quotes). 389 is standard. */
$servers->setValue('server','port',389);

/* Array of base DNs of your LDAP server. Leave this blank to have phpLDAPadmin
 auto-detect it for you. */
// $servers->setValue('server','base',array(''));

/* Five options for auth_type:
 1. 'cookie': you will login via a web form, and a client-side cookie will
 store your login dn and password.
 2. 'session': same as cookie but your login dn and password are stored on the
 web server in a persistent session variable.
 3. 'http': same as session but your login dn and password are retrieved via
 HTTP authentication.
 4. 'config': specify your login dn and password here in this config file. No
 login will be required to use phpLDAPadmin for this server.
 5. 'sasl': login will be taken from the webserver's kerberos authentication.
 Currently only GSSAPI has been tested (using mod_auth_kerb).

 Choose wisely to protect your authentication information appropriately for
 your situation. If you choose 'cookie', your cookie contents will be
 encrypted using blowfish and the secret your specify above as
 session['blowfish']. */
$servers->setValue('login','auth_type','session');

/* The DN of the user for phpLDAPadmin to bind with. For anonymous binds or
 'cookie','session' or 'sasl' auth_types, LEAVE THE LOGIN_DN AND LOGIN_PASS
 BLANK. If you specify a login_attr in conjunction with a cookie or session
 auth_type, then you can also specify the bind_id/bind_pass here for searching
 the directory for users (ie, if your LDAP server does not allow anonymous
 binds. */
// $servers->setValue('login','bind_id','');
# $servers->setValue('login','bind_id','cn=Manager,dc=example,dc=com');

/* Your LDAP password. If you specified an empty bind_id above, this MUST also
 be blank. */
// $servers->setValue('login','bind_pass','');
# $servers->setValue('login','bind_pass','secret');

/* Use TLS (Transport Layer Security) to connect to the LDAP server. */
   $servers->setValue('server','tls',true);

 

rc.conf for both servers:

Included is the /etc/rc.conf file to ensure both ldap://  (TLS) and ldaps:// (SSL) connections are possible.  Connections via ldapi:// via sockets are not included:

slapd_enable="YES"
slapd_flags="-4 -h 'ldap:/// ldaps:///'"

 

Testing:

To ensure TLS/SSL is configured correctly and our certificates are valid.  A little testing is in order.

# ldapsearch
# extended LDIF
#
# LDAPv3
# base <dc=loga,dc=us> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 13 Confidentiality required
text: confidentiality required

From the last line of the output, one can see our security strength factor (ssf=128) that requires a minimum of 128 bit cryptographic key length is working fine.  Next, ldapsearch command is executed again with the -Z Z option which issues the startTLS extended operations and requires the operation to be successful.

# ldapsearch -ZZ
# GroupNames, Groups, loga.us
dn: cn=GroupNames,ou=Groups,dc=loga,dc=us
businessCategory: Internet
cn: GroupNames
description: GroupNames
member: cn=Sam Hall,ou=People,dc=loga,dc=us
objectClass: groupOfNames
objectClass: top

# search result
search: 3
result: 0 Success

From the abbreviated ldapsearch -ZZ command output, it’s evident our certificates and TLS/SSL requirements are working correctly.

 

Summary:

By now, all the end points, servers, processes, and tools connect to the OpenLDAP servers via TLS or SSL connections.  In Part VI, Macintosh OS X 10.9 client connections to the OpenLDAP Server is demonstrated.

 

Additional Resources:

http://www.openldap.org

http://www.zytrax.com

5 thoughts on “Openldap and Multi-Master Replication in FreeBSD – Part V: TLS/SSL to secure OpenLDAP Data”

  1. Hi,

    I see that you put the same, server1 data to both servers configuration. Is that only an accident or did yo do that on purpose?

    # Security – TLS Section
    TLSCACertificateFile /usr/local/etc/openldap/certs/cacert.pem
    TLSCertificateFile /usr/local/etc/openldap/certs/ldap1cert.pem
    TLSCertificateKeyFile /usr/local/etc/openldap/certs/ldap1key.pem
    TLSCipherSuite TLSv1+RSA:!NULL
    security ssf=128

    1. In the example, Server 1 should have ldap1cert.pem and ldap1key.pem and Server 2 should have ldap2cert.pem and ldap2key.pem. Each ldap server must have its own certificate. Thanks for the feedback!

      P.S. I corrected the site to reflect the change.

      1. Hi,

        I hope to have a response.

        I already know how to perform a replication multi master but not in TLS.

        If I understand, for both servers, I have to generate certs with the same cacert.pem right ?

        And, still for both servers, I have to store the same certs ?

        I thank you in advance

        1. Matthieu, I believe I used the same cacert.pem for both key and CSR Generation in the tutorial. Since the certificates are self-signed, it would be wise to store both certificates on each server.

Leave a Reply

Your email address will not be published. Required fields are marked *