Objectif
Mettre en place un annuaire LDAP sur Centos 6.2 avec openLDAP 2.4.23-20. Notre annuaire LDAP hébergera un arbre constitué de 2 branches exemple.zz et demo.zz. Dans chaque branche nous ajouterons une sous-organisation (OU) People qui contiendra quelques utilisateurs. Nous interdirons aux utilisateurs anonymes l’accès à certains attributs. Toutes les transactions entre le serveur LDAP et les clients pourront s’effectuer de manière chiffrée (LDAPS ou StartTLS).
Paquets à installer
[root@ldap-provider2 ~]# yum install openldap-servers openldap-clients
Ces 2 paquets se trouvent dans les repository de base Centos.
Configuration de base
Avant de démarrer slapd, copiez le fichier d’exemple de configuration de la base de données dans /var/lib/ldap:
[root@ldap-provider2 ~]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
Rendez slapd persistant:
[root@ldap-provider2 ~]# chkconfig slapd on
Démarrer le serveur LDAP:
[root@ldap-provider2 ~]# service slapd start
Configuration de l’administrateur
Avant de pouvoir ajouter notre nouvel arbre LDAP, nous devons définir un utilisateur qui pourra effectuer des modifications dans cet arbre.
Pour ajouter et configurer notre administrateur nous allons utiliser ldapvi qui est disponible sur EPEL.
[root@ldap-provider2 ~]# wget http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
[root@ldap-provider2 ~]# yum localinstall epel-release-6-5.noarch.rpm -y
[root@ldap-provider2 ~]# yum install ldapvi -y
Depuis la version 2.3 la configuration de notre serveur peut-être stockée directement dans notre arbre LDAP dans la branche cn=config. Cette nouvelle approche va nous permettre d’effectuer des modifications “à chaud” sur la configuration du serveur via un client LDAP. Toutes ces modifications seront appliquées sans devoir redémarrer le service slapd.
Pour accéder à votre configuration, utilisez la commande suivante:
[root@ldap-provider2 ~]# ldapvi -Y external -h ldapi:// -b cn=config
Modifier le suffixe de notre arbre:
Rendez-vous en bas du fichier et remplacer la ligne
olcSuffix: dc=my-domain,dc=com
par
olcSuffix: dc=zz
sauvegardez et acceptez les changements.
Changer le DN de notre administrateur et lui attribuer un mot de passe:
Remplacez la ligne
olcRootDN: cn=Manager,dc=my-domain,dc=com
par
olcRootDN: cn=admin,dc=zz
Définissez le mot de passe de l’administrateur en ajoutant la ligne suivante:
olcRootPW: {SSHA}password
Le mot de passe peut être généré avec la commande slappasswd:
slappasswd -s motdepasse
Si vous lancer de nouveau votre client LDAP vous devriez retrouver les lignes suivantes en fin de fichier:
[root@ldap-provider2 ~]# ldapvi -Y external -h ldapi:// -b cn=config
olcSuffix: dc=zz
olcRootDN: cn=admin,dc=zz
olcRootPW: {SSHA}password
Ajout de nouveaux schemas
Avant de peupler notre base de données, nous allons tout d’abord voir comment ajouter un nouveau schema. Dans notre exemple nous allons utiliser le schema samba.schema fourni par le paquet samba-3.5.10-114.el6.x86_64.rpm.
Téléchargez le RPM:
[root@ldap-provider2 tmp]# wget http://mirror.centos.org/centos/6/os/x86_64/Packages/samba-3.5.10-114.el6.x86_64.rpm
Récupérez le schema qui se trouve dans le RPM:
[root@ldap-provider2 tmp]# rpm2cpio samba-3.5.10-114.el6.x86_64.rpm |cpio -ivd ./etc/openldap/schema/samba.schema
./etc/openldap/schema/samba.schema
35763 blocks
Copiez-le dans le répertoire schema de openldap:
[root@ldap-provider2 ~]# cp /tmp/etc/openldap/schema/samba.schema /etc/openldap/schema/
Avant d’ajouter notre nouveau schema, nous devons le convertir au format LDIF.
Le schéma samba est dépendant d’autres schémas, nous devons donc inclure tous les schémas dont il dépend avant d’effectuer la conversion.
On crée un fichier texte dans lequel on renseigne les différents schémas que nous allons convertir:
[root@ldap-provider2 ~]# vi /tmp/schema_to_convert.txt
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/samba.schema
On crée le répertoire qui va contenir les schémas au format LDIF:
[root@ldap-provider2 ~]# mkdir /tmp/converted_schema
On lance la conversion avec slaptest:
[root@ldap-provider2 ~]# slaptest -f /tmp/schema_to_convert.txt -F /tmp/converted_schema/
Les schémas au format LDIF se retrouveront dans /tmp/converted_schema/cn\=config/cn\=schema/
Avant de pouvoir ajouter notre schéma samba, nous devons l’éditer:
[root@ldap-provider2 ~]# vi /tmp/converted_schema/cn\=config/cn\=schema/cn\=\{4\}samba.ldif
Editez la première ligne et remplacez là par:
dn: cn=samba,cn=schema,cn=config
La troisième ligne doit également être adaptée pour correspondre au DN:
cn: samba
Il faut également supprimer les dernières lignes du fichier LDIF:
structuralObjectClass: organization
entryUUID: 157352d4-228b-102a-9b33-e79503e120b9
creatorsName: cn=ldapadmin,ou=admin,dc=zz
createTimestamp: 20060126074245Z
entryCSN: 2006012607:42:45Z#0x0001#0#0000
modifiersName: cn=ldapadmin,ou=admin,dc=zz
modifyTimestamp: 20060126074245Z
Il ne reste plus qu’à ajouter le schéma
[root@ldap-provider2 ~]# ldapadd -Y EXTERNAL -H ldapi:// -f /tmp/converted_schema/cn\=config/cn\=schema/cn\=\{4\}samba.ldif
Pour vérifier que le schéma a bien été ajouté:
[root@ldap-provider2 ~]# ldapsearch -LLL -b cn=schema,cn=config -H ldapi:/// dn
Peupler notre arbre LDAP
Maintenant que nous avons un administrateur et nos schémas nous pouvons enfin peupler notre arbre LDAP
[root@ldap-provider2 ~]# mkdir /etc/openldap/ldif
Ajout de l’organisation zz:
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/zz.ldif
dn: dc=zz
objectClass: top
objectClass: dcObject
objectClass: organization
o: zz
dc: zz
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/zz.ldif -W
Ensuite, nous ajoutons demo.zz:
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/demo.zz.ldif
dn: dc=demo,dc=zz
objectClass: top
objectClass: dcObject
objectClass: organization
o: demo.zz
dc: demo
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/demo.zz.ldif -W
Même chose pour exemple.zz
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/exemple.zz.ldif
dn: dc=exemple,dc=zz
objectClass: top
objectClass: dcObject
objectClass: organization
o: exemple.zz
dc: exemple
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/exemple.zz.ldif -W
Ajout des OU People pour demo.zz et exemple.zz.
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/people.demo.zz.ldif
dn: ou=People,dc=demo,dc=zz
objectClass: organizationalUnit
ou: People
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/people.demo.zz.ldif -W
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/people.exemple.zz.ldif
dn: ou=People,dc=exemple,dc=zz
objectClass: organizationalUnit
ou: People
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/people.exemple.zz.ldif -W
Nous allons maintenant ajouter 2 utilisateurs dans chaque OU People:
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/dupond.demo.zz.ldif
dn: cn=dupond,ou=People,dc=demo,dc=zz
givenName: Jean
mailRoutingAddress: dupond@demo.zz
uid: dupond
mail: jean.dupond@demo.zz
cn: dupond
initials: 1
loginShell: /bin/bash
sn: Dupond
telephoneNumber: +32-01-23457
uidNumber: 8099
sambaDomainName: demozz
sambaPrimaryGroupSID: S-1-5-32-590
sambaHomeDrive: U:
displayName: Jean Dupond
gidNumber: 10000
shadowLastChange: 14452
sambaSID: S-1-5-21-2902724253-31401442-67869251-3333
sambaPwdLastSet: 999999999
sambaAcctFlags: [UX]
objectClass: top
objectClass: posixAccount
objectClass: person
objectClass: inetOrgPerson
objectClass: inetLocalMailRecipient
objectClass: sambaSamAccount
objectClass: shadowAccount
homeDirectory: /home/dupond
departmentNumber: maildir:storage=400000
userPassword: {SSHA}sL5ukz/38fxHeIFsx+K/qYbFpqRXdHN2cTc4d3ZMWW9ZRkZJ
sambaLMPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sambaNTPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
mailLocalAddress: dupond
mailLocalAddress: jean.dupond
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/dupond.demo.zz.ldif -W
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/zeman.demo.zz.ldif
dn: cn=zeman,ou=People,dc=demo,dc=zz
givenName: Jean
mailRoutingAddress: zeman@demo.zz
uid: zeman
mail: jean.zeman@demo.zz
cn: zeman
initials: 1
loginShell: /bin/bash
sn: Zeman
telephoneNumber: +32-01-23457
uidNumber: 8100
sambaDomainName: demozz
sambaPrimaryGroupSID: S-1-5-32-590
sambaHomeDrive: U:
displayName: Jean Zeman
gidNumber: 10001
shadowLastChange: 14452
sambaSID: S-1-5-21-2902724253-31401442-67869251-3333
sambaPwdLastSet: 999999999
sambaAcctFlags: [UX]
objectClass: top
objectClass: posixAccount
objectClass: person
objectClass: inetOrgPerson
objectClass: inetLocalMailRecipient
objectClass: sambaSamAccount
objectClass: shadowAccount
homeDirectory: /home/zeman
departmentNumber: maildir:storage=400000
userPassword: xxxxxxxxxxxxxxxxXXXXXXXXXXXXx
sambaLMPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sambaNTPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
mailLocalAddress: zeman
mailLocalAddress: jean.zeman
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/zeman.demo.zz.ldif -W
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/dupond.exemple.zz.ldif
dn: cn=dupond,ou=People,dc=exemple,dc=zz
givenName: Pierre
mailRoutingAddress: dupond@exemple.zz
uid: dupond
mail: pierre.dupond@exemple.zz
cn: dupond
initials: 1
loginShell: /bin/bash
sn: Dupond
telephoneNumber: +32-01-23456
uidNumber: 8099
sambaDomainName: exemplezz
sambaPrimaryGroupSID: S-1-5-32-590
sambaHomeDrive: U:
displayName: Pierre Dupond
gidNumber: 10000
shadowLastChange: 14452
sambaSID: S-1-5-21-2902724253-31401442-67869251-2222
sambaPwdLastSet: 999999999
sambaAcctFlags: [UX]
objectClass: top
objectClass: posixAccount
objectClass: person
objectClass: inetOrgPerson
objectClass: inetLocalMailRecipient
objectClass: sambaSamAccount
objectClass: shadowAccount
homeDirectory: /home/dupond
departmentNumber: maildir:storage=400000
userPassword: xxxxxxxXXXXXXXXXXXXXXXxxxxxxxXXXXx
sambaLMPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sambaNTPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
mailLocalAddress: dupond
mailLocalAddress: pierre.dupond
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/dupond.exemple.zz.ldif -W
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/zeman.exemple.zz.ldif
dn: cn=zeman,ou=People,dc=exemple,dc=zz
givenName: Pierre
mailRoutingAddress: zeman@exemple.zz
uid: zeman
mail: pierre.zeman@exemple.zz
cn: zeman
initials: 1
loginShell: /bin/bash
sn: Zeman
telephoneNumber: +32-01-234568
uidNumber: 8039
sambaDomainName: exemplezz
sambaPrimaryGroupSID: S-1-5-32-590
sambaHomeDrive: U:
displayName: Pierre Zeman
gidNumber: 10002
shadowLastChange: 14452
sambaSID: S-1-5-21-2902724253-31401442-67869251-2222
sambaPwdLastSet: 999999999
sambaAcctFlags: [UX]
objectClass: top
objectClass: posixAccount
objectClass: person
objectClass: inetOrgPerson
objectClass: inetLocalMailRecipient
objectClass: sambaSamAccount
objectClass: shadowAccount
homeDirectory: /home/zeman
departmentNumber: maildir:storage=400000
userPassword: xxxxxxxXXXXXXXXXXXXXXXxxxxxxxXXXXx
sambaLMPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sambaNTPassword: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
mailLocalAddress: zeman
mailLocalAddress: pierre.zeman
[root@ldap-provider2 ~]# ldapadd -D "cn=admin,dc=zz" -H ldapi:// -f /etc/openldap/ldif/zeman.exemple.zz.ldif -W
Pour afficher les entrées que vous venez de rajouter:
[root@ldap-provider2 ~]# slapcat
[root@ldap-provider2 ~]# ldapsearch -x -b "dc=demo,dc=zz"
Sécurité
Par défaut, si vous lancez un ldapsearch en anonyme vous avez accès à tous les attributs sans aucune exception.
Certains attributs doivent être protégés comme par exemple l’attribut userPassword.
Par défaut le RootDN (cn=admin,dc=zz) peut accéder à tous les attributs, il ne faut donc plus l’indiquer dans les différentes ACL.
Nous allons empêcher les utilisateurs anonyme d’accéder à l’attribut userPassword. Seul les utilisateurs authentifiés auront accès à leur propre mot de passe.
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/access.ldif
dn: olcDatabase={2}bdb,cn=config
add: olcAccess
olcAccess: to attrs=userPassword by self write by anonymous auth by * none
olcAccess: to * by * read
Modification de notre configuration avec les informations présentes dans notre LDIF:
[root@ldap-provider2 ~]# ldapmodify -Y EXTERNAL -H ldapi:// -f /etc/openldap/ldif/access.ldif
Si on relance un ldapsearch en anonyme, l’attribut userPassword des utilisateurs ne s’affiche plus:
ldapsearch -x -b
Pour éviter que les données critiques stockées dans notre arbre LDAP ne transitent en clair sur le réseau, nous allons mettre en place du chiffrement grâce à startTLS.
Nous avons besoin de 3 fichiers pour mettre ça en place:
- un certificat signé
- la clef privée qui va avec ce certificat
- l’autorité de certification qui a validé notre certificat
Si vous ne savez pas comment faire rendez-vous sur http://www.404blog.net/?p=122 pour créer une autorité de certification et sur http://www.404blog.net/?p=165 pour générer et signer une demande de certificat.
[root@ldap-provider2 ~]# vi /etc/openldap/ldif/tls.ldif
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap-provider2.exemple.zz.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/ldap-provider2.exemple.zz.key
[root@ldap-provider2 ~]# ldapmodify -Y EXTERNAL -H ldapi:// -f /etc/openldap/ldif/tls.ldif
Placer le certificat, la clef et l’autorité de certification aux endroits indiqués dans le fichier LDIF. Veillez à ce que l’utilisateur ldap((utilisateur qui lance splad)) puisse lire ces différents fichiers. Le CN de votre certificat doit correspondre exactement au FQDN de votre serveur LDAP.
Modifier le fichier /etc/openldap/ldap.conf sur le client:
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable
BASE dc=zz
URI ldap://ldap-provider2.exemple.zz
TLS_CACERT /etc/ssl/certs/cacert.pem
Par défaut on pourra interroger le LDAP sur le port 389 en TLS:
[root@ldap-provider2 ~]# ldapsearch -x -ZZ
Si vous êtes en mode enforcing vous risqueriez d’avoir l’erreur suivante:
[root@ldap-provider2 ~]# ldapsearch -x -Z
ldap_start_tls: Connect error (-11)
additional info: TLS error -5938:Encountered end of file
Veillez à donner comme contexte cert_t à votre CA et votre certificat:
[root@ldap-provider2 ~]# restorecon -Rv /etc/ssl/certs/
Si l’on veut pouvoir interroger le serveur en LDAPS, il faudra éditer /etc/sysconfig/ldap
SLAPD_LDAPS=yes
redémarrez slapd
[root@ldap-provider2 ~]# service slapd restart
Vous pouvez désormais interroger votre serveur ldap en LDAPS:
[root@ldap-provider2 ~]# ldapsearch -x -H ldaps://ldap-provider2.exemple.zz
Par défaut sur Centos, netfilter empêche les connexions de l’extérieur vers le port LDAP et LDAPS.
[root@ldap-provider2 ~]# iptables -I INPUT -p tcp --dport 389 -j ACCEPT
[root@ldap-provider2 ~]# iptables -I INPUT -p tcp --dport 636 -j ACCEPT
On sauvegarde les règles:
[root@ldap-provider2 ~]# /etc/init.d/iptables save
Backup
Etant donné que notre configuration est sauvegardée dans notre arbre LDAP, un simple slapcat suffit pour faire une sauvegarde:
[root@ldap-provider2 ~]# slapcat -b cn=config > config.ldif
Pour sauvegarder notre organisation zz:
[root@ldap-provider2 ~]# slapcat -b cn=zz > zz.ldif
Restore
Voici les différentes étapes afin de récupérer notre serveur LDAP depuis nos sauvegardes au format LDIF:
[root@ldap-provider2 ~]# /etc/init.d/slapd stop
Supprimez le contenu du dossier /var/lib/ldap/ sauf la configuration de notre DB:
[root@ldap-provider2 ~]# for i in $(ls /var/lib/ldap/|grep -v DB_CONFIG);do rm /var/lib/ldap/$i;done
Supprimez le contenu du dossier /etc/openldap/slapd.d
[root@ldap-provider2 ~]# rm -r /etc/openldap/slapd.d/*
Restaurez la configuration depuis notre sauvegarde:
[root@ldap-provider2 ~]# slapadd -F /etc/openldap/slapd.d/ -b cn=config -l config.ldif
Restaurez le contenu de notre organisation zz:
[root@ldap-provider2 ~]# slapadd -b dc=be -l be.ldif
Restaurez les droits:
[root@ldap-provider2 ~]# chown -R ldap /etc/openldap/slapd.d/
[root@ldap-provider2 ~]# chown -R ldap /var/lib/ldap
Redémarrez le serveur:
[root@ldap-provider2 ~]# /etc/init.d/slapd start