Bonjour
J'essaye depuis quelques jours de faire dialoguer mon apache-ssl qui héberge une application avec un openldap.
Nous avons finalement réussi à résoudre le problème.
Voilà quelques infos pour ceux qui veulent mettre en place un système d'authentification forte entre un site web et un annuaire openldap.
--------Config--------
Serveur apache:
OS Debian Etch 4.0
apache-ssl v1.3
php4
Serveur ldap:
OS Debian sarge 3.1
Openldap v1.130.2.13.2.1
----------------------
L'idée est la suivante:
Mon site est accessible en https. Les utilisateurs s'authentifient par certificat. Cette partie là fonctionne bien.
Parallèlement, le site accède à des données hébergées sur un autre serveur qui a openldap d'installé. L'accès à ce ldap doit se faire avec SSL/TLS.
Le problème ici concerne bien le dialogue entre le code php du site et le serveur ldap.
Des certificats ont été générés et signés par une même autorité de certification pour le serveur LDAP et pour le serveur apache.
Côté ldap, le fichier slapd.conf contient ces informations:
Code :
- #Certificat de l'AC
- TLSCACertificateFile /etc/ldap/ssl/cert_CA.cert
- #Certificat du serveur ldap
- TLSCertificateFile /etc/ldap/ssl/cert_mon_ldap.cert
- #Clé privée du serveur ldap
- TLSCertificateKeyFile /etc/ldap/ssl/cert_mon_ldap.key
- #Demande d'un certificat client valide
- TLSVerifyClient demand
|
Côté serveur apache-ssl, mon site a le code suivant (volontairement simplifié pour seulement tester la connexion):
Code :
- $host="ldaps://monserveur.mondomaine.com";
- $port="636";
- $ds=ldap_connect($host,$port);
- ldap_set_option($ds,LDAP_OPT_PROTOCOL_VERSION,3);
- $r=@ldap_bind($ds,"cn=admin,o=organisation,c=fr","password" );
- $sr=ldap_search($ds,"o=organisation,c=fr",("objectClass=organizationalUnit" ));
- $info=ldap_get_entries($ds,$sr);
- print $info["count"]." enregistrements trouvés.";
|
Le fichier /etc/ldap/ldap.conf du serveur apache (considéré comme client) contient les informations suivantes:
Code :
- TLS_REQCERT demand
- TLS_CACERT /etc/ssl/cert/cert_CA.cert
|
Enfin, le fichier .ldaprc doit être créé (s'il n'existe pas) dans le hoe directory du user apache et il doit contenir:
Code :
- TLS_CERT /etc/ssl/cert/cert_mon_apachessl.cert
- TLS_KEY /etc/ssl/cert/key_mon_apachessl.key
|
Quand je fais des tests de connexion sur le port 389, c'est-à-dire que la connexion avec le ldap s'effectue en clair, tout fonctionne bien. Mais si je passe en ldaps sur le port 636, ça ne fonctionne plus.
Côté ldap dans les logs, j'ai alors le message "TLS accept error error=-1".
A noter que le cn du certificat du ldap correspond bien à l'url qui me permet de me connecter au ldap à savoir monserveur.mondomaine.com.
En fait je ne sais pas si php va bien lire dans le fichier /etc/ldap/ldap.conf.
J'ai fait pas mal de rercherche et voici quelques liens qui pourront en aider certains:
http://www.arnaudcharlier.be/blog/ [...] l-avec-php
http://www.openldap.org/pub/ksoper/OpenLDAP_TLS.html
http://www.openldap.org/lists/open [...] 01023.html
Voici mes questions:
1) comment savoir si php va bien lire dans le fichier /etc/ldap/ldap.conf ?
2) avez vous des idées pour faire fonctionner cette connexion entre le site php et le ldap?
La question a été posée plusieurs fois sur le net mais il n'y a pas vraiment de réponse claire qui fonctionne.
Souvent la solution de facilité est de mettre le paramètre TLSVerifyClient à never mais du coup, même si cela fonctionne, il n'y a plus de sécurité car le serveur ldap autorise toujours la connexion (pas de demande de certificat valide) sans être sûr de l'identité du serveur qui vient se connecter.
Merci d'avance
------------------Solutions-------------------
Il y avait en fait 2 problèmes:
1) Le certificat généré pour le serveur apache ne contenait pas l'extension "Web client authentication" mais seulement "Web server Authentication".
J'ai généré un nouveau certificat avec les 2 extensions.
2) Il manquait le positionnement de la variable d'environnement $HOME au chargement d'apache.
L'initialisation de cette variable permet à php d'aller chercher le fichier .ldaprc, de récupérer le certificat indiqué dans le fichier et de le présenter au ldap.
La solution que j'ai trouvé pour initialiser cette variable (mais il y en a sûrement d'autres), c'est de modifier la ligne suivante dans le script de démarrage apache:
Code :
- ENV="env -i LANG=C PATH=/bin:/usr/bin/usr/local/bin HOME=/<home_dir_user_apache>"
|
Note: - pour que le chargement de la nouvelle variable soit pris en compte, il faut faire un stop/start de apache et non un restart.
- il est important côté client et serveur de choisir la demande d'un certificat valide (TLSVerifyClient demand) sans quoi l'authentification n'a plus lieu d'être. On trouve beaucoup de commentaire sur le web de personnes qui résolvent le problème en mettant ce paramètre à "never". Dans ce cas, le serveur ne vérifie pas le certificat client et autorise toujours la connexion ce qui dans le cas présent est totalement contraire à ce que l'on veut faire.
Message édité par neyro le 20-12-2007 à 15:41:47