# OpenLDAP + SSL communication problem

## wyvern

I'm having trouble getting OpenLDAP/SSL working, I hope somebody can help me. Here's what I did. (/etc files at the end)

My server is a Gentoo server, relatively new with no hacks. I emerged OpenLDAP, configured /etc/openldap/slapd.conf and /etc/conf.d/slapd and loaded some information into the directory. That worked fine and slapd started without problems.

I then tried to access the LDAP server from another machine using 

 *Quote:*   

> $ ldapsearch -H "ldap://ogre.phys.uvic.ca" -b "dc=phys,dc=uvic,dc=ca"

 

This returned the info I expected. So far, so good. I then tried to set up SSL. I emerged openssl, and then configured openssl.cnf. Then following the advice from http://www.sendmail.org/~ca/email/other/cagreg.html, I created the root CA and the certificates I would need:

 *Quote:*   

> 
> 
> # cd /etc/ssl
> 
> # openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem -days 365 -config openssl.cnf
> ...

 

I used 'Root CA' for the CA common name. Then:

 *Quote:*   

> 
> 
> # openssl req -nodes -new -x509 -keyout ldapkey.pem -out ldapkey.pem -days 365 -config openssl.cnf
> 
> # openssl x509 -x509toreq -in ldapkey.pem -signkey ldapkey.pem -out tmp.pem
> ...

 

I used 'ogre.phys.UVic.CA' as the common name, which is the name of the machine as returned by DNS. (I also tried ogre.phys.uvic.ca, which changed nothing)

So now I have a private key for ldap in /etc/ssl/ldapkey.pem, and a signed cert in /etc/ssl/ldap.pem. I set up the slapd.conf to include the lines

```

TLSCertificateFile /etc/ssl/ldap.pem

TLSCertificateKeyFile /etc/ssl/ldapkey.pem

```

So I can get TLS working. Finally, I edit /etc/conf.d/slapd to:

```

OPTS="-d7 -h 'ldap:// ldaps://'"

```

And restart the slapd. No problems.

Then, on the remote machine, I try a simple SSL search and get this:

 *Quote:*   

> 
> 
> $ ldapsearch -H "ldaps://ogre.phys.uvic.ca" -b "dc=phys,dc=uvic,dc=ca"
> 
> ldap_bind: Can't contact LDAP server
> ...

 

I then tried using openssl's s_client to see if I could get some more information:

 *Quote:*   

> 
> 
> # openssl s_client -CAfile /etc/ssl/cacert.pem -connect ogre.phys.uvic.ca:636
> 
> CONNECTED(00000003)
> ...

 

cacert.pem is the root certificate from ogre, copied to the remote machine. By 'remote', I mean on the same subnet.

Here is the output from slapd during the ldapsearch connect:

 *Quote:*   

> 
> 
> connection_get(10)
> 
> connection_get(10): got connid=0
> ...

 

What am I doing wrong?   :Mad:   Am I somehow generating the wrong kind of certificate, or using them in an incorrect manner? Any help would be appreciated. 

Here is my openssl.cnf:

```

#

# OpenSSL example configuration file.

# This is mostly being used for generation of certificate requests.

#

# This definition stops the following lines choking if HOME isn't

# defined.

HOME         = .

RANDFILE      = $ENV::HOME/.rnd

# Extra OBJECT IDENTIFIER info:

#oid_file      = $ENV::HOME/.oid

oid_section      = new_oids

# To use this configuration file with the "-extfile" option of the

# "openssl x509" utility, name here the section containing the

# X.509v3 extensions to use:

# extensions      = 

# (Alternatively, use a configuration file that has only

# X.509v3 extensions in its main [= default] section.)

[ new_oids ]

# We can add new OIDs in here for use by 'ca' and 'req'.

# Add a simple OID like this:

# testoid1=1.2.3.4

# Or use config file substitution like this:

# testoid2=${testoid1}.5.6

####################################################################

[ ca ]

default_ca   = CA_default      # The default ca section

####################################################################

[ CA_default ]

dir      = /etc/ssl      # Where everything is kept

certs      = $dir/certs      # Where the issued certs are kept

crl_dir      = $dir/crl      # Where the issued crl are kept

database   = $dir/index.txt   # database index file.

new_certs_dir   = $dir/newcerts      # default place for new certs.

certificate   = $dir/cacert.pem    # The CA certificate

serial      = $dir/serial       # The current serial number

crl      = $dir/crl.pem       # The current CRL

private_key   = $dir/private/cakey.pem# The private key

RANDFILE   = $dir/private/.rand   # private random number file

x509_extensions   = usr_cert      # The extentions to add to the cert

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs

# so this is commented out by default to leave a V1 CRL.

# crl_extensions   = crl_ext

default_days   = 365         # how long to certify for

default_crl_days= 30         # how long before next CRL

default_md   = md5         # which md to use.

preserve   = no         # keep passed DN ordering

# A few difference way of specifying how similar the request should look

# For type CA, the listed attributes must be the same, and the optional

# and supplied fields are just that :-)

policy      = policy_match

# For the CA policy

[ policy_match ]

countryName      = match

stateOrProvinceName   = match

organizationName   = match

organizationalUnitName   = optional

commonName      = supplied

emailAddress      = optional

# For the 'anything' policy

# At this point in time, you must list all acceptable 'object'

# types.

[ policy_anything ]

countryName      = optional

stateOrProvinceName   = optional

localityName      = optional

organizationName   = optional

organizationalUnitName   = optional

commonName      = supplied

emailAddress      = optional

####################################################################

[ req ]

default_bits      = 1024

default_keyfile    = privkey.pem

distinguished_name   = req_distinguished_name

attributes      = req_attributes

x509_extensions   = v3_ca   # The extentions to add to the self signed cert

# Passwords for private keys if not present they will be prompted for

# input_password = secret

# output_password = secret

# This sets a mask for permitted string types. There are several options. 

# default: PrintableString, T61String, BMPString.

# pkix    : PrintableString, BMPString.

# utf8only: only UTF8Strings.

# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).

# MASK:XXXX a literal mask value.

# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings

# so use this option with caution!

string_mask = nombstr

# req_extensions = v3_req # The extensions to add to a certificate request

[ req_distinguished_name ]

countryName         = Country Name (2 letter code)

countryName_default      = CA

countryName_min         = 2

countryName_max         = 2

stateOrProvinceName      = State or Province Name (full name)

stateOrProvinceName_default   = British Columbia

localityName         = Locality Name (eg, city)

localityName_default      = Victoria

0.organizationName      = Organization Name (eg, company)

0.organizationName_default   = University of Victoria HEP

# we can do this but it is not needed normally :-)

#1.organizationName      = Second Organization Name (eg, company)

#1.organizationName_default   = World Wide Web Pty Ltd

organizationalUnitName      = Organizational Unit Name (eg, section)

organizationalUnitName_default   = HEP

commonName         = Common Name (eg, YOUR name)

commonName_max         = 64

emailAddress         = Email Address

emailAddress_max      = 40

# SET-ex3         = SET extension number 3

[ req_attributes ]

challengePassword      = A challenge password

challengePassword_min      = 4

challengePassword_max      = 20

unstructuredName      = An optional company name

[ usr_cert ]

# These extensions are added when 'ca' signs a request.

# This goes against PKIX guidelines but some CAs do it and some software

# requires this to avoid interpreting an end user certificate as a CA.

basicConstraints=CA:FALSE

# Here are some examples of the usage of nsCertType. If it is omitted

# the certificate can be used for anything *except* object signing.

# This is OK for an SSL server.

# nsCertType         = server

# For an object signing certificate this would be used.

# nsCertType = objsign

# For normal client use this is typical

# nsCertType = client, email

# and for everything including object signing:

# nsCertType = client, email, objsign

# This is typical in keyUsage for a client certificate.

# keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# This will be displayed in Netscape's comment listbox.

nsComment         = "OpenSSL Generated Certificate"

# PKIX recommendations harmless if included in all certificates.

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid,issuer:always

# This stuff is for subjectAltName and issuerAltname.

# Import the email address.

# subjectAltName=email:copy

# Copy subject details

# issuerAltName=issuer:copy

#nsCaRevocationUrl      = http://www.domain.dom/ca-crl.pem

#nsBaseUrl

#nsRevocationUrl

#nsRenewalUrl

#nsCaPolicyUrl

#nsSslServerName

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

[ v3_ca ]

# Extensions for a typical CA

# PKIX recommendation.

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid:always,issuer:always

# This is what PKIX recommends but some broken software chokes on critical

# extensions.

#basicConstraints = critical,CA:true

# So we do this instead.

basicConstraints = CA:true

# Key usage: this is typical for a CA certificate. However since it will

# prevent it being used as an test self-signed certificate it is best

# left out by default.

# keyUsage = cRLSign, keyCertSign

# Some might want this also

# nsCertType = sslCA, emailCA

# Include email address in subject alt name: another PKIX recommendation

# subjectAltName=email:copy

# Copy issuer details

# issuerAltName=issuer:copy

# DER hex encoding of an extension: beware experts only!

# obj=DER:02:03

# Where 'obj' is a standard or added object

# You can even override a supported extension:

# basicConstraints= critical, DER:30:03:01:01:FF

[ crl_ext ]

# CRL extensions.

# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.

# issuerAltName=issuer:copy

authorityKeyIdentifier=keyid:always,issuer:always

```

Here is my slapd.conf:

```

# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.8.8.7 2001/09/27 20:00:31 kurt Exp $

#

# See slapd.conf(5) for details on configuration options.

# This file should NOT be world readable.

#

include      /etc/openldap/schema/core.schema

include      /etc/openldap/schema/cosine.schema

include      /etc/openldap/schema/inetorgperson.schema 

include    /etc/openldap/schema/nis.schema

include    /etc/openldap/schema/krb5-kdc.schema

# Define global ACLs to disable default read access.

# Users with /admin principals can change anything

# Users can change their shell, anyone else can see it

access to dn=="uid=([^,]+),ou=HEP,dc=phys,dc=uvic,dc=ca" attr=loginShell

   by dn="uid=$1\+(realm=HEP\.PHYS\.UVIC\.CA)?" write

   by dn="uid=[^/]+/admin\+(realm=HEP\.PHYS\.UVIC\.CA)?" write

   by * read

# Default read access for everything else

access to *

   by dn="uid=[^/]+/admin\+(realm=HEP\.PHYS\.UVIC\.CA)?" write

   by * read

# 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

# Create a replication log in /var/lib/openldap-slurp for use by slurpd

#   REPLICA: comment this out in replicas

replogfile   /var/lib/openldap-slurp/master-slapd.replog

# Load dynamic backend modules:

# modulepath   /usr/lib/openldap/openldap

# moduleload   back_ldap.la

# moduleload   back_ldbm.la

# moduleload   back_passwd.la

# moduleload   back_shell.la

#

# Sample Access Control

#   Allow read access of root DSE

#   Allow self write access

#   Allow authenticated users read access

#   Allow anonymous users to authenticate

#

#access to dn="" by * read

#access to *

#   by self write

#   by users read

#   by anonymous auth

#

# if no access controls are present, the default is:

#   Allow read by all

#

# rootdn can always write!

# SSL certificate and key with the official (as reported by a reverse

# DNS name lookup) hostname in the CN field.

# Make sure the key file is not world-readable. Best also if the ldap

# user can't write to it. 

#   REPLICA: Each replica should have it's own SSL cert/key

TLSCertificateFile /etc/ssl/ldap.pem

TLSCertificateKeyFile /etc/ssl/ldapkey.pem

#######################################################################

# ldbm database definitions

#######################################################################

database   ldbm

suffix      "dc=phys,dc=uvic,dc=ca"

#suffix      "o=My Organization Name,c=US"

rootdn      "cn=Manager,dc=phys,dc=uvic,dc=ca"

#rootdn      "cn=Manager,o=My Organization Name,c=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      <snip>

# The database directory MUST exist prior to running slapd AND 

# should only be accessible by the slapd/tools. Mode 700 recommended.

directory   /var/lib/openldap-ldbm

# Indices to maintain

index   objectClass,uid,uidNumber,gidNumber,memberUid   eq

index   cn,mail,surname,givenname         eq,subinitial

```

Need...help...badly...  :Sad: 

----------

## wica

common name has to be the your host name of the server

nslookup [server ip]

----------

## wyvern

It wasn't the common name.  :Smile: 

I solved it by modifying slapd.conf like so:

```

...

TLSVerifyClient allow

TLSCertificateFile /etc/ssl/ldap.pem

TLSCertificateKeyFile /etc/ssl/ldap.pem

TLSCACertificateFile /etc/ssl/cacert.pem

...

```

And by modifying ldap.conf on the client like so:

```

...

ssl start_tls

tls_reqcert allow

tls_cacertfile /etc/ssl/cacert.pem

...

```

I generated the certificate 'ldap.pem' like so:

 *Quote:*   

> 
> 
> # openssl req -new -x509 -nodes -out ldap.pem -keyout ldap.pem -days 365
> 
> 

 

I don't know why this particular configuration works and the other doesn't. It looks like black magic to me.    :Confused:   But I had a gander at a live session with ethereal, and I didn't see any unencrypted data during the session, so I guess it's all good... I hope.

----------

