3

Update

I have been able to reproduce the problem in a smaller scale using a simple php script that attempts an LDAP bind. From that script I got more debug output which lets me identify the actual problem. So I am rewriting this question.

Scenario

I am trying to set up an LDAP environment on my Debian Wheezy server.
I want to secure the communication with the server using a valid SSL certificate (meaning, it is not self signed).
I am using a self compiled version of OpenLDAP because the latest version in the Debian repository does not support SHA2 password hashes.

Problem Details

I can use this simple php script to try to bind to my LDAP server.

<?php
        error_reporting(E_ALL);
        ini_set('display_errors', 'On');
        /* if I remove this, it doesn't work */
        putenv('LDAPTLS_CACERT=/path/to/my/root.ca');
        $uri='ldaps://localhost';
        if (!ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7) ) {
                die('log level option failed\n');
        }
        $ldap = ldap_connect($uri) or die ('connect failed');
        if ( !ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3) ) {
                die('protocol version set failed\n');
        }
        if ( !ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0) ) {
                die('referrals option set failed\n');
        }
        $dn = 'cn=root,dc=domain,dc=tld';
        $pw = '...';
        $bind = ldap_bind($ldap, $dn, $pw);
        if ($bind) {
                echo 'bind succeeded\n';
        } else {
                echo 'bind failed\n';
        }
        ldap_close($ldap);
        echo '<p>blubb</p>';
?>

Binding fails and the script produces following messages in my apache error log:

ldap_create
ldap_url_parse_ext(ldaps://localhost)
ldap_bind_s
ldap_simple_bind_s
ldap_sasl_bind_s
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP localhost:636
ldap_new_socket: 20
ldap_prepare_socket: 20
ldap_connect_to_host: Trying 127.0.0.1:636
ldap_pvt_connect: fd: 20 tm: -1 async: 0
TLS: peer cert untrusted or revoked (0x42)
TLS: can't connect: (unknown error code).
ldap_err2string

So it is obviously a certificate problem. I guess, that the php ldap library for some reason doesn't find/use my ldap.conf (which is located under /usr/local/etc/openldap) and therefore doesn't use the TLS_CACERT provided there.
I tried symlinking /usr/local/etc/openldap/ldap.conf to /etc/openldap/ldap.conf, which normally is the default location. That sadly didn't work either.

Update I was able to get it working by putting

putenv('LDAPTLS_CACERT=/path/to/my/root.ca');

inside my script. This proves that php doesn't use my ldap.conf. Would it be a reasonable solution to put this enviroment variable in my phpldapadmin configuration?

Other non-php LDAP client tools, such as ldapsearch work perfectly.

Does anyone have an idea what could cause the php ldap client library to not find/use my ldap.conf?

System Configuration

slapd.conf

cat /usr/local/etc/openldap/slapd.conf

include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/inetorgperson.schema

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

# self-compiled to enable SHA2 password hash support
modulepath /usr/local/lib
moduleload pw-sha2.so

database        bdb
suffix          "dc=domain,dc=tld"
rootdn          "cn=root,dc=domain,dc=tld"
cachesize       2000

# Use this command to generate a SHA512 hash:
# slappasswd -o module-path=/usr/local/lib -o module-load=pw-sha2.so -h "{SSHA512}"
rootpw          {SSHA512}...

directory       /var/ldap
mode 0600
# Indices to maintain
index   objectClass     eq
index   cn              pres,eq

###############################################################################
# Logging stuff
###############################################################################
loglevel      488

###############################################################################
# TLS stuff
###############################################################################

TLSCipherSuite        ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
TLSCertificateFile    path to certificate file
TLSCertificateKeyFile path to key file
TLSCACertificateFile  path to CA certificate file
TLSVerifyClient       never

###############################################################################
# LDAP security stuff
###############################################################################

password-hash {SSHA512}
security update_tls=256 ssf=256
require authc bind

###############################################################################
# ACLs
###############################################################################

# enable users to change their own password. Everyone else can only use it for auth
#access to * by *
access to attrs=userPassword
       by self write
       by * auth

slapd startup parameters

ps aux | grep slapd
ldap      4801  0.0  0.0  73612  7924 ?        Ssl  07:19   0:00 /usr/local/bin/slapd -h ldaps://127.0.0.1:636 -g ldap -u ldap -f /usr/local/etc/openldap/slapd.conf

ldap.conf

cat /usr/local/etc/openldap/ldap.conf

BASE    dc=domain,dc=tld
URI     ldaps://127.0.0.1:636

#TLS_REQCERT     never
TLS_CACERT      path to CA certificate file

phpldapadmin config.php (all comments removed)

<?php
  $config->custom->debug['level'] = 255;
  $config->custom->debug['syslog'] = true;
$config->custom->appearance['friendly_attrs'] = array(
    'facsimileTelephoneNumber' => 'Fax',
    'gid'                      => 'Group',
    'mail'                     => 'Email',
    'telephoneNumber'          => 'Telephone',
    'uid'                      => 'User Name',
    'userPassword'             => 'Password'
);
   $config->custom->modify_member['attr'] = 'dn';


$servers = new Datastore();
$servers->newServer('ldap_pla');
$servers->setValue('server','name','domain.tld LDAP server');
/* according to documentation port must be provided in URI and server->port
 * must be 0 when using ldaps
 */
$servers->setValue('server','host','ldaps://127.0.0.1:636');
$servers->setValue('server','port',0);
$servers->setValue('server','base',array('dc=domain,dc=tld'));
$servers->setValue('login','auth_type','session');
$servers->setValue('login','bind_id','cn=root,dc=domain,dc=tld');
/* no need to enable this, if ldap is running on port 636 with ldaps:// */
$servers->setValue('server','tls',false);
$servers->setValue('login','anon_bind',false);
?>

LDAP DB content (Just getting started ;) )

slapcat

dn: dc=domain,dc=tld
dc: domain
objectClass: dcObject
objectClass: organizationalUnit
structuralObjectClass: organizationalUnit
entryUUID: c2dc8e83-77a6-47ca-b245-f74636aca48f
creatorsName: cn=root,dc=domain,dc=tld
createTimestamp: 20140928123911Z
ou: domain.tld
entryCSN: 20140929080227.350590Z#000000#000#000000
modifiersName: cn=root,dc=domain,dc=tld
modifyTimestamp: 20140929080227Z

What I tried

To ensure this is not a SSL configuration problem I invoked:

openssl s_client -connect localhost:636 -CAfile /path/to/CA_certificate.file -verify 5 

CONNECTED(00000003)
depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Certification Authority
verify return:1
depth=1 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Class 1 Primary Intermediate Server CA
verify return:1
depth=0 description = BNw48VehLnkei38O, C = DE, CN = domain.tld, emailAddress = webmaster@domain.tld
verify return:1
---
Certificate chain
 0 s:/description=<stripped>/C=DE/CN=domain.tld/emailAddress=webmaster@domain.tld
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
 1 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
 2 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
<stripped>
-----END CERTIFICATE-----
subject=/description=BNw48VehLnkei38O/C=DE/CN=domain.tld/emailAddress=webmaster@domain.tld
issuer=/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
---
No client certificate CA names sent
---
SSL handshake has read 5739 bytes and written 891 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-GCM-SHA384
    Session-ID: <stripped>
    Session-ID-ctx: 
    Master-Key: <stripped>
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    <stripped>

    Start Time: 1412055431
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

ldapsearch works perfectly:

su www-data -c 'ldapsearch -H "ldaps://localhost" -b "dc=domain,dc=tld" -s base "dc=domain,dc=tld" -D "cn=root,dc=domain,dc=tld" -w"<stripped>" -v -d256'
ldap_initialize( ldaps://localhost:636/??base )
filter: dc=domain,dc=tld
requesting: All userApplication attributes
# extended LDIF
#
# LDAPv3
# base <dc=domain,dc=tld> with scope baseObject
# filter: dc=domain,dc=tld
# requesting: ALL
#

# search result
search: 2
result: 0 Success

# numResponses: 1

Versions

These are the versions of the relevant software packages I use:

OpenLDAP (self compiled)

slapd -V
@(#) $OpenLDAP: slapd 2.4.39 (Sep 28 2014 22:28:35)

PHP

php --version
PHP 5.4.4-14+deb7u14 (cli) (built: Aug 21 2014 08:36:44)

Apache

apache2 -v
Server version: Apache/2.2.22 (Debian)
Server built:   Jul 24 2014 15:34:00

phpldapadmin (from SID)

cat /usr/share/phpldapadmin/VERSION
RELEASE-1.2.2

Sorry for this very long question. I hope someone is able to help me, because I'm pretty much out of ideas.
Thanks a lot for any help in advance!

  • Did you check syslog for slapd entries? Maybe also increase the loglevel (see slapd.conf man page). – tlo Sep 30 '14 at 9:55
  • The syslog snipped above contains a few lines of slapd output (such as that a TLS connection has been established). But I will increase the loglevel and post results – Chris Sep 30 '14 at 10:14
  • Raised loglevel to 488 now. I added the additional output in the log above – Chris Sep 30 '14 at 11:13
  • I was able to reproduce the problem in a smaller scale and could therefore simplify the question and identify the actual problem. the php ldap library doesn't seem to find/use my ldap.conf. I rewrote the question – Chris Oct 1 '14 at 6:14
  • And another update: I was able to 'solve' it, by putting a LDAPTLS_CACERT enviroment variable in my script. Would it be a reasonable solution to put this environment variable somewhere in the phplapadmin sources? Also updated question – Chris Oct 1 '14 at 6:59
0

Ok, I was able to solve it.
I needed a symlink from /usr/local/etc/openlad/ldap.conf to /etc/ldap/ldap.conf

  • Do you mean /usr/local/etc/openldap/ldap.conf? Or maybe /usr/local/etc/ldap/ldap.conf? Why is your system looking for the config file there? – Richard Hansen Aug 24 '15 at 6:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.