[ Présentation | format de la base et définitions ( Le Directory Information Tree , Les attributs , Les classes d'objet , Les schémas ) | Installation d'OpenLDAP    ( Présentation , installation ) | Mettre en place son schéma d'annuaire ( Mise en place des classes d'objet , choix du suffixe ) | Configuration du serveur LDAP  | Lancement du serveur | Configurer une connexion chiffrée avec SSL | Ajouter un enregistrement | Rechercher un enregistrement | Modifier un enregistrement ( Rajouter un attribut à un enregistrement , modifier un attribut , supprimer un attribut , supprimer un enregistrement) | Passer en connexion chiffrée ]

Dernière modification 3 février 2017

Installation de l'annuaire OpenLDAP

Applis spécifiques

(ce document est téléchargeable au format pdf dans la section download)

Présentation

LDAP est un protocole basé sur TCP/IP qui permet de partager des bases de données d'information sur un réseau interne (intranet) ou externe (internet). Ces bases de données sont appelées annuaire électronique (Directory en anglais), elles peuvent contenir tout type d'informations, des informations sur les personnes, à des données systèmes. Qui dit base de données, dit recherche, il est donc possible de faire des recherches dans la base en employant plusieurs critères, mais aussi bien sûr de la modifier, mais contrairement à un SGBD, un annuaire est très rapide en lecture, mais l'est beaucoup moins en écriture, en effet comme un annuaire est plutôt lu que modifier il a été optimisé pour la lecture et ne possède pas les mécanismes de transaction complexe que les SGBD possèdent pour traiter de gros volumes de données.
Le LDAP ou Lightweight Directory Access Protocol est la version TCP/IP du protocole DAP, ce dernier étant le protocole pour accéder au protocole OSI du service d'annuaire X500. Dans un premier temps LDAP s'est contenté d'être l'interface à des annuaires X500, mais maintenant LDAP peut gérer complètement les bases (standalone LDAP).

Si on rentre dans les détails, le protocole LDAP est du type client serveur, le serveur contient la base de données, et le client consulte la base de données, le protocole fournit les bases pour cette communication entre la client et le serveur (normalisée par l'IETF par la RFC2251), et les commandes nécessaires au client pour rechercher, créer, modifier ou effacer des données. LDAP est bien entendu sécurisé pour le transfert et l'accès aux des données, avec des outils de cryptage comme SSL et d'authentification.
Par ailleurs LDAP fournit des outils pour que les serveurs LDAP puissent communiquer entre eux, on a ainsi la possibilité de créer des serveurs miroirs qui pourront se synchroniser, ou de relier simplement les serveurs entre eux, les serveurs redirigeant automatiquement les requêtes qui ne les concernent pas.

Les exemples d'applications de LDAP sont nombreux:
- bases de données d'employés,
- bases de données de produits,
- bases de données pour certaines applis, exemple :
        * toutes les infos contenant les utilisateurs de votre réseau (mot de passe, shell, homedirectory, ...) peuvent être dans la base, on a ainsi beaucoup plus de possibilités qu'un simple fichier /etc/passwd, l'authentification peut donc utiliser LDAP plutôt que passwd ou shadow ou encore NIS. Vos utilisateurs pourront ainsi changer leur mot de passe et certains de leurs attributs à partir d'une interface web.
        * les préférences d'applis ou d'environnement (netscape, environnement graphique KDE, ...) sont sauvegardés dans la base, ainsi l'utilisateur peut passer d'une machine à une autre et retrouver ses préférences.

Cette page est une introduction à LDAP elle ne couvre pas certains aspects comme les liens avec d'autres bases (duplication, miroir, ...), la sécurité (access control, SSL, ...). Elle n'a seulement pour but de mettre en place un serveur LDAP simplement configuré pour que vous puissiez faie vos "premières armes" dans le domaine. Pour plus d'info reportez vous à l'excellente page de Laurent Mirtain .

Pour utiliser une base LDAP à partir de script PHP, voir ma page Apache .

Pour voir comment mettre en place un système d'authentification utilisateurs en utilsant LDAP à la manière de NIS voir mon autre page sur LDAP.

 

[Retour haut de la page ]

Format de la base et définitions

Le Directory Information Tree

Les LDAP standalone utilisent le format de base de données LDBM, ce dernier utilise le modèle hiérarchique comme le système de fichiers UNIX, c'est à dire qu'il s'apparente à un arbre, qu'on appelle DIT (Directory Information Tree). Au sommet de cet arbre se trouve la racine ou suffixe et à chaque noeud de l'arborescence on a un DSE (Directory Service Entry) qui correspond à une entrée de l'annuaire. L'entrée située à la racine est appelé rootDSE (root Directory Specific Entry), qui décrit la structure de l'arborescence (le DIT) ainsi que son contenu.
Chaque entrée est connue de manière unique dans l'arborescence grâce à son dn (Distinguished Name). Le dn indique le chemin à parcourir pour en partant du sommet arriver à l'entrée correspondante. Par exemple pour identifier une personne, on part du pays (fr), puis le nom de domaine (kervao), le groupe de travail et enfin le nom de la personne, l'ensemble de ces paramètres est le dn qui identifie de manière unique une personne.
[Retour haut de la page ]

Les attributs

Chaque entrée peut être considérée comme un objet (au sens C++) possédant donc certains attributs, par exemple si une personne est une entrée, les attributs peuvent être, le nom, le prénom, l'âge, .... On peut aussi définir des attributs obligatoires et d'autres optionnels, en d'autres termes, les attributs obligatoires devront être renseignés mais pas forcément les optionnels. Il existe par ailleurs pour chaque DSE des attributs d'administration qui ne servent qu'au serveur.
[Retour haut de la page ]

Les classes d'objet

On regroupe les objets qui sont du même domaine dans une classe d'object, celle-ci est caractérisée par des attributs obligatoires ou optionnels et un type. Les types de classe d'objet sont:
- type structurel car elle contient des d'objets concrets de l'annuaire (personnes, groupes de personnes, ...),
- type auxiliaire, c'est des classes d'objets qu'on peut créer, pour rajouter des informations (attributs) supplémentaires à des classes d'objet de type structurel déjà existantes. En C++ on dira que la classe auxiliaire dérive d'une classe structurelle,
- type abstraite, c'est les classes d'objet qui existent par défaut et qui n'ont pas de signification concrète, par exemple la classe top est la classe d'objet générique, toutes les autres classes dérivent de cette classe.

Le principe est donc le même qu'en C++, on retrouve une structure arborescente, avec à la racine la classe top, toutes les autres classes d'objet dérivent de cette classe générique, chaque classe hérite des propriétés d'une classe père et possède des attributs supplémentaires par rapport à ce dernier.

Les schémas

Un schéma décrit toutes les règles qu'utilisent le serveur LDAP pour décrire les classes d'objets (attributs, syntaxe, ...).
[Retour haut de la page ]

Installation d'OpenLDAP

Présentation

Il existe de nombreux serveurs LDAP, nous utiliserons OpenLDAP qui comme son nom l'indique est sous licence GPL. Vous avez le choix entre la version packagée par votre distribution ou la dernière version stable 2.4.44 à l'URL http://www.openldap.org.  Ma préférence va vers la recompilation pour avoir une version optimisée et de plus plus récente.

[Retour haut de la page ]

Installation

On vérifie d'abord qu' Openldap n'est pas déjà installé sur votre système en tapant :

rpm -qa | grep -i ldap

On supprime du système les packages contenus dans la liste avec la commande rpm -e nom-du-package (sauf libldap2 qui sert pour de nombreux packages).
Si pour des histoires de dépendance vous n'arrivez pas à tout supprimer ce n'est pas bien grave car par défaut le tarball et les packages ne placent pas les fichiers au même endroit. Lors du lancement du daemon et des exécutables il faut juste faire attention d'appeler le bon exécutable (servez vous de la commande which nom-exe ).

L'archive à récupérer est  openldap-2.4.44.tgz qu'on décompressera en tapant :

tar xvfz openldap-2.4.44.tgz

Cela va nous créer un répertoire openldap-2.4.44. Avant d'aller plus loin il faudra installer (commande urpmi nom-package ) les packages suivants

lib64db5.3-devel
gnutls-devel
lib64sasl2-devel
lib64nss-devel

Puis on tape successivement :

./configure
make


On peut tester maintenant que tout marche bien  en tapant :

cd tests
make

pour installer les binaires de ldap on tapera, en tant que root :

cd ..
make install

Les binaires sont installés par défaut dans /usr/local/sbin et /usr/local/libexec, les fichiers de config dans /usr/local/etc/openldap et les bases dans /usr/local/var/openldap-data. Les biblio vont se trouver sous /usr/local/lib, si ce n'est pas fait, rajouter ce chemin à la fin du fichier /etc/ld.so.conf et tapez

ldconfig

pour changer l'emplacement de tous ces fichiers taper:

configure -help

[Retour haut de la page ]

Mettre en place son schéma d'annuaire

Mise en place des classes d'objet

Le fichier de conf slapd.conf fait appel à /usr/local/etc/openldap/schema/core.schema qui décrit les classes d'objet. Voilà un exemple avec la classe "person"

objectclass ( 2.5.6.6 NAME 'person'
        DESC 'RFC2256: a person'
        SUP top STRUCTURAL
        MUST ( sn $ cn )
        MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )

MUST correspond au attributs obligatoires et MAY à ceux facultatifs
objectClass est le nom de la classe qui descend elle même de la classe top
sn correspond à surname (nom)
cn correspond à common name (prénom nom)
Je vous laisse déviner la signification des autres attributs.

On voit qu'il est nécessaire de fournir les attributs sn (surname) et cn (common name), sont facultatifs le mot de passe (userPassword), le numéro de téléphone (telephoneNumber ), les liens (seeAlso) et la description.

Les attributs sont définis dans le même fichier, la syntaxe est la suivante pour telephoneNumber par exemple :

attributetype ( 2.5.4.20 NAME 'telephoneNumber'
        DESC 'RFC2256: Telephone Number'
        EQUALITY telephoneNumberMatch
        SUBSTR telephoneNumberSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )

Je vous présenterai la syntaxe plus tard, on peut dans un premier temps se limiter aux attributs disponibles. Pour créer une classe d'objet breizhPerson dérivant de person, disposant de l'attribut obligatoire title en plus et des arguments facultatifs ou (groupe de travail) et l (localistation). On tapera dans le fichier core.schema juste après la définition de la classe person

objectclass ( 2.5.6.6.2 NAME 'breizhPerson' SUP person STRUCTURAL
    MUST ( title )
    MAY ( ou $ l ) )

Vous noterez le nombre 2.5.6.6.2, ce nombre doit être unique dans le fichier, il dérive directement du numéro de la classe objet person qui a pour numéro 2.5.6.6. Il est évident que comme breizhPerson dérive de person, les attributs sn et cn sont aussi obligatoires.

 

[Retour haut de la page ]

Choix du suffixe

Le rootDSE ou suffixe correspond à l'entrée tout en haut de l'arbre (DIT) de l'annuaire, on utilise généralement le nom de domaine, avec la syntaxe suivante  dc=kervao, dc=fr  pour le domaine kervao.fr (dc
correspond à Domain Component).
[Retour haut de la page ]

Configuration du serveur LDAP

On va créer un annuaire LDAP pour votre domaine privé kervao.fr. On doit modifier les fichiers slapd.conf et ldap.conf se trouvant sous /usr/local/etc/openldap.Voilà pour le fichier de configuration slapd.conf

# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.8.8.4 2000/08/26 17:06:18
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#

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

# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral   ldap://root.openldap.org
# le chemin est différent avec une install avec package

pidfile     /usr/local/var/slapd.pid
argsfile    /usr/local/var/slapd.args

# Load dynamic backend modules:
# modulepath    /usr/local/libexec/openldap
# moduleload    back_ldap.la
# moduleload    back_ldbm.la
# moduleload    back_passwd.la
# moduleload    back_shell.la

# slapd est bavard, pour le limiter aux messages critiques on mettre none

loglevel none

# Sample security restrictions
#       Require integrity protection (prevent hijacking)
#       Require 112-bit (3DES or better) encryption for updates
#       Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64

#######################################################################
# database definitions
#######################################################################

database        bdb
suffix          "dc=kervao,dc=fr"
rootdn          "cn=Manager,dc=kervao,dc=fr"

#mot de passe en clair, on verra plus loin comment le crypter
rootpw          secret

# là où va se trouver la base ldap /var/lib/ldap dans le cas d'une install par package
directory   /usr/local/var/openldap-data

# Indices to maintain
index   objectClass eq

Attention vous devez vous assurer que le répertoire où se trouvera la base LDAP a été créé, par défaut c'est /usr/local/var/openldap-data mais vous pouvez très bien mettre /var/lib/ldap si ça vous chante.

Le fichier ldap.conf peut être vide dans un premier temps voire inexistant.

Le mot de passe de l'administrateur est secret en clair, si ça ne vous convient pas et que vous voulez le crypter, il faudra taper

slappasswd

on saisit son mot de passe

New password:
Re-enter new password:

et voilà le résultat

{SSHA}vNCYRQthN6u3OqcTAJ4lt/9vIhjsFmI

A la place de

rootpw      secret

Dans slapd.conf, vous mettrez donc:

rootpw          {SSHA}vNCYRQthN6u3OqcTAJ4lt/9vIhjsFmI

pour plus de sécurité on crée maintenant un utilisateur et un groupe système ldap

groupadd ldap
useradd -g ldap -c "slapd demon" -s /sbin/nologin -d /tmp ldap

on le rend propriétaire du fichier de configuration et de la base ldap en tapant

chown ldap:ldap /usr/local/etc/openldap/slapd.conf
chown -fR ldap:ldap /usr/local/var/openldap-data
chown -fR ldap:ldap /usr/local/var/run

maintenant sous /usr/local/var/openldap-data on tapera

cp DB_CONFIG.example DB_CONFIG
chown ldap:ldap DB_CONFIG

[Retour haut de la page ]

Lancement du serveur

La configuration du lancement sous systemd est la suivante. On crée un fichier slapd.service qu'on place sous /usr/lib/systemd/system/ voilà son contenu

[Unit]
Description=OpenLDAP server daemon

[Service]
Type=forking
ExecStart=/usr/local/libexec/slapd -u ldap -g ldap -f /usr/local/etc/openldap/slapd.conf

[Install]
WantedBy=multi-user.target  
 
maintenant pour que le service soit lancé à chaque boot de la machine il faudra taper

systemctl enable slapd.service

voillà le résultat

Created symlink from /etc/systemd/system/multi-user.target.wants/slapd.service to /usr/lib/systemd/system/slapd.service.

pour le lancer il suffit maintenant de taper

systemctl  start slapd.service
 

et pour connaitre son état

systemctl status slapd.service

voilà le résultat

● slapd.service - OpenLDAP server daemon
   Loaded: loaded (/usr/lib/systemd/system/slapd.service; enabled)
   Active: active (running) since sam. 2016-12-24 11:14:52 CET; 27s ago
  Process: 15515 ExecStart=/usr/local/libexec/slapd -u ldap -g ldap -f /usr/local/etc/openldap/slapd.conf (code=exited, status=0/SUCCESS)
 Main PID: 15517 (slapd)
   CGroup: /system.slice/slapd.service
           └─15517 /usr/local/libexec/slapd -u ldap -g ldap -f /usr/local/etc/openldap/slapd.conf

déc. 24 11:14:41 mana.kervao.fr slapd[15515]: @(#) $OpenLDAP: slapd 2.4.44 (Dec 24 2016 11:12:03) $
                                                       olivier@mana.kervao.fr:/usr/local/linux/systeme/openldap-2.4.44/servers/slapd


[Retour haut de la page ]

Connexion chiffrée avec SSL

Pour une connexion chiffrée avec SSL entre le client et le serveur LDAP on a le choix entre :

StartTLS, avec standard LDAP utilise TLS/SSL pour chiffrer les échanges en passant par le port classique de LDAP

ldaps:// une connexion TLS/SSL est initialisée par LDAP sur un port alternatif (par défaut 636).

On préfèrera la première méthode. On va créer maintenant un certificat perso auto signé qui ne marchera que pour mon réseau privé comme j'ai pu le faire pour sendmail et dovecot. On va commencer par se créer un certificat CA, pour cela il faudra avoir installé OpenSSL comme décrit ici, on doit trouver un fichier /usr/local/ssl/misc/CA.sh on modifie la ligne suivante ainsi

if [ -z "$CATOP" ] ; then CATOP=/etc/ssl/CA ; fi

on modifie également deux lignes du fichier /usr/local/ssl/openssl.cnf

dir             = /etc/ssl/CA           # Where everything is kept
dir             = /etc/ssl/CA           # TSA root directory

on tape maintenant :

cd /usr/local/ssl/misc
./CA.sh -newca


voilà le résultat

CA certificate filename (or enter to create)

Making CA certificate ...
Generating a 2048 bit RSA private key
.....................+++
................................................................................................................................................................+++
writing new private key to '/etc/ssl/CA/private/./cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Bretagne
Locality Name (eg, city) []:Brest
Organization Name (eg, company) [Internet Widgits Pty Ltd]:none
Organizational Unit Name (eg, section) []:none
Common Name (e.g. server FQDN or YOUR name) []:mon-serveur.mon-domaine
Email Address []:olivier.hoarau@funix.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:password
An optional company name []:
Using configuration from /usr/local/ssl/openssl.cnf
Enter pass phrase for /etc/ssl/CA/private/./cakey.pem:
Can't open /etc/ssl/CA/index.txt.attr for reading, No such file or directory
140161513776896:error:02001002:system library:fopen:No such file or directory:crypto/bio/bss_file.c:74:fopen('/etc/ssl/CA/index.txt.attr','r')
140161513776896:error:2006D080:BIO routines:BIO_new_file:no such file:crypto/bio/bss_file.c:81:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            c8:26:95:62:b9:b6:85:b2
        Validity
            Not Before: Feb  3 18:31:26 2017 GMT
            Not After : Feb  3 18:31:26 2020 GMT
        Subject:
            countryName               = FR
            stateOrProvinceName       = Bretagne
            organizationName          = none
            organizationalUnitName    = none
            commonName                = mana.kervao.fr
            emailAddress              = olivier.hoarau@funix.org
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                08:27:2D:99:EF:5E:33:6A:EE:37:D8:73:CA:3E:A1:D8:A5:B3:D5:E6
            X509v3 Authority Key Identifier:
                keyid:08:27:2D:99:EF:5E:33:6A:EE:37:D8:73:CA:3E:A1:D8:A5:B3:D5:E6

            X509v3 Basic Constraints:
                CA:TRUE
Certificate is to be certified until Feb  3 18:31:26 2020 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated


Maintenant toujours sous /usr/local/ssl/misc on va générer une clé privée et un certificat pour le serveur LDAP

openssl req -new -nodes -keyout newreq.pem -out newreq.pem
arrows47
voilà le résultat

Generating a 2048 bit RSA private key
...........................+++
............................+++
writing new private key to 'newreq.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Bretagne
Locality Name (eg, city) []:Brest
Organization Name (eg, company) [Internet Widgits Pty Ltd]:none
Organizational Unit Name (eg, section) []:none
Common Name (e.g. server FQDN or YOUR name) []:
mon-serveur.mon-domaine
Email Address []:olivier.hoarau@funix.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:password
An optional company name []:

maintenant on va signer notre certificat avec notre certificat CA maison, on est toujours sous /usr/local/ssl/misc, on tape

./CA.sh -sign

voilà le résultat

Using configuration from /usr/local/ssl/openssl.cnf
Enter pass phrase for /etc/ssl/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            c8:26:95:62:b9:b6:85:b3
        Validity
            Not Before: Feb  3 18:33:32 2017 GMT
            Not After : Feb  3 18:33:32 2018 GMT
        Subject:
            countryName               = FR

on modifie la ligne suivante ainsi            stateOrProvinceName       = Bretagne
            localityName              = Brest
            organizationName          = none
            organizationalUnitName    = none
            commonName                = mana.kervao.fr
            emailAddress              = olivier.hoarau@funix.org
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                0F:E8:A2:53:AA:E2:5D:B9:45:78:95:25:65:48:59:05:C9:9D:AE:A0
            X509v3 Authority Key Identifier:
                keyid:08:27:2D:99:EF:5E:33:6A:EE:37:D8:73:CA:3E:A1:D8:A5:B3:D5:E6

Certificate is to be certified until Feb  3 18:33:32 2018 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            c8:26:95:62:b9:b6:85:b3
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=FR, ST=Bretagne, O=none, OU=none, CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org
        Validity
            Not Before: Feb  3 18:33:32 2017 GMT
            Not After : Feb  3 18:33:32 2018 GMT
        Subject: C=FR, ST=Bretagne, L=Brest, O=none, OU=none, CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b3:8c:8a:7d:e0:15:5e:ea:74:c3:89:ad:65:7b:
                    79:9b:65:3e:86:f3:e0:14:55:a2:e5:57:61:a8:d3:
                    46:a7:7e:2b:3d:d9:9f:25:82:15:f8:13:3d:bd:c0:
                    16:4a:ca:96:93:82:50:6f:02:87:4a:13:ac:17:ac:
                    65:70:88:e0:7f:aa:cb:20:ca:01:bb:82:af:25:b1:
                    72:e9:25:9b:0e:5e:70:2d:f1:49:52:d2:26:65:2b:
                    53:29:70:1f:44:15:76:81:fc:cc:a8:14:12:89:97:
                    04:e9:2f:1d:14:eb:31:25:97:dd:dd:c9:02:ce:f6:
                    1d:f6:f9:36:3d:ba:4b:ed:83:8a:77:48:37:5d:f9:
                    1b:0f:28:fe:ff:c1:cd:56:de:f7:2b:c1:6d:39:55:
                    51:74:ef:00:a3:c9:a9:ae:85:b0:06:04:da:20:af:
                    d9:62:61:1a:2b:c1:65:f0:8c:94:c6:aa:0b:cf:b7:
                    fe:99:14:d4:b3:09:a4:dc:38:4a:92:e9:0e:13:b7:
                    d4:07:03:59:51:69:2a:b7:2e:a1:40:bb:a3:f6:94:
                    d5:43:80:e0:c6:20:dc:6a:83:ae:ec:15:f4:50:e4:
                    8e:89:5e:73:22:59:9e:98:ff:82:c5:da:45:2a:47:
                    59:47:3c:bd:9c:0d:71:12:8c:25:c7:ef:b8:fd:76:
                    2c:71
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                0F:E8:A2:53:AA:E2:5D:B9:45:78:95:25:65:48:59:05:C9:9D:AE:A0
            X509v3 Authority Key Identifier:
                keyid:08:27:2D:99:EF:5E:33:6A:EE:37:D8:73:CA:3E:A1:D8:A5:B3:D5:E6

    Signature Algorithm: sha256WithRSAEncryption
         c3:92:f3:2f:08:55:94:cd:a2:dd:0f:56:91:82:65:40:32:39:
         c0:f2:69:6c:34:0b:44:e6:e6:cf:2c:c3:5e:c3:44:1d:1b:12:
         1e:f4:ec:f1:1c:3e:2b:21:0e:8d:85:01:64:f1:0f:00:f7:3a:
         84:5f:6c:24:91:e1:e9:7a:4e:95:f1:be:07:db:d6:bb:ea:57:
         2b:cd:c0:19:d2:7e:ff:44:e0:cc:2a:20:2d:82:05:19:75:51:
         f2:46:cd:02:d6:da:8c:e6:db:6a:88:85:fe:97:6b:ca:24:56:
         8f:63:ff:f5:ac:c0:99:2a:6e:1f:b5:e1:ad:fb:26:7c:cf:f1:
         3e:27:bb:dc:8b:30:d2:be:99:5c:43:62:c2:df:c9:d4:7f:c1:
         11:8d:09:ea:b9:a4:f4:7c:47:55:77:f1:ae:6e:54:40:f3:3c:
         d9:f6:49:11:b3:4f:3f:2e:8f:51:cf:6a:14:06:da:72:0f:cc:
         da:44:a7:fd:0c:22:b0:be:a9:17:c5:bd:36:13:27:82:35:54:
         81:94:b8:54:84:dd:b6:86:ed:b4:11:0a:4c:94:33:de:dc:4e:
         32:ef:73:0a:36:59:55:70:81:bb:41:5c:05:ae:54:93:47:15:
         86:11:68:bd:d5:51:b3:84:c9:10:c7:49:af:cc:af:5d:0c:48:
         95:fe:49:c1
-----BEGIN CERTIFICATE-----
MIIEEDCCAvigAwIBAgIJAMgmlWK5toWzMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD
VQQGEwJGUjERMA8GA1UECAwIQnJldGFnbmUxDTALBgNVBAoMBG5vbmUxDTALBgNV
BAsMBG5vbmUxFzAVBgNVBAMMDm1hbmEua2VydmFvLmZyMScwJQYJKoZIhvcNAQkB
FhhvbGl2aWVyLmhvYXJhdUBmdW5peC5vcmcwHhcNMTcwMjAzMTgzMzMyWhcNMTgw
MjAzMTgzMzMyWjCBkDELMAkGA1UEBhMCRlIxETAPBgNVBAgMCEJyZXRhZ25lMQ4w
DAYDVQQHDAVCcmVzdDENMAsGA1UECgwEbm9uZTENMAsGA1UECwwEbm9uZTEXMBUG
A1UEAwwObWFuYS5rZXJ2YW8uZnIxJzAlBgkqhkiG9w0BCQEWGG9saXZpZXIuaG9h
cmF1QGZ1bml4Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALOM
in3gFV7qdMOJrWV7eZtlPobz4BRVouVXYajTRqd+Kz3ZnyWCFfgTPb3AFkrKlpOC
UG8Ch0oTrBesZXCI4H+qyyDKAbuCryWxcuklmw5ecC3xSVLSJmUrUylwH0QVdoH8
zKgUEomXBOkvHRTrMSWX3d3JAs72Hfb5Nj26S+2DindIN135Gw8o/v/BzVbe9yvB
bTlVUXTvAKPJqa6FsAYE2iCv2WJhGivBZfCMlMaqC8+3/pkU1LMJpNw4SpLpDhO3
1AcDWVFpKrcuoUC7o/aU1UOA4MYg3GqDruwV9FDkjolecyJZnpj/gsXaRSpHWUc8
vZwNcRKMJcfvuP12LHECAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0E
HxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFA/oolOq
4l25RXiVJWVIWQXJna6gMB8GA1UdIwQYMBaAFAgnLZnvXjNq7jfYc8o+odils9Xm
MA0GCSqGSIb3DQEBCwUAA4IBAQDDkvMvCFWUzaLdD1aRgmVAMjnA8mlsNAtE5ubP
LMNew0QdGxIe9OzxHD4rIQ6NhQFk8Q8A9zqEX2wkkeHpek6V8b4H29a76lcrzcAZ
0n7/RODMKiAtggUZdVHyRs0C1tqM5ttqiIX+l2vKJFaPY//1rMCZKm4fteGt+yZ8
z/E+J7vcizDSvplcQ2LC38nUf8ERjQnquaT0fEdVd/GublRA8zzZ9kkRs08/Lo9R
z2oUBtpyD8zaRKf9DCKwvqkXxb02EyeCNVSBlLhUhN22hu20EQpMlDPe3E4y73MK
NllVcIG7QVwFrlSTRxWGEWi91VGzhMkQx0mvzK9dDEiV/knB
-----END CERTIFICATE-----
Signed certificate is in newcert.pem

on copie maintenant les fichiers aux endroits qui vont bien (répertoire à créer éventuellement préalablement)

cp newcert.pem /etc/ssl/public/ldapcrt.pem
cp newreq.pem /etc/ssl/ldap/ldapkey.pem


chown ldap:ldap /etc/ssl/ldap/ldapkey.pem


l'utilisateur ldap doit en être propriétaire

chwon ldap:ldap /etc/ssl/ldap/ldapkey.pem

ça nous évitera une erreur du genre
 

slapd[5803]: main: TLS init def ctx failed: -1

maintenant on va modifier le fichier /usr/local/etc/openldap/slapd.conf on rajoute les lignes suivantes

TLSCACertificateFile /etc/ssl/CA/cacert.pem
TLSCertificateFile /etc/ssl/public/ldapcrt.pem
TLSCertificateKeyFile /etc/ssl/ldap/ldapkey.pem

# cette directive c'est pour ne pas vérifier le certificat du client
TLSVerifyClient never

maintenant sur les postes clients  on copiera le certificat signé du serveur LDAP où bon vous semble (dans mon exemple sous /etc/pki/tls/certs/). Il doit avoir les droits 644

chmod 644 ldapcrt.pem

cela évite l'erreur suivante

TLS: could not load verify locations (file:`/etc/openldap/cacerts/ldapcrt.pem',dir:`/etc/openldap/cacerts').
TLS: error:02001002:system library:fopen:No such file or directory bss_file.c:175
TLS: error:2006D080:BIO routines:BIO_new_file:no such file bss_file.c:182
TLS: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib by_file.c:256


On édite le fichier
/usr/local/etc/openldap/ldapd.conf et on modifie ainsi

# SSL/TSL configuration. With CA-signed certs, TLS_REQCERT should be
# "demand", with the CA certificate accessible
#TLS_REQCERT    ([demand],never,allow,try)
# We ship with allow by default as some LDAP clients (e.g. evolution) have
# no interactive SSL configuration
# on doit mettre allow si le certificat a été signé de manière maison, sinon ça sera demand
TLS_REQCERT     allow

# CA Certificate locations
# Use the default self-signed cert generated by openldap-server postinstall
# by default
TLS_CACERT      /etc/pki/tls/certs/ldapcrt.pem

on relance slapd

systemctl stop sladp
systemctl start slapd

Voir par ici pour tester la config.



Ajouter un enregistrement

Vous avez différent moyen d'ajouter des données à l'annuaire, pour une meilleure compréhension on va d'abord aborder la méthode manuelle. Pour ajouter des données au serveur LDAP vous devez vous fournir un fichier au format LDIF (pour LDAP Directory Interchange Format), le format est un format texte facilement lisible au contraire du format interne de l'annuaire. Voici un exemple de fichier LDIF, à noter que:
- chaque enregistrement dans le fichier est séparé du précédent et du suivant par une ligne vierge,
- les espaces sont pris en compte. ATTENTION, il est très important qu'il n'y ait aucun espace en fin de ligne. Dans ce cas vous risqueriez d'obtenir une erreur du style

ldap_add: Invalid syntax (21)
        additional info: objectClass: value #0 invalid per syntax

La syntaxe du format LDIF est la suivante:

dn: description du distinguished name
objetclass: classe d'objet d'origine
...
objetclass: classe d'objet dérivée
type attribut: valeur
...

On va par exemple utiliser la classe breizPerson définie plus haut pour décrire une nouvelle personne Veronique Hoarau qu'on va rajouter dans l'annuaire. Elle appartient au service (organizationalUnit) staff, ce même service appartenant à l'organisation kervao.fr
Soit le fichier entree.ldif

dn:     dc=kervao, dc=fr
objectClass: dcObject
objectClass:    organization
dc:     kervao
o:      kervao.fr

dn: ou=staff, dc=kervao, dc=fr
objectclass:    organizationalUnit
ou: staff

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
objectclass: person
objectclass: breizhPerson
cn: Veronique Hoarau
sn: Hoarau
title: madame

Quelques commentaires, le premier groupe correspond à la définition de votre organisation, le deuxième à celui du groupe de travail (organizationalUnit) et le dernier à la personne. Celle-ci est définie par son dn (Distinguished Name), on part du sommet bz (suffixe du nom de domaine), puis le nom de domaine, le groupe de travail et enfin la personne. L'arbre (DIT) pourrait ressembler à ça:

 

                                                                                                                         dc=fr
                                                                                                                            |
                                                                                                                     dc=kervao
                                                                                                                            |
                                                          ------------------------------------------------------------------------------------------------------------
                                                            |                                              |                                                              |                                |
                                                        ou=staff                                ou=informatique                ou=production            ou=achat
                                                            |
               ------------------------------------------------------------------
                    |                                                                |-b 'dc=kervao, dc=fr' '(objectclass=*)'
            cn=Veronique Hoarau                            cn=Olivier Hoarau

Au niveau de la définition de la personne:

objetclass: person définit la classe père de la classe breizPerson,
objetclass: breizPerson classe décrivant la personne,
cn et sn sont des attributs à renseigner obligatoirement,
title est un attribut obligatoire

On rajoutera l'enregistrement en utilisant la syntaxe suivante  (en tant que simple utilisateur):

ldapadd -x -D "description du dn de l'administrateur" -W -f nom-du-fichier-ldif

Exemple concret:

ldapadd -x  -D "cn=Manager, dc=kervao, dc=fr" -W -f entree.ldif
Enter LDAP Password: secret
adding new entry "dc=kervao, dc=fr"

adding new entry "ou=staff, dc=kervao, dc=fr"

adding new entry "cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr"

Pour rajouter par la suite un autre enregistement dans le groupe staff, il sera plus nécessaire de rajouter la définition du groupe et de l'organisation. Soit le fichier entree.ldif

dn: cn=Olivier Hoarau, ou=staff, dc=kervao, dc=fr
objectclass:    person
objectclass:    breizhPerson
cn: Olivier Hoarau
sn: Hoarau
title:   monsieur

On tape ensuite la commande:

ldapadd -x  -D "cn=Manager, dc=kervao, dc=fr" -W -f entree.ldif
Enter LDAP Password:
adding new entry "cn=Olivier Hoarau, ou=staff, dc=kervao, dc=fr"

[Retour haut de la page ]

Rechercher un enregistrement

On utilisera la fonction ldapsearch. Pour visualiser tout l'annuaire on peut taper :

ldapsearch -x -b 'dc=kervao, dc=fr' '(objectclass=*)'

Voilà le résultat

# extended LDIF
#
# LDAPv3
# filter: (objectclass=*)
# requesting: ALL
#

# kervao, fr
dn: dc=kervao, dc=fr
objectClass: dcObject
objectClass: organization
dc: kervao
o: kervao.fr

# staff, kervao, fr
dn: ou=staff, dc=kervao, dc=fr
objectClass: organizationalUnit
ou: staff

# Veronique Hoarau, staff, kervao, fr
dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
objectClass: person
objectClass: breizhPerson
cn: Veronique Hoarau
sn: Hoarau
title: madame

# Olivier Hoarau, staff, kervao, fr
dn: cn=Olivier Hoarau, ou=staff, dc=kervao, dc=fr
objectClass: person
objectClass: breizhPerson
cn: Olivier Hoarau
sn: Hoarau
title: monsieur

# search result
search: 2
result: 0 Success

# numResponses: 5
# numEntries: 4

[Retour haut de la page ]

Modifier un enregistrement

Rajouter un attribut à un enregistrement

On va rajouter l'attribut facultatif location (l) à l'enregistrement Veronique Hoarau. On va créer un fichier modif.ldif contenant:

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
add:    l
title: bureau36

On tape ensuite

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
modifying entry "cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr"

[Retour haut de la page ]

Modifier un attribut

On va modifier l'attribut titre (title) à l'enregistementVeronique Hoarau. On va créer un fichier modif.ldif contenant:

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
changetype: modify
replace: title
title: mademoiselle

On tape ensuite

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
modifying entry "cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr"

[Retour haut de la page ]

Supprimer un attribut

On va supprimer l'attribut location (l) à l'enregistement Veronique Hoarau. On va créer un fichier modif.ldif contenant:

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
delete: l

On tape ensuite

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
modifying entry cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr

[Retour haut de la page ]

Supprimer un enregistrement

Pour supprimer l'enregistrement Veronique hoarau, an va créer un fichier modif.ldif contenant

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
changetype: delete

On tape ensuite:

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
deleting entry cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr

ATTENTION Vous ne pouvez pas supprimer un attribut obligatoire comme title pour la classe breizhPerson.

Passer en connexion chiffrée

Il suffit de rajouter l'option -Z pour passer en connexion chiffrée, avec le mode debug en plus (-d 1), on doit obtenir ce genre de message

TLS trace: SSL_connect:before/connect initialization
TLS trace: SSL_connect:SSLv2/v3 write client hello A
TLS trace: SSL_connect:SSLv3 read server hello A
TLS certificate verification: depth: 1, err: 19, subject: /C=FR/ST=Bretagne/O=none/OU=none/CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org, issuer: /C=FR/ST=Bretagne/O=none/OU=none/CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org
TLS certificate verification: Error, self signed certificate in certificate chain
TLS certificate verification: depth: 1, err: 19, subject: /C=FR/ST=Bretagne/O=none/OU=none/CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org, issuer: /C=FR/ST=Bretagne/O=none/OU=none/CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org
TLS certificate verification: depth: 0, err: 19, subject: /C=FR/ST=Bretagne/L=Brest/O=none/OU=none/CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org, issuer: /C=FR/ST=Bretagne/O=none/OU=none/CN=mana.kervao.fr/emailAddress=olivier.hoarau@funix.org
TLS trace: SSL_connect:SSLv3 read server certificate A
TLS trace: SSL_connect:SSLv3 read server done A
TLS trace: SSL_connect:SSLv3 write client key exchange A
TLS trace: SSL_connect:SSLv3 write change cipher spec A
TLS trace: SSL_connect:SSLv3 write finished A
TLS trace: SSL_connect:SSLv3 flush data
TLS trace: SSL_connect:SSLv3 read server session ticket A
TLS trace: SSL_connect:SSLv3 read finished A
ldap_sasl_bind
ldap_send_initial_request
ldap_send_server_request

(...)

  # numResponses: 9
# numEntries: 8
ldap_free_connection 1 1
ldap_send_unbind
ber_flush2: 7 bytes to sd 3
TLS trace: SSL3 alert write:warning:close notify
ldap_free_connection: actually freed

il y a une erreur avec le certificat qui est auto signé mais comme on a mis TLS_REQCERT allow dans le fichier ldap.conf ce n'est pas bloquant
 
[Retour page d'accueil FUNIX]