Обновить
Мне удалось воспроизвести проблему в меньшем масштабе, используя простой скрипт php, который пытается выполнить привязку LDAP. Из этого сценария я получил больше отладочных данных, которые позволяют мне определить настоящую проблему. Итак, я переписываю этот вопрос.
Я пытаюсь настроить среду LDAP на своем сервере Debian Wheezy.
Я хочу защитить связь с сервером, используя действующий сертификат SSL (то есть он не самоподписанный).
Я использую самокомпилированную версию OpenLDAP, потому что последняя версия в репозитории Debian не поддерживает хэши паролей SHA2.
Я могу использовать этот простой скрипт php, чтобы попытаться выполнить привязку к моему серверу LDAP.
<?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>';
?>
Привязка не удалась, и сценарий выдает следующие сообщения в моем журнале ошибок apache:
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
Так что, очевидно, проблема в сертификате. Полагаю, что библиотека php ldap по какой-то причине не находит / не использует мой ldap.conf
(который находится под /usr/local/etc/openldap
) и поэтому не использует предоставленный там TLS_CACERT.
Я пробовал создать символическую ссылку /usr/local/etc/openldap/ldap.conf
к /etc/openldap/ldap.conf
, который обычно используется по умолчанию. К сожалению, это тоже не сработало.
Обновить Я смог заставить его работать, поставив
putenv('LDAPTLS_CACERT=/path/to/my/root.ca');
внутри моего сценария. Это доказывает, что php не использует мои ldap.conf
. Было бы разумным решением поместить эту переменную окружения в мою конфигурацию phpldapadmin?
Другие клиентские инструменты LDAP, отличные от php, такие как ldapsearch
работают отлично.
Кто-нибудь знает, что может привести к тому, что клиентская библиотека php ldap не найдет / не использует мой ldap.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
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
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
<?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);
?>
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
Чтобы убедиться, что это не проблема конфигурации SSL, которую я вызвал:
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 отлично работает:
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
Вот версии соответствующих программных пакетов, которые я использую:
slapd -V
@(#) $OpenLDAP: slapd 2.4.39 (Sep 28 2014 22:28:35)
php --version
PHP 5.4.4-14+deb7u14 (cli) (built: Aug 21 2014 08:36:44)
apache2 -v
Server version: Apache/2.2.22 (Debian)
Server built: Jul 24 2014 15:34:00
cat /usr/share/phpldapadmin/VERSION
RELEASE-1.2.2
Извините за очень длинный вопрос. Я надеюсь, что кто-то сможет мне помочь, потому что у меня почти нет идей.
Большое спасибо за любую помощь заранее!
Хорошо, я смог это решить.
Мне нужна была символическая ссылка от /usr/local/etc/openlad/ldap.conf
к /etc/ldap/ldap.conf