evoformations/support/openldap.tex

1196 lines
43 KiB
TeX
Raw Normal View History

\chapter{Les annuaires}
~\\
\section{Les services d'annuaire en g<>n<EFBFBD>ral}
~\\
\subsection{D<EFBFBD>finitions}
\begin{itemize}
\item{\textbf{Annuaire}} :D<>finition (Larousse) : \textsc{Annuaire n.m. (lat. annuus, annuel). Ouvrage publi<6C> chaque ann<6E>e, donnant la liste des membres
d'une profession, des abonn<6E>s <20> un service, etc. Annuaire du t<>l<EFBFBD>phone.}\\
Exemples : Annuaire t<>l<EFBFBD>phonique (pages jaunes, pages blanches), Guide Michelin (guide rouge, etc.),
\item{\textbf{Annuaire <20>lectronique}}: D<>finition : \textsc{ Possibilit<69> de mise-<2D>-jour directement pour la consultation en ligne.}\\
Exemples : pagesjaunes.fr, DMOZ (Open Directory Project), Listes des utilisateurs sur un ordinateur (fichier /etc/passwd sous Unix)
\item{\textbf{Service d'annuaire}}: D<>finition : \textsc{ Service r<>seau, Architecture client/serveur}\\
Exemples : Annuaire des d<>veloppeurs Debian, Annuaires dans les universit<69>s fran<61>aises,
\end{itemize}
~\\
Note : en anglais, annuaire se dit "directory".
%\subsection{Annuaires distribu<62>s}
%Dans les cas o<> l'on doit stocker une grande quantit<69> d'informations, une base centralis<69>e est non raisonable.
%TODO
%<25>viter la duplication des donn<6E>es
%R<>partition en fonction du temps de r<>ponse => acc<63>s simple et rapide
%\textit{Exemples : <20>tat civil, Annuaire distribu<62> des adresses de l'Internet (DNS)}
\subsection{Exemples}
%Mettre des sch<63>mas DNS (voir Oreilly Bind) :
%D<>l<EFBFBD>guation d'autorit<69>
\subsubsection{DNS}
Le service DNS (Domain Name System) permet la conversion de noms de domaine en adresses IP (et inversement). On parlera de "nom pleinement qualifi<66>" pour d<>signer un nom de domaine complet (typiquement sousdomaine.domaine.tld).\\
Il est plus facile pour l'<27>tre humain de retenir des noms que des num<75>ros : il a donc <20>t<EFBFBD> d<>cid<69> d'associer des noms de domaine aux adresses IP. Au d<>part, un simple fichier HOSTS.TXT rassemblait les correspondances entre les adresses IP et les noms. Mais rapidement, ce syst<73>me est devenu ing<6E>rable et il fut d<>cid<69> d'opter pour une base de donn<6E>es distribu<62>es en arbre (similaire au syst<73>me de fichier UNIX) : la racine est g<>r<EFBFBD>e par l'ICANN\footnote{\url{http://www.icann.org/}} et les sous-domaines de la racine (TLD) sont d<>l<EFBFBD>gu<67>s <20> des organismes : par exemple, chaque pays se voit confier un TLD (fr pour la France, us pour les <20>tats-Unis, uk pour la Grande-Bretagne, etc.). Ces organismes permettent ensuite <20> certaines soci<63>t<EFBFBD>s, sous certaines conditions, de revendre des sous-domaines. <20> chaque sous-domaine achet<65> est associ<63> un ou plusieurs serveurs DNS ma<6D>tre. Il est conseill<6C> d'utiliser un serveur ma<6D>tre primaire et un serveur ma<6D>tre secondaire (ou serveur esclave) qui se synchronise sur le serveur primaire.\\
\textbf{Serveur DNS}\\
Un serveur DNS est (souvent) ma<6D>tre pour un certain nombre de noms de domaines, c'est-<2D>-dire qu'il a autorit<69> sur plusieurs zones. Il peut ainsi r<>soudre un certains nombres de demandes (il contient les informations gr<67>ce <20> des fichiers) ou d<>l<EFBFBD>guer des sous-zones <20> d'autres serveurs de domaine. Le serveur r<>pond donc aux requ<71>tes o<> il a autorit<69> (en r<>pondant directement ou en redirigeant vers le serveur ayant autorit<69>) ou bien se redirige vers un serveur "racine" capable lui-m<>me de rediriger vers les serveurs appropri<72>s.\\
Au niveau r<>seau, un serveur DNS <20>coute sur le port 53 en TCP et UDP.\\
\textbf{Resolvers DNS}\\
Un r<>solver, ou client DNS, peut formuler deux types de demandes <20> un serveur DNS~:
\begin{itemize}
\item{les demandes en mode r<>cursif} qui demandent une r<>solution compl<70>te au serveur DNS, l'obligeant <20> faire lui-m<>me les requ<71>tes pour apporter la r<>ponse
\item{les demandes en mode it<69>ratif} qui demandent une r<>ponse sans g<>n<EFBFBD>rer de requ<71>te de la part du serveur (sera donc sovent redirig<69> vers un serveur racine ou d<>l<EFBFBD>gu<67>)
\end{itemize}
\textit{Exemple de r<>solution "classique"}\\
Le r<>solveur adresse une requ<71>te en mode r<>cursif : le serveur local envoie une requ<71>te en mode it<69>ratif <20> un serveur de nom faisant autorit<69> sur la demande. Il essaiera le serveur le plus <20> m<>me de r<>pondre. Dans le pire des cas il contactera un serveur "racine" et suivra les r<>f<EFBFBD>rences jusqu'<27> obtenir une r<>ponse compl<70>te (g<>n<EFBFBD>ralement par le serveur de nom s'occupant du r<>seau o<> se trouve la machine).\\
Une fois la r<>ponse trouv<75>e, le serveur local envoie la r<>ponse au r<>solveur.\\
Attention, il faut noter que les applications ou les syst<73>mes ont souvent leur propre cache DNS.\\
~\\
\textit{Types d'enregistrement}\\
Bien que le principal but soit de convertir un nom de domaine en adresse IP, il existe diff<66>rents types d'enregistrement au niveau d'un serveur DNS. L'enregistrement principal est l'enregistrement A qui associe directement un nom de domaine <20> une adresse IP mais il enexiste d'autres : l'enregistrement CNAME (qui lie un nom de domaine vers un autre nom de domaine), MX (qui permet de sp<73>cifier plusieurs serveurs SMTP avec diff<66>rentes priorit<69>s), NS (qui sp<73>cifie les serveurs de noms), TXT (qui permet d'avoir un champ texte), PTR (pour les enregistrements invers), etc. Il existe <20>galement des enregistrements pour IPv6 o<> il faut <20> priori utiliser les enregistrements AAAA (il peut exister <20>galement des enregistrements A6).\\
~\\
\textit{R<EFBFBD>solution inverse}\\
La r<>solution d'une adresse en nom n'est pas triviale car le processus de r<>solution devrait conna<6E>tre <20> peu pr<70>s toutes les branches de l'arbre pour pouvoir r<>pondre, (sans compter que plusieurs noms pointent souvent vers la m<>me adresse). L'id<69>e a donc <20>t<EFBFBD> de d<>velopp<70>e un sous-domaine pour les adresses. Ce sous-domaine est in-addr.arpa et peut contenir toutes les adresse IP existantes (elles sont invers<72>es afin de partir des feuilles jusqu'<27> la racine). Ainsi, pour qu'une adresse IP fasse l'objet d'une r<>solution inverse, elle doit avoir un enregistrement dans ce sous-domaine.\\
~\\
\textbf{M<EFBFBD>moire cache et dur<75>e de vie}\\
En plus des diff<66>rents m<>canismes de r<>solution, l'utilisation d'une m<>moire-cache acc<63>l<EFBFBD>re efficacement ces r<>solutions. En effet, lorsqu'un serveur de nom effectue une requ<71>te r<>cursive il obtient de nombreuses informations (r<>solutions compl<70>tes, serveurs faisant autorit<69>, etc.). Il va donc stocker ces informations afin de pouvoir r<>pondre plus rapidement <20> de prochaines requ<71>tes utilisant ces informations, et ainsi <20>viter d'interroger de nouveau les serveurs concern<72>s. Il conserve en fait ces donn<6E>es pendant un temps fix<69> par le serveur DNS o<> il a <20>t<EFBFBD> cherch<63> ses donn<6E>es. Les serveurs DNS ayant des donn<6E>es qui varient fr<66>quemment adapteront donc cette dur<75>e appel<65>e TTL (Time To Live).\\
~\\
\textit{Les outils}\\
L'outil "historique" pour provoquer une r<>solution DNS est \textit{nsloookup}.
Sous Unix, on trouvera les outils \textit{host} et \textit{dig}.\\
~\\
Exemple d'une requ<71>te avec dig~:\\
\begin{verbatim}
$ dig @192.168.1.4 cmi.univ-mrs.fr +norecurse +notcp \
+noquestion +noauthority +noadditional MX
; <<>> DiG 9.3.1 <<>> @192.168.1.4 cmi.univ-mrs.fr
+norecurse +notcp +noquestion +noauthority +noadditional MX
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4914
;; flags: qr ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 2
;; ANSWER section:
cmi.univ-mrs.fr. 86236 IN MX 10 gyptis.univ-mrs.fr.
;; Query time: 6 msec
;; SERVER: 192.168.1.4#53(192.168.1.4)
;; WHEN: Sun Nov 6 19:56:15 2005
;; MSG SIZE rcvd: 157
\end{verbatim}
\subsubsection{Arborescence des syst<73>mes de fichiers Unix}
sch<EFBFBD>mas avec /bin, /boot, /etc, /usr, /var, etc.
Avantages de la r<>partition en r<>pertoires :
- Nombre de fichiers limit<69>s par r<>pertoires
- Performance (acc<63>s plus rapide, recherche optimis<69>e, etc.)
\subsubsection{Gestion des utilisateurs}
On peut voir les fichiers qui stocke les utilisateurs et des renseignements
sur eux (et m<>me leurs mots de passe) comme un annuaire~:
Extrait d'un fichier /etc/passwd~:
\begin{verbatim}
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
\end{verbatim}
NIS/NIS+ est un service standard Unix qui permet de partager
des fichiers/annuaires pour toutes les machines d'un r<>seau :
\begin{verbatim}
/etc/passwd
/etc/group
/etc/hosts
/etc/aliases
/etc/protocols
/etc/services
\end{verbatim}
LDAP/Active Directory
\section{Protocole LDAP}
\subsection{Historique}
X.500, standard promulgu<67> par l'OSI\footnote{International Organization for Standardization} et l'ITU-T\footnote{International Telecommunication Union-Telecommunication Standardization Sector}, d<>finit :
- DAP (Directory Access protocol) : protocole de communication DUA<->DSA
- DSP (Directory System Protocol) : protocole de communication entre DSAs
- DISP (Directory Information Shadowing Protocol) : protocole de synchronisation/r<>plication entre DSAs
- DOP (Directory Operational Bindings Management Protocol) : protocole de gestion de liaison op<6F>rationnelle d'annuaire
DIB (Directory Information Base) : objets, classes d'objet, OID
DIT (Directory Information Tree) : noeud, feuille, alias, DN, RDN,
Mod<EFBFBD>les clients (DUA) / serveurs (DSA) : connexion, op<6F>ration, r<>plication, droits, authentification
% Sch<63>mas d'apr<70>s http://www.sysium.com/ldap.html
% http://sec.cs.kent.ac.uk/x500book/
Ces protocoles standards et ouverts ont <20>t<EFBFBD> normalis<69>s au d<>but des ann<6E>es 1990.
S'appuyant sur des couches r<>seaux aujourd'hui peu r<>pandues (mod<6F>le OSI), on
ne retrouve directement ces protocoles que dans des applications sp<73>cifiques
(arm<72>e, gouvernement, etc.). N<>anmoins, ces protocoles ont pos<6F>s les fondements
de toutes les applications d'annuaires modernes.
LDAP est d<>riv<69> du protocole DAP X.500, c'est-<2D>-dire le protocole de communication entre un DUA et DSA.
Il s'agit d'une version simplifi<66>e (d'o<> l'appelation "Light") principalement tir<69>e du fait
qu'elle s'appuye sur la couche r<>seau TCP/IP, version simplifi<66>e et r<>pandue du mod<6F>le r<>seau d'OSI.
C'est l'IETF (Internet Engineering Task Force) qui centralise les travaux sur LDAP et publie les
sp<EFBFBD>cifications dans des RFCs. La derni<6E>re version de LDAP est la version 3.
\subsection{Vocabulaire}
\textbf{Sch<EFBFBD>ma}\\
Un sch<63>ma est une d<>finition de classes d'objets, d'attributs et leur syntaxe. Chaque serveur utilisant un sch<63>ma sp<73>cifique ou des extensions doit l'enregistrer notamment pour obtenir un OID.\\
Exemple de d<>finition d'attributs~:
\begin{verbatim}
attributetype ( 1.3.6.1.4.1.18413.21.3.10 NAME 'postfixTransport'
DESC 'transport for Postfix'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{20} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.18413.21.3.20 NAME 'isActive'
DESC 'an account is active or not'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
\end{verbatim}
SYNTAX (1.3.6.1.4.1.1466.115.121.1.x)~:
\begin{verbatim}
7 = Boolean
8 = Certificat
15 = Directory String
26 = IA5 String
27 = INTEGER
50 = Telephone Number
\end{verbatim}
EQUALITY :
\begin{verbatim}
telephoneNumberMatch
integerMatch
booleanMatch
caseExactIA5Match
caseIgnoreIA5Match
\end{verbatim}
\textit{Liens~:}\\
\url{http://www.openldap.org/doc/admin22/schema.html}\\
\url{http://www.iana.org/cgi-bin/enterprise.pl}\\
\url{http://www.rfc-editor.org/rfc/rfc2252.txt}\\
EQUALITY type
SYNTAX type
\textbf{Objectclass}\\
Les classes d'objet, d<>finies dans un sch<63>ma par un nom et OID (Object IDentifier), mod<6F>lisent des objets d<>finissant un certain nombres d'attributs obligatoires ou facultatifs. Elles peuvent <20>tre de plusieurs types~:\\
- structurelle <20>ad correspondant <20> la description d'objets basiques~: personnes, groupes, etc.
- auxiliaire c<>d correspondant <20> des informations compl<70>mentaires <20> des objets de classe "structure"
- abstraite c<>d d<>signant des objets basiques de LDAP comme 'top' ou 'alias'
Les ObjectClass forment une hi<68>rarchie. Prenons l'exemple de la classe d'objet "person" : elle est d<>finie en tant que "SUP top STRUCTURAL", c'est <20> dire que c'est une classe structurelle en dessous de la classe abstraite 'top'. L'ObjectClass 'top' est toujours tout en haut. En pratique, il n'est pas n<>cessaire de le pr<70>ciser mais il sera toujours l<> (m<>me si il n'apparait pas). Les classes abstraites sont implicitement l<>~!\\
\textbf{OID (Object IDentifier)}\\
Un OID est une s<>quence de nombres entiers s<>par<61>s par des points normalis<69>e dans la RFC 2256. L'OID doit <20>tre unique afin de permettre une compatibilit<69> entre les applications. C'est l'IANA\footnote{Internet Assigned Numbers Authority} qui est responsable de leur attribution et chaque entreprise peut obtenir un OID.\\
\textit{Lien~:} \url{http://www.isi.edu/cgi-bin/iana/enterprise.pl}\\
\textbf{attribut}\\
Les attributs, d<>finis dans un sch<63>ma, sont rattach<63>s <20> une classe d'objet. Un attribut d<>finit une certaine syntaxe et des contraintes pour des donn<6E>es~: on peut rapprocher l'attribut LDAP du type de donn<6E>es d'une base de donn<6E>es.\\
\textbf{entr<EFBFBD>e (ou objet)}\\
Il s'agit d'un ensemble de donn<6E>es entr<74>es formant un noeud dans l'arbre. Elle est d<>finit de mani<6E>re unique par un DN. Elle contient un ou plusieurs attributs. Une donn<6E>e est rattach<63>e <20> un attribut. On peut avoir plusieurs valeurs pour un attribut.\\
un objet doit <20>tre identifi<66> de mani<6E>re unique
son adresse permet de retrouver l'objet
un objet peut avoir plusieurs noms
\textbf{DN (Distinguish Name)}\\
Le DN est une suite de valeurs (\textit{code = valeur}, o<> \textit{code} est l'un des attributs de l'entr<74>e et \textit{valeur} est la valeur associ<63>e <20> l'attribut dans l'entr<74>e) s<>par<61>es par des virgules. L'ordre est important : on remonte l'arbre (le suffixe se trouve donc <20> gauche). Le DN d<>finit une entr<74>e unique pour un annuaire LDAP. Exemple~: \textit{cn=Manager,dc=evolix,dc=net}\\
\textbf{RDN (Relative DN)}\\
%(on remonte vers le suffixe)
\textbf{suffixe}\\
Il s'agit du DN du domaine. Il est souvent calqu<71> sur un nom de domaine appartenant <20> la structure. Exemple : \textit{dc=evolix,dc=net}\\
\textbf{CN (Common Name)}\\
Il s'agit simplement d'un attribut (obligatoire) appartenant <20> la classe d'objet person. Il est souvent utilis<69> comme premier code dans le DN d'une entr<74>e correspiondant <20> une personne. Mais l'on peut tout aussi bien utiliser un autre attribut (uid est <20>galement souvent utilis<69>).\\
DIT
Un DSA est un serveur de l'architecture LDAP/X.500
Un DUA est un client LDAP/X.500
\subsection{Protocole d'acc<63>s}
Capture de trame LDAP
Commentaires sur le protocole.
\subsection{RFCs <20> propos de LDAP}
RFC 1777 : LDAPv2
RFC 2251 : LDAPv3
RFC 2252 : syntaxe des attributs
RFC 2254 : filtres de recherche LDAP
RFC 2255 : format des URLs LDAP
\subsection{Principes des sch<63>mas LDAP}
attributs
Syntaxe attributs
Classes d'objects
Arborescence des classes d'objet
\subsection{Format LDIF}
Ldap Data Interchange Format
RFC 2849
Repr<EFBFBD>sentation sous forme de fichier texte des donn<6E>es
pr<EFBFBD>sentes dans un annuaire.
Syntaxe pour g<>rer des ajouts, modifications, suppressions.
\subsubsection{Les mod<6F>les LDAP}
mod<EFBFBD>le = services offerts par un serveur LDAP
La RFC 2251 d<>finit deux mod<6F>les :
\subsubsection{Mod<EFBFBD>le protocole}
\subsubsection{Mod<EFBFBD>le donn<6E>es}
N<EFBFBD>anmoins, certains ouvrages pr<70>sentent quatres mod<6F>les :
\subsubsection{Mod<EFBFBD>le d'information}
\subsubsection{Mod<EFBFBD>le de nommage}
\subsubsection{Mod<EFBFBD>le fonctionnel}
\subsubsection{Mod<EFBFBD>le de s<>curit<69>}
\subsection{Annuaires LDAP vs Bases de donn<6E>es}
\subsubsection{Acc<EFBFBD>s en lecture (consultation)}
\subsubsection{Mod<EFBFBD>le hi<68>rachique (arborescence)}
Pour stocker un grand nombre de donn<6E>es et pouvoir y acc<63>der de fa<66>on optimis<69>e,
il faut s<>parer les donn<6E>es. Les s<>parer dans plusieurs branches du m<>me niveau
revient <20> les r<>partir dans diff<66>rentes tables. Mais si l'on prend en consid<69>ration
que le nombre de branches est important, il devient n<>cessaire d'<27>galement s<>parer ces
branches. On entre donc dans un mod<6F>le hierarchique impossible <20> avoir avec une base
de donn<6E>es classique (pas de hi<68>rarchie entre les tables).
\subsubsection{Possibilit<EFBFBD> d'une mod<6F>le distribu<62>}
\subsubsection{S<EFBFBD>curit<EFBFBD> (authentification, gestion des droits)}
\subsubsection{Orient<EFBFBD>e objet}
\subsubsection{etc.}
\subsection{Vue du march<63> LDAP}
\subsubsection{Logiciels serveurs LDAP}
OpenLDAP
MS Active Directory
% http://mi.cnrs-orleans.fr/Security/Win2k/ActiveDirectory/ActiveDirectory1.htm
Novell eDirectory
etc.
\subsubsection{Logiciels compatibles LDAP}
Microsoft Outlook
Apache
ProFTPD
Applications WEB
\subsubsection{Logiciels clients LDAP}
Il existe plusieurs logiciels clients pour visualiser, ins<6E>rer, modifier, supprimer, etc. des donn<6E>es issues d'un annuaire LDAP~:
\begin{itemize}
\item \textbf{LDAP Browser/Editor} logiciel graphique en Java permettant
de visualiser, modifier et rechercher ais<69>ment. Import et export au
format LDIF sont pratiques.\\
\textit{Lien~:} \url{http://www-unix.mcs.anl.gov/~gawor/ldap/}
\item \textbf{PhpLDAPadmin} interface web en PHP permettant d'effectuer de nombreuses op<6F>rations ais<69>ment.\\
\textit{Lien~:} \url{http://phpldapadmin.sourceforge.net/}
\end{itemize}
Voir aussi les clients proprios (notam. Microsoft)
\section{Champs d'applications des annuaires LDAP}
\subsection{Service d'authentification}
\subsubsection{L'authentification avec LDAP}
simple\_bind
simple\_bind\_s
\subsubsection{Utilisation dans un logiciel}
\subsubsection{Exemple avec Windows/Active Directory}
\subsubsection{Exemple avec Linux/libnss}
\subsubsection{Exemple avec Apache}
\subsubsection{Autres exemples}
\subsubsection{Utilisation avec SASL}
\subsubsection{Un pas vers la SSO}
\subsection{Service de stockage d'informations}
\subsubsection{Informations stock<63>es avec LDAP}
\subsubsection{Utilisation dans un logiciel}
\subsubsection{Stockage de profils}
\subsubsection{Contr<EFBFBD>le d'acc<63>s aux donn<6E>es}
\subsubsection{Exemple avec un carnet d'adresses}
\subsubsection{LDAP et les langages de programmation}
%\section{M<>ta-annuaire LDAP}
%Annuaire d'annuaire
\section{Architecture et mise en place}
%http://www.sysium.com/fr/offres-ldap/annuaire-ldap/demarche-ldap.html
\subsection{Concevoir un cahier des charges}
Respect des conventions
Lister applications
Lister contenu
\subsubsection{Audit de l'existant}
\subsubsection{Expression des besoins}
\subsubsection{D<EFBFBD>finition du contenu et architecture}
\subsubsection{Choix techniques}
\subsubsection{Ajout de sch<63>mas personnalis<69>s}
Applications clients
Utiliser sch<63>mas existants
<EFBFBD>tendre ou ajouter des sch<63>mas
\subsubsection{Politique de s<>curit<69>}
ACLs
\subsubsection{Test et recette}
V<EFBFBD>rifications
Benchmarks
\subsection{Utilisation et administration}
\subsubsection{Gestion des donn<6E>es}
\subsubsection{Logiciels client LDAP}
\subsubsection{Import/export donn<6E>es}
\subsubsection{Utilisation avec SSL/TLS}
\subsubsection{R<EFBFBD>plication}
\subsubsection{Sauvegarde}
\section{Application pratique}
\subsection{Mise en place d'un annuaire LDAP}
\subsubsection{Installation}
\subsubsection{Configuration}
\subsubsection{Gestion des droits}
\subsubsection{Installation des sch<63>mas}
\subsubsection{S<EFBFBD>curit<EFBFBD>}
\subsection{Utilisation d'un annuaire LDAP}
\subsubsection{Installation des outils n<>cessaires}
\subsubsection{Configuration}
\subsubsection{<EFBFBD>criture des fichiers au format LDIF}
\subsubsection{Ajout/modification/suppression donn<6E>es}
\subsubsection{Recherche de donn<6E>es}
%\subsection{Utilisation avec TLS}
\subsubsection{Focus sur l'authentification LDAP}
\newpage
\section{OpenLDAP}
~\\
\subsection{Pr<EFBFBD>sentation}
~\\
LDAP (Lightweight Directory Access Protocol) est un protocole pour acc<63>der <20> un service d'annuaire. Les annuaires permettent de partager des informations, telles que des coordonn<6E>es d'entit<69>s ou personnes ou encore des donn<6E>es syst<73>me. Un annuaire est une base de donn<6E>es sp<73>cifique structur<75>e dans une arborescence hi<68>rarchique. Un annuaire est cens<6E> <20>tre largement plus performant en consultation qu'un syst<73>me de gestion de bases de donn<6E>es classique. LDAP peut servir d'annuaire pour g<>rer des coordonn<6E>es, pour servir des applications (SMTP, Groupware, etc.) ou pour g<>rer l'authentification (UNIX, Apache, IMAP, etc.)\\
~\\
\textit{Liens~:}\\
\url{http://www-sop.inria.fr/semir/personnel/Laurent.Mirtain/ldap-livre.html}\\
\url{http://www.cru.fr/ldap/}\\
\url{http://www.quesaco.org/astuces.php?targt=ldap}\\
\url{http://www.fefe.de/tinyldap/}\\
\url{http://www.commentcamarche.net/ldap/}\\
\url{http://www.lifl.fr/~boulet/formation/syst-dist/exposes2003-2004/ldap/}\\
http://www.computerbooksonline.com/chapters/ldapchap.htm
http://www.editions-eyrolles.com/Livre/9782212115048/annuaires-ldap
http://yolinux.com/TUTORIALS/LinuxTutorialLDAP.html
\subsection{Installation}
\subsubsection{<EFBFBD> partir des sources}
~\\
On peut utiliser la m<>thode classique de recompilation <20> partir des sources~:
\begin{verbatim}
$ ./configure [options]
$ make depend
$ make
# make install
\end{verbatim}
\subsubsection{Par paquets}
~\\
Sous Debian, les paquets principaux <20> installer sont~:
~\\
\textbf{slapd} : serveur OpenLDAP\\
\textbf{libldap} : librairies OpenLDAP\\
\textbf{ldap-utils} : outils OpenLDAP\\
~\\
\emph{D<EFBFBD>pendances Debian~:}
\begin{center}
\begin{tabular}{|c|c|}
\hline
libc6 :& librairies "GNU C"\\
\hline
libdb4.2 :& librairies "Berkeley v4.2 Database"\\
\hline
libgcrypt11 :& librairies cryptographiques LGPL\\
\hline
libgnutls11 :& librairies GNU TLS\\
\hline
libgpg-error0 :& librairie pour erreurs/messages composants GnuPG\\
\hline
libiodbc2 :& gestion pilote iODBC\\
\hline
libltdl3 :& librairie libltdl (wrapper dlopen pour GNU libtool)\\
\hline
libsasl2 :& librairies SASL v2\\
\hline
libslp1 :& librairies OpenSLP\\
\hline
libwrap0 :& librairies TCP wrapper de Wietse Venema\\
\hline
zlib1g :& librairies de compression gzip\\
\hline
perl :& fameux language interpr<70>t<EFBFBD> de Larry Wall\\
\hline
\end{tabular}
\end{center}
~\\
\subsection{Configuration}
~\\
Le r<>pertoire \textit{/etc/ldap/schema/} contient les sch<63>mas LDAP disponibles.\\
~\\
Certains sch<63>mas sont pr<70>sents par d<>faut.\\
Il est aussi possible d'en ajouter ou d'en d<>finir manuellement.\\
~\\
\textit{Lien~:} \url{http://www.openldap.org/doc/admin22/schema.html}\\
~\\
\texttt{ldap.conf} est le fichier de configuration pour toutes les applications clientes faisant appel aux biblioth<74>ques OpenLDAP (dans le paquet Debian libldap2). Parmi celles-ci se trouvent, non exhaustivement, Sendmail, Pine, Balsa, Evolution, Gnome Meeting, etc. Voici un exemple de ce fichier~:\\
\begin{verbatim}
BASE dc=evolix,dc=net
URI 127.0.0.1
\end{verbatim}
~\\
\texttt{slapd.conf} est le fichier de configuration pour le d<>mon slapd~:\\
\begin{verbatim}
#modules
modulepath /usr/lib/ldap
moduleload back_bdb
backend bdb
#schemas
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/misc.schema
#options
schemacheck on
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
replogfile /var/lib/ldap/replog
loglevel 0
#base
database bdb
suffix "dc=evolix,dc=net"
directory "/var/lib/ldap"
index objectClass eq
lastmod on
\end{verbatim}
Les donn<6E>es LDAP sont dans le r<>pertoire \texttt{/var/lib/ldap/} sous Debian~:\\
\begin{verbatim}
# ls /var/lib/ldap/
__db.001 __db.003 __db.005 dn2id.bdb log.0000000001
__db.002 __db.004 DB_CONFIG id2entry.bdb objectClass.bdb
\end{verbatim}
\subsection{Gestion des droits}
Pour g<>rer les droits d'acc<63>s <20> l'annuaire LDAP, on <20>crit des r<>gles dites ACL (Access Control List) dans le fichier de configuration pour le d<>mon slapd \textit{slapd.conf}. Voici un exemple~:\\
\begin{verbatim}
access to attribute=userPassword
by dn="cn=admin3,dc=evolix,dc=net" write
by anonymous auth
by self write
by * none
access to dn.children="ou=Clients,dc=evolix,dc=net"
by dn.regex="cn=admin,ou=Clients,dc=evolix,dc=net" write
by dn.children="ou=People,dc=evolix,dc=net" write
by users none
by * none
access to *
by dn.regex="cn=admin,dc=evolix,dc=net" write
by users read
by * none
# Administrateur "en dur" (voir slappasswd)
rootdn "cn=admin2,dc=evolix,dc=net"
rootpw {SSHA}ez1NjoyNPknjuKrORzXpem16h/tGgee7
\end{verbatim}
Remarquons qu'on peut utiliser un administrateur "en dur" (\texttt{rootdn} dans le fichier \texttt{slapd.conf}) qui aura alors un acc<63>s <20> toutes les ressources (les lignes lui attribuant des droits sont inutiles). Mais on peut tout <20> fait utiliser un utilisateur LDAP classique~!
~\\
Pour <20>crire des r<>gles ACL, on pr<70>cise donc une entit<69> LDAP et ensuite on pr<70>cise des droits pour des entit<69>s LDAP~:
\begin{verbatim}
access to dn.<scope-style>=<DN> attrs=[attributs]
by <entit<69> LDAP> <droit LDAP>
\end{verbatim}
Lorsque l'on fait une op<6F>ration sur une certaine entit<69> de l'annuaire LDAP, les droits sont d<>termin<69>s par le premier entit<69> LDAP rencontr<74>. Ainsi, on pr<70>cisera toujours les droits par d<>faut <20> la fin.\\
~\\
Exemple typique d'une r<>gle ACL~:
\begin{verbatim}
access to dn.children="ou=Clients,dc=evolix,dc=net" attrs=telephoneNumber
by dn.regex="cn=admin,ou=Clients,dc=evolix,dc=net" write
by dn.children="ou=People,dc=evolix,dc=net" write
by users read
by * none
\end{verbatim}
Droits LDAP~:
\begin{verbatim}
none =0 no access
auth =x needed to bind
compare =cx needed to compare
search =scx needed to apply search filters
read =rscx needed to read search results
write =wrscx needed to modify/rename
\end{verbatim}
Entit<EFBFBD>s LDAP~:
\begin{verbatim}
* All, including anonymous and authenticated users
anonymous Anonymous (non-authenticated) users
users Authenticated users
self User associated with target entry
dn[.<basic-style>]=<regex> Users matching a regular expression
dn.<scope-style>=<DN> Users within scope of a DN
\end{verbatim}
\begin{verbatim}
dn[.<basic-style>]= dn.regex, dn.exact
dn.<scope-style> = dn.base, dn.one, dn.subtree, dn.children
\end{verbatim}
On peut utiliser une liste d'attributs en ajoutant attr=<attributs>\\
On peut utiliser un filtre en ajoutant filter=<filtre>\\
Exemple~:
\begin{verbatim}
to dn.one="ou=People,dc=evolix,dc=net" filter=(gidNumber=2000)
\end{verbatim}
Attention la syntaxe du fichier \texttt{slapd.conf} est importante~!
Par exemple, il ne faut pas ins<6E>rer de commentaires dans les r<>gles ACL.
Ainsi l'exemple suivant est non valable~:
\begin{verbatim}
access to *
# commentaires
by * none
\end{verbatim}
\textit{Lien~:}
\url{http://www.openldap.org/doc/admin22/slapdconfig.html\#Access\%20Control}
\subsection{Utilisation}
On cr<63>e le domaine et <20>ventuellement son administrateur (si non pr<70>sent).\\
<EFBFBD> noter que sous Debian, cette op<6F>ration est automatiquement faite <20> l'installation (questions pos<6F>es via debconf)\\
~\\
Contenu du fichier \texttt{domaine.ldif}~:\\
\begin{verbatim}
dn: dc=evolix, dc=net
objectclass: top
objectclass: dcObject
objectClass: organization
o: exemple
dc: evolix
description: LDAP Evolix
dn: cn=admin,dc=evolix,dc=net
objectclass: organizationalRole
cn: admin
\end{verbatim}
\begin{verbatim}
# ldapadd -x -h solaris -D "cn=admin2,dc=evolix,dc=net" -W -f domaine.ldif
Enter LDAP Password:
adding new entry "dc=evolix,dc=net"
adding new entry "cn=admin2,dc=evolix,dc=net"
\end{verbatim}
~\\
On cr<63>e ensuite un annuaire.\\
~\\
\texttt{create.ldif}~:\\
\begin{verbatim}
dn: ou=annuaire,dc=evolix,dc=net
objectClass: organizationalUnit
ou: annuaire
description: Annuaire Evolix
\end{verbatim}
\begin{verbatim}
# ldapadd -x -D "cn=admin2,dc=evolix,dc=net" -W -f create.ldif
Enter LDAP Password:
adding new entry "ou=annuaire, dc=evolix, dc=net"
\end{verbatim}
~\\
\textbf{Remarque} : il est conseill<6C> d'utiliser \texttt{slapaddd -x -D [...] fichier.ldif plutot que slapdadd < fichier.ldif} afin d'<27>viter des erreurs de syntaxes.\\
<EFBFBD>ventuellement pour des fichiers LDIF importants, la deuxi<78>me m<>thode est plus rapide.\\
On remplit l'annuaire avec des donn<6E>es. Par exemple, avec le fichier \texttt{entree.ldif}~:\\
~\\
\begin{verbatim}
dn: cn=Gregory, ou=annuaire, dc=evolix, dc=net
objectClass: person
objectClass: inetOrgPerson
cn: Gregory
sn: reg
telephoneNumber: 06 98 86 00 00
\end{verbatim}
\begin{verbatim}
ldapadd -x -D "cn=admin2,dc=evolix,dc=net" -W -f entree2.ldif
\end{verbatim}
Dans cet exemple, on utilise le mot de passe "en dur" dans le fichier \texttt{slapd.conf}.\\
~\\
On peut <20>galement utiliser~:
\begin{verbatim}
# slapadd < entree.ldif
\end{verbatim}
~\\
Pour une recherche dans la table, on peut utiliser le client \texttt{ldapsearch}. Par exemple~:\\
\begin{verbatim}
$ ldapsearch -x -b "ou=annuaire,dc=evolix,dc=net" -D \
"cn=admin2,dc=evolix,dc=net" -W -h 192.168.1.5
\end{verbatim}
Quelques options disponibles~:
\begin{verbatim}
-L : renvoie les r<>sultat au format LDIFv1
-LL : d<>sactive les commentaires
-LLL : d<>sactive l'affichage de la version de LDIF
-h <host> : permet de se connecter <20> un serveur distant
(par d<>faut, il s'agit de localhost)
\end{verbatim}
~\\
Pour faire des modifications en mode console, on peut utiliser un \texttt{ldapmodify}. Par exemple, prenons le fichier \texttt{modif.ldif}~:
\begin{verbatim}
dn: cn=Gregory, ou=annuaire, dc=evolix, dc=net
changetype: modify
replace: telephoneNumber
telephoneNumber: 04 98 86 00 00
\end{verbatim}
Au lieu de sp<73>cifier \texttt{remplace:}, on peut mettre \texttt{add:} (il est possible de mettre plusieurs valeurs pour le m<>me atribut) ou \texttt{delete:} (bien s<>r sans mettre de valeur pour l'attribut supprim<69>).\\
On peut ensuite effectuer effectivement les modifications~:
~\\
\begin{verbatim}
$ ldapmodify -x -D "cn=admin2,dc=evolix,dc=net" -W -f /tmp/modif.ldif
\end{verbatim}
On notera que diverses informations sur les changements sont retenues si l'option \texttt{lastmod on} est pr<70>sente dans le fichier \texttt{slapd.conf}~: la date de modification (\texttt{modifyTimestamp}), l'auteur de la modification (\texttt{modifiersName}), etc.\\
~\\
Pour la suppression, on peut <20>galement proc<6F>der en utilisant un fichier LDIF. Par exemple, voici un fichier \texttt{suppr.ldif}~:
\begin{verbatim}
cn=Gregory, ou=annuaire, dc=evolix, dc=net
\end{verbatim}
Les modifications effectives seront faites par la commande \texttt{ldapdelete}~:
\begin{verbatim}
$ ldapdelete -x -D "cn=root,dc=evolix,dc=net" -W -f /tmp/suppr.ldif
\end{verbatim}
On peut <20>galement faire directement~:
\begin{verbatim}
$ ldapdelete -x -D "cn=admin2,dc=evolix,dc=net" -W \
"cn=Gregory,ou=annuaire, dc=evolix, dc=net"
\end{verbatim}
~\\
Bien s<>r, toutes ces op<6F>rations peuvent <20>tre automatis<69>es <20> l'aide Shellscripts ou bien <20> l'aide d'autres clients en Perl, PHP, Java... (voir ci-apr<70>s)
\subsubsection{Exemples d'utilisation}
~\\
\textbf{Carnet d'adresses}\\
~\\
Pour une utilisation en tant que carnet d'adresses, on peut se connecter gr<67>ce <20> des clients mail comme Outlook, Mozilla-Thunderbird, etc.\\
~\\
\textbf{Comptes Unix}\\
~\\
L'utilisation en tant qu'annuaire d'utilisateurs/mots de passe peut se faire sous Linux en utilisant la librairie NSS (Name Service Switch)\footnote{\url{http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html}} et PAM (Pluggable Authentication Modules)\footnote{\url{http://www.kernel.org/pub/linux/libs/pam/}}.\\
~\\
Sous Debian GNU/Linux, on fera~:
\begin{verbatim}
2012-05-21 16:07:10 +02:00
# apt-get install ldap-utils libnss-ldap libpam-ldap
\end{verbatim}
Pour utiliser notre annuaire en plus des comptes UNIX classiques, on pr<70>cisera dans le fichier \texttt{/etc/nsswitch.conf}~:
\begin{verbatim}
passwd: compat ldap
group: compat ldap
shadow: compat ldap
\end{verbatim}
~\\
On pr<70>cise les param<61>tres de l'annuaire LDAP dans le fichier \texttt{/etc/libnss-ldap.conf}~:
\begin{verbatim}
host IP_serveur_LDAP
base dc=evolix,dc=net
ldap_version 3
#binddn cn=unix,dc=evolix,dc=net
#bindpw XXX
#rootbinddn cn=adminunix,dc=evolix,dc=net
\end{verbatim}
Attention, ces fichiers doivent <20>tre lisibles par tous les utilisateurs. Si l'on doit pr<70>ciser \texttt{binddn} et \texttt{bindpw}, on prendra bien garde <20> ce que l'utilisateur LDAP pr<70>cis<69> ne puisse acc<63>der aux donn<6E>es LDAP utiles uniquement en lecture. Pour \texttt{root} on peut pr<70>ciser un utilisateur LDAP diff<66>rent gr<67>ce <20> la directive \texttt{rootbinddn} et le mot de passe sera stock<63> dans le fichier \texttt{/etc/ldap.secret} accessible en lecture uniquement <20> \texttt{root}.\\
On v<>rifiera que cela fonctionne correctement en faisant~:\\
\begin{verbatim}
$ getent passwd
\end{verbatim}
Ensuite, pour pouvoir utiliser ces donn<6E>es <20> partir d'applications, on modifie le fichier \texttt{/etc/pam\_ldap.conf} qui est de syntaxe similaire au fichier \texttt{libnss-ldap.conf}~:\\
\begin{verbatim}
host IP_serveur_LDAP
base dc=evolix,dc=net
ldap_version 3
#binddn cn=unix,dc=evolix,dc=net
#bindpw XXX
#rootbinddn cn=adminunix,dc=evolix,dc=net
pam_password crypt
\end{verbatim}
~\\
Afin d'optimiser less requ<71>tes les plus fr<66>quentes, on indexe les valeurs qui vont <20>tre demand<6E>es le plus souvent. Dans le fichier \texttt{slapd.conf}~:
\begin{verbatim}
index uidNumber eq
index gidNumber eq
index memberUid eq
\end{verbatim}
Et on doit ensuite le faire prendre en compte <20> OpenLDAP en utilisant la commande \texttt{slapindex}~:\\
\begin{verbatim}
# slapindex -f slapd.conf && /etc/init.d/slapd restart
\end{verbatim}
On peut <20>galement installer \texttt{nscd} (Name Service Cache Daemon) qui utilise un syst<73>me de cache utilisateur afin d'optimiser les requ<71>tes vers un annuaire. Notons qu'il faut prendre gare au cache de \texttt{nscd} lors de changement (on devra souvent relancer \texttt{nscd}).\\
~\\
\textbf{Postfix}\\
~\\
Les bases de donn<6E>es d'utilisateurs et de leurs param<61>tres d'un serveur de messagerie <20>lectronique peuvent <20>tre stock<63>s dans une base de donn<6E>es externe et notamment un annuaire LDAP.\\
~\\
Dans le fichier \texttt{main.cf} de Postfix, on utilisera une configuration type~:\\
\begin{verbatim}
alias_maps = [autres bases] ldap:ldapbla
ldapbla_server_host = [serveur ldap]
ldapbla_search_base = [dn de base]
ldapbbla_result_attribute = [type de champs <20> chercher]
#ldapaliases_bind = yes
#ldapaliases_bind_dn = cn=postfix,dc=evolix,dc=net
#ldapaliases_bind_pw = XXX
ldapaliases_query_filter = (mail=%s)
ldapaliases_result_attribute = uid
ldapaliases_debuglevel = 0
\end{verbatim}
Par d<>faut, Postfix regarde le(s) attribut(s) \texttt{mailacceptinggeneralid} pour d<>terminer <20> qui le mail est destin<69> (on peut sp<73>cifier un mail "entier" ce qui permet de diff<66>rencier \textit{alias@domain1.tld} de \textit{alias@domain1.tld}). Ensuite, il regarde le(s) attribut(s) \texttt{maildrop} pour d<>terminer <20> qui distribuer le mail. On change cela gr<67>ce aux directives \texttt{query\_filter} et \texttt{result\_attribute} dans Postfix.
On peut aussi pr<70>ciser un nom de fichier o<> l'on mettra ces directives. Par exemple~:
\begin{verbatim}
alias_maps = [autres bases] ldap:/etc/postfix/ldap-aliases.cf
\end{verbatim}
Dans le fichier \texttt{/etc/postfix/ldap-aliases.cf} on mettra les m<>mes directives que celles pr<70>cis<69>es ci-dessus sans le suffixe \textit{ldapbla\_}.\\
~\\
Pour notre exemple, on aura des entr<74>es LDAP ressemblant <20>~:\\
\begin{verbatim}
dn: uid=pnom,[dn de base]
objectClass: inetOrgPerson
objectClass: inetLocalMailRecipient
objectClass: posixAccount
sn: Nom
givenName: Prenom Nom
mail: pnom@domain.tld
mail: prenom.nom@domain.tld
cn: Prenom Nom
displayName: Prenom Nom
uid: pnom
userPassword: XXXX
uidNumber: 1006
gidNumber: 1000
homeDirectory: /home/pnom/
\end{verbatim}
Il est aussi envisageable d'avoir des entr<74>es correspondant uniquement <20> des aliases (et non rattach<63>s <20> un utilisateur) et notamment pr<70>ciser un alias de collecte pour un domaine (\texttt{mailacceptinggeneralid: @domain.tld}).\\
~\\
%http://archives.neohapsis.com/archives/postfix/1999-q4/1358.html
\textbf{Apache}\\
~\\
On peut utiliser l'authentification Apache avec un annuaire OpenLDAP. Il existe plusieurs modules pour utiliser LDAP avec Apache. Pour Apache2, un module \textit{mod\_auth\_ldap} est int<6E>gr<67> par d<>faut\footnote{\url{http://httpd.apache.org/docs-2.0/mod/mod\_auth\_ldap.html}}. Voici un exemple de configuration~:
\begin{verbatim}
AuthName "Acces Prive"
AuthType Basic
AuthLDAPEnabled on
AuthLDAPURL ldap://127.0.0.1/ou=people,dc=evolix,dc=net?uid?one
AuthLDAPAuthoritative on
require valid-user
\end{verbatim}
\textbf{Diverses applications}\\
~\\
De nombreuses applications permettent d'utiliser une base OpenLDAP pour le stockage de donn<6E>es et/ou l'authentification. Typiquement, une application comme Egroupware permet l'utilisation d'une base OpenLDAP pour l'authentification des utilisateurs et pour le stockage des contacts. Plus globalement, un annuaire LDAP est souvent utilis<69> comme un serveur d'authentification~: toutes les applications d'une structure l'utilisent pour authentifier les utilisateurs. Centraliser l'authentification offre de nombreux avantages~: un mot de passe identique pour toutes les applications, facilit<69> d'administration pour g<>rer ajout/changement, etc. Par contre, le serveur OpenLDAP est dans ce cas extr<74>mement critique car si il est d<>faillant, toutes les applications peuvent <20>tre inutilisables~! Ainsi, il peut <20>tre important d'avoir une politique de sauvegarde et de tol<6F>rance de panne.
\subsection{Utilisation avec TLS}
Afin de s<>curiser les connexions entre le client et le serveur (chiffrement et authentification), on peut utiliser TLS (Transport Layer Security). TLS utilise des certificats X.509. Il peut <20>tre essentiel de ne pas transporter des donn<6E>es non chiffr<66>es surtout lorsqu'un serveur OpenLDAP est utilis<69> en tant que serveur d'authentification. Ainsi, si on utilise LDAP en mode classique, les mots de passe circulent en clair~!\\
~\\
Pour utiliser un certificat sur le serveur OpenLDAP, il nous faut obtenir un certificat X.509 et une cl<63> priv<69>e. Selon la politique de s<>curit<69> en place au sein de sa structure, on utilisera un certificat sign<67> par une autorit<69> de certification ou bien g<>n<EFBFBD>r<EFBFBD> par une PKI (Public Key Infrastructure) interne. On peut <20>galement g<>n<EFBFBD>rer un certificat auto-sign<67>.\\
~\\
On rappelle la proc<6F>dure de g<>n<EFBFBD>ration d'un certificat auto-sign<67>~:\\
~\\
On cr<63>e une "demande" de certificat en se basant sur des param<61>tres al<61>atoires ainsi qu'une cl<63> priv<69>e \texttt{privkey.pem} prot<6F>g<EFBFBD>e par un mot de passe~:
\begin{verbatim}
$ openssl req -new > demande.csr
\end{verbatim}
Si l'on veut supprimer ce mot de passe de protection (utile dans le cas d'un serveur), on ajoute l'argument \texttt{-out cleprivee.pem} et l'on obtient une cl<63> priv<69>e \texttt{cleprivee.pem} non prot<6F>g<EFBFBD>e~:
\begin{verbatim}
$ openssl rsa -in privkey.pem -out cleprivee.pem
\end{verbatim}
Enfin, on g<>n<EFBFBD>re le certificat bas<61> sur la demande et sign<67> par la cl<63> priv<69>e~:
\begin{verbatim}
$ openssl x509 -in demande.csr -out certificat.pem -req -signkey
cleprivee.pem -days 365
\end{verbatim}
On peut ensuite ajouter les lignes suivantes dans le fichier \texttt{slapd.conf}~:
\begin{verbatim}
TLSCertificateFile /path/to/certs/certificat.pem
TLSCertificateKeyFile /path/to/certs/cleprivee.pem
\end{verbatim}
On peut ensuite red<65>marrer le serveur OpenLDAP.\\
~\\
Du c<>t<EFBFBD> du client, il faut poss<73>der le certificat pour pouvoir se connecter au serveur avec TLS. On veillera <20> utiliser un moyen s<>r pour transporter le certificat serveur jusqu'au client afin d'assurer <20>galement l'authentification lors de la connexion. Pour se connecter avec le client console (paquet \textit{ldap-utils}), on cr<63>e un fichier \texttt{~/.ldaprc} qui contiendra le chemin vers le certificat serveur~:
\begin{verbatim}
TLS_CACERT /path/to/cert/certificat.pem
\end{verbatim}
On peut ensuite se connecter en utilisant l'option \texttt{-ZZ}. Par exemple~:
\begin{verbatim}
$ ldapsearch -x -b "dc=formations,dc=evolix,dc=fr" -D \
"cn=admin,dc=formations,dc=evolix,dc=fr" -LL uid -h \
ldap.formations.evolix.fr -ZZ -W
\end{verbatim}
On note qu'il est obligatoire d'utiliser le nom de domaine du serveur pr<70>sent dans le certificat. Sinon la connexion en TLS est impossible~!\\
~\\
De m<>me, on peut utiliser TLS avec des clients LDAP.\\
\newpage
\subsection{Annuaires distribu<62>s}
\subsubsection{Liens entre annuaire}
Le but est de lier diff<66>rentes branches d'annuaires distincts. Les liaisons possibles sont le service referral (apparu dans la norme LDAPv3) et le cha<68>nage de donn<6E>es (qui ressemble <20> des requ<71>tes DNS r<>cursives).
Pour le service referral, cela consiste <20> un serveur \texttt{example.com} de d<>l<EFBFBD>guer une branche, par exemple \texttt{dc=myref,dc=example,dc=com}, <20> un autre serveur, par exemple \texttt{bis.example.com}.
\texttt{example.com} comportera une entr<74>e du type~:
\begin{verbatim}
dn: dc=myref,dc=example,dc=com
objectClass: referral
objectClass: extensibleObject
dc: myref
ref: ldap://bis.example.com/dc=myref,dc=example,dc=com
\end{verbatim}
\texttt{bis.example.com} pourra <20>galement pointer vers \texttt{example.com} pour les entr<74>es non d<>finies. Dans ce cas, on pr<70>cisera dans le fichier \texttt{slapd.conf}~:
\begin{verbatim}
referral ldap://example.com/
\end{verbatim}
Il faut utiliser l'option \texttt{-M} pour contr<74>ler ces informations sans "suivre" les referral. Par exemple, pour supprimer un referral~:
\begin{verbatim}
ldapdelete -M -x -D "cn=admin,dc=example,dc=com" -W "dc=myref,dc=example,dc=com"
\end{verbatim}
\subsubsection{R<EFBFBD>plication}
Dans cette architecture, il y a un serveur OpenLDAP ma<6D>tre et un serveur OpenLDAP esclave. La gestion des r<>plications est faite gr<67>ce au daemon slurpd (Standalone LDAP Update Replication Daemon) sur le serveur OpenLDAP ma<6D>tre.~\\
\textit{Lien~:}
\url{http://www.openldap.org/doc/admin22/config\_repl.gif}\\
~\\
Sur le serveur ma<6D>tre~:\\
~\\
\texttt{slapd.conf}\\
\begin{verbatim}
replogfile /var/lib/ldap/replog
replica uri=ldap://ldap2.evolix.net:389
binddn="cn=Replicator,dc=evolix,dc=net"
bindmethod=simple credentials=secret
\end{verbatim}
~\\
Sur le serveur esclave~:\\
~\\
\texttt{slapd.conf}
\begin{verbatim}
rootdn "cn=Replicator,dc=evolix,dc=net"
rootpw {SSHA}UflDkKSi+YdiQ+5OUrM1uJsJKZDSO++W
updatedn "cn=Replicator,dc=evolix,dc=net"
updateref "ldap://ldap.evolix.net"
\end{verbatim}
Les modifications LDAP sont stock<63>es dans le replogfile qui est vid<69> par slurpd. Si le serveur esclave est disponible, elles lui sont ensuite envoy<6F>s. Si aucun acc<63>s en <20>criture n'est possible, les modificatiosn sont rejet<65>s et conserv<72>s dans des fichiers \texttt{.rej}. <20> noter que la premi<6D>re fois les donn<6E>es LDAP doivent <20>tre import<72>s manuellement sur le serveur esclave.
\subsection{Clients OpenLDAP}
~\\
Il existe plusieurs logiciels clients pour visualiser, ins<6E>rer, modifier, supprimer, etc. des donn<6E>es dans une base OpenLDAP~:
~\\
\begin{itemize}
\item \textbf{ldap-utils} commandes en mode console (ldapadd, ldapcompare, ldapdelete, ldapmodify, ldapmodrdn, ldappasswd, ldapsearch, ldapwhoami)
\item \textbf{LDAP Browser/Editor} logiciel graphique en Java permettant
de visualiser, modifier et rechercher ais<69>ment. Import et export au
format LDIF sont pratiques.\\
\textit{Lien~:} \url{http://www-unix.mcs.anl.gov/~gawor/ldap/}
\item \textbf{GQ} logiciel graphique en GTK permettant de visualiser ais<69>ment.\\
\textit{Lien~:} \url{http://biot.com/gq/}
\item \textbf{PhpLDAPadmin} interface web en PHP permettant d'effectuer de nombreuses op<6F>rations ais<69>ment.\\
\textit{Lien~:} \url{http://phpldapadmin.sourceforge.net/}
\end{itemize}
% voir le package Debian 'cpu'
% http://www.urec.cnrs.fr/cours/Applis/x500/
% http://www.sysium.com/ldap.html