Formation OpenLDAP

De PedroWiki

Système et versions utilisés pour la formation

  • Fedora release 14 (Laughlin)
  • Linux kjh.localdomain 2.6.35.6-45.fc14.x86_64 #1 SMP Mon Oct 18 23:57:44 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
  • pam_ldap-185-5.fc14.x86_64
  • apr-util-ldap-1.3.9-3.fc13.x86_64
  • openldap-servers-2.4.23-4.fc14.x86_64
  • openldap-2.4.23-4.fc14.x86_64
  • openldap-clients-2.4.23-4.fc14.x86_64

Installation

Recherche du package:

yum search openldap

Vérification des packages déjà installés:

rpm -qa openldap

ATTENTION on n'a que la partie cliente...

Vérification de la version de noyau

uname -a

Installation du serveur openldap

yum install openldap-servers.x86_64

ATTENTION à cette étape, on n'a pas les commandes clientes ldap*, uniquement les slap*

yum install openldap-clients.x86_64

Configuration initiale

Fichier de configuration slapd.conf

ATTENTION pb: pas de slapd.conf

updatedb
locate slapd.conf
less /usr/share/openldap-servers/slapd.conf.obsolete
cp /usr/share/openldap-servers/slapd.conf.obsolete /etc/openldap/slapd.conf

Edition de /etc/openldap/slapd.conf.

Documentation officielle de OpenLDAP pour slapd.conf


Configuration du Root DN et de l'accès Manager

database        bdb
suffix          "dc=pedrono,dc=fr"
rootdn          "cn=Manager,dc=pedrono,dc=fr"
rootpw          {SHA}C5wmJdwh7wX2rU3fR8XyA4N6oyw= (toto)

Génération du mot de passe du manager (rootdn) via slappasswd

slappasswd -h {SHA} -T ./pwdfile

ou

slappasswd -h {SHA} (fonctionnement interactif)

Le mot de passe est affichée sur la sortie standard.

Données

Les données sont dans /var/lib/ldap, mais préférer l'utilisation de slapcat pour faire ses sauvegardes en ldif.

Attention, faire des exports ldif réguliers, en particulier avant la mise à jour d'un serveur, car en cas de changement de format bdb, on peut abimer tout l'annuaire et donc devoir le réimporter.

Mise en place d'ACL

Toujours dans slapd.conf:

# On bloque tout pour tout le monde
# Tout est déjà ouvert pour le rootdn puisque pas sujet aux ACL
# On ouvre en lecture pour un eventuel futur utilisateur "admin"
access to *
        by dn.exact="cn=admin,dc=pedrono,dc=fr" write
        by * none

Droits sur les fichiers

ATTENTION à ce que les données appartiennent bien à ldap et non à root, sinon chown.

Mise en place des logs

slapd utilise la facility de loggage local.4.

Modifier /etc/rsyslog.conf pour y décommenter les lignes suivantes:

# Provides UDP syslog reception
$ModLoad imudp.so
$UDPServerRun 514

Ajouter la ligne suivante:

local4.*                                                /var/log/ldap.log

Mettre en place un loglevel dans /etc/openldap/slapd.conf:

loglevel 132

Cf la doc officielle d'OpenLDAP ou le support de formation pour les différents niveaux de logs (pour les combiner, additionner les valeurs).

Il faut ensuite (dans le cas de cette distro) démarrer le serveur syslog:

/etc/init.d/rsyslog start

Puis il faut effectuer au moins 1 requête LDAP pour commencer à logger.

Démarrage du service

Mise en place de traces:

tail -f /var/log/messages &

Démarrage du service:

/etc/init.d/slapd start

Warning dans les logs:

[root@kjh openldap]# /etc/init.d/slapd start
Vérification des fichiers de configuration pour slapd :    [AVERTISSEMENT]
bdb_db_open: warning - no DB_CONFIG file found in directory /var/lib/ldap: (2).
Expect poor performance for suffix "dc=my-domain,dc=com".
config file testing succeeded
Démarrage de slapd :                                       [  OK  ]

Ceci est du certainement à de la mise en cache de la part d'openldap sur les fichiers de conf initiaux (cf la référence à dc=my-domain,dc=com).

Tentative:

touch /var/lib/ldap/DB_MONITOR
chown ldap: /var/lib/ldap/DB_MONITOR


touch /var/lib/ldap/DB_CONFIG
chown ldap: /var/lib/ldap/DB_CONFIG

Pas d'amélioration après restart du service.

Solution: suppression des données du cache:

rm -rf /etc/openldap/cacerts/

Sans effet, autre solution:

rm -rf /var/lib/ldap/*

Après restart du service disparition du warning.

Vérification du démarrage:

[root@kjh openldap]# netstat -tpln
...
tcp        0      0 0.0.0.0:389                 0.0.0.0:*                   LISTEN      30083/slapd 
...
[root@kjh openldap]# ps fax|grep ldap
30098 pts/1    S+     0:00  |           \_ grep --color=auto ldap
30083 ?        Ssl    0:00 /usr/sbin/slapd -h  ldap:/// -u ldap

Création d'un domaine

Documentation spécifique d'OpenLDAP

Choix d'un schéma

A moins de partir d'une requête précise sur un schéma précis, le challenge est de choisir un schéma afin d'y piocher nos objectClasses.

[root@kjh openldap]# grep organization /etc/openldap/schema/*|grep objectclass
/etc/openldap/schema/core.schema:objectclass ( 2.5.6.4 NAME 'organization'
/etc/openldap/schema/core.schema:objectclass ( 2.5.6.5 NAME 'organizationalUnit'
/etc/openldap/schema/core.schema:objectclass ( 2.5.6.7 NAME 'organizationalPerson'
/etc/openldap/schema/core.schema:objectclass ( 2.5.6.8 NAME 'organizationalRole'

On souhaite créer une organisation donc on peut utiliser l'objectClass "organisation" disponible dans core.schema.

A priori nécessité d'utiliser un objectClass dcObject.

En synthèse, pour tout annuaire à mettre en place, on utilisera une base commune, cf le fichier LDIF ci dessous.

Création du fichier LDIF de création de notre organisation

Création d'un fichier entries.ldif:

dn: dc=pedrono,dc=fr
objectClass: dcObject
objectClass: organization
dc: pedrono
o: Pedrono Org
description: Organisation Pedrono.fr

Import de ce fichier LDIF via la commande slapadd (initialisation de notre nouvel annuaire/organisation. ATTENTION: ceci nécessite l'arrêt du service slapd).

ATTENTION: si on souhaite modifier ce LDIF après import dans OpenLDAP, nécessité de supprimer et de recréer notre dn/annuaire.

Il est possible de gérer des LDIF de modification de notre annuaire, et de les appliquer par ldapmodify.

ATTENTION: ceci implique:

  • qu'il faut historiser ses fichiers LDIF
  • idéalement qu'on va gérer un script pour réappliquer tous les LDIF dans le bon ordre en cas de besoin de re création de la structure de l'annuaire.
  • NB: il est possible de gérer à la base un LDIF pour l'organisation, plusieurs LDIF pour les OU, etc.

A cette étape, simple tentative de stop puis start du service avant toute entrée du LDIF. On se retrouve avec le même problème qu'au moment du lancement initial:

[root@kjh ~]# /etc/init.d/slapd start
Vérification des fichiers de configuration pour slapd :    [AVERTISSEMENT]
bdb_db_open: warning - no DB_CONFIG file found in directory /var/lib/ldap: (2).
Expect poor performance for suffix "dc=my-domain,dc=com".
config file testing succeeded
Démarrage de slapd :                                       [  OK  ]

Tentative de résolution de ce warning:

[root@kjh ~]# /etc/init.d/slapd stop
Arrêt de slapd :                                           [  OK  ]
[root@kjh ~]# rm -rf /var/lib/ldap/*
[root@kjh ~]# touch /var/lib/ldap/DB_CONFIG
[root@kjh ~]# chown ldap: /var/lib/ldap/DB_CONFIG
[root@kjh ~]# /etc/init.d/slapd start

On a donc résolu à nouveau ce problème de warning.

cf cette page de résolution du problème

ATTENTION: une partie des problèmes peut venir de selinux => désactivation de selinux:

vi /etc/selinux/config
...
SELINUX=enforcing (à modifier en disabled)
...

+ redémarrage du système ou setenforce 0 pour désactivation pour la session en cours.

ATTENTION: il peut rester un contenu de paramétrage initial sur la conf par défaut dans /etc/openldap/splapd.d/ (cf l'étape suivante)

Tentative:

cp -r /etc/openldap/slapd.d/ /etc/openldap/slapd.d.SAVE/
rm -rf /etc/openldap/slapd.d/*

Import du LDIF

[root@kjh ~]# slapadd -f conf_ldap/organisation.ldif  
conf_ldap/organisation.ldif: line 2: unknown directive <dn:> outside backend info and database definitions.
slapadd: bad configuration file!
[root@kjh ~]# 

Une piste ici

Tentatives sans suivre la page web ci dessus: ATTENTION utilisation du mauvais switch pour la commande slapadd!!!

[root@kjh ~]# slapadd -l /root/conf_ldap/organisation.ldif 
bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
_#################### 100.00% eta   none elapsed            none fast!         
Closing DB...

A priori OK, warning sur le fait d'avoir mis en commentaire "database monitor" dans /etc/openldap/slapd.conf. Pas de réel problème, réactivation par suppression de la mise en commentaire et redémarrage du service.

[root@kjh ~]# /etc/init.d/slapd start
ls: impossible d'accéder à /etc/openldap/slapd.d//cn=config/olcDatabase*.ldif: Aucun fichier ou dossier de ce type
sed: can't read /etc/openldap/slapd.d//cn=config.ldif: No such file or directory
Vérification des fichiers de configuration pour slapd :    [AVERTISSEMENT]
bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
config file testing succeeded
Démarrage de slapd :                                       [  OK  ]

On remet donc en place l'ancien contenu de /etc/openldap/slapd.d.

[root@kjh ~]# /etc/init.d/slapd stop
Arrêt de slapd :                                           [  OK  ]
[root@kjh ~]# rm -rf /etc/openldap/slapd.d
slapd.d/      slapd.d.SAVE/ 
[root@kjh ~]# rm -rf /etc/openldap/slapd.d
[root@kjh ~]# mv /etc/openldap/slapd.d.SAVE/ /etc/openldap/slapd.d/
[root@kjh ~]# ls -la /etc/openldap/slapd.d/
total 16
drwx------. 3 root root 4096 14 déc.  17:21 .
drwxr-xr-x. 4 root root 4096 14 déc.  17:24 ..
drwx------. 3 root root 4096 14 déc.  17:21 cn=config
-rw-------. 1 root root  986 14 déc.  17:21 cn=config.ldif
[root@kjh ~]# /etc/init.d/slapd start
/var/lib/ldap/objectClass.bdb is not owned by "ldap"       [AVERTISSEMENT]
Vérification des fichiers de configuration pour slapd :    [ÉCHOUÉ]
ldif_read_file: Permission denied for "/etc/openldap/slapd.d/cn=config.ldif"
slaptest: bad configuration file!

A cette étape, problème car slapadd lancé en tant que root: les données de /var/lib/ldap appartiennent à root et non à ldap...

[root@kjh ~]# chown -R ldap: /etc/openldap/slapd.d/
[root@kjh ~]# /etc/init.d/slapd start
/var/lib/ldap/objectClass.bdb is not owned by "ldap"       [AVERTISSEMENT]
Démarrage de slapd :                                       [  OK  ]
[root@kjh ~]# chown ldap: /var/lib/ldap/*
[root@kjh ~]# /etc/init.d/slapd restart
Arrêt de slapd :                                           [  OK  ]
Démarrage de slapd :                                       [  OK  ]
[root@kjh ~]# 

Vérification de l'import:

[root@kjh ~]# ldapsearch -x -b 'dc=pedrono,dc=fr'
# extended LDIF
#
# LDAPv3
# base <dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 32 No such object

# numResponses: 1

Apparement l'import s'est mal passé.

Nouvelle tentative:

[root@kjh ~]# /etc/init.d/slapd stop
Arrêt de slapd :                                           [  OK  ]
[root@kjh ~]# slapadd -l /root/conf_ldap/organisation.ldif  
slapadd: line 1: database #1 (dc=my-domain,dc=com) not configured to hold "dc=pedrono,dc=fr"; no database configured for that naming context
_#################### 100.00% eta   none elapsed            none fast!         
Closing DB...

Nouveau test:

[root@kjh ~]# rm /etc/openldap/slapd.d/cn\=config.ldif 
rm : supprimer fichier « /etc/openldap/slapd.d/cn=config.ldif » ? y
[root@kjh ~]# slapadd -l /root/conf_ldap/organisation.ldif 
bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
=> bdb_tool_entry_put: id2entry_add failed: DB_KEYEXIST: Key/data pair already exists (-30995)
=> bdb_tool_entry_put: txn_aborted! DB_KEYEXIST: Key/data pair already exists (-30995)
slapadd: could not add entry dn="dc=pedrono,dc=fr" (line=1): txn_aborted! DB_KEYEXIST: Key/data pair already exists (-30995)
_#################### 100.00% eta   none elapsed            none fast!         
Closing DB...

Cette fois slapadd nous indique qu'on a déjà créé la base et qu'on ne peut pas la recréer, il faut donc à nouveau supprimer le contenu de /var/lib/ldap:

[root@kjh ~]# rm -rf /var/lib/ldap/*
[root@kjh ~]# touch /var/lib/ldap/DB_CONFIG
[root@kjh ~]# chown ldap: /var/lib/ldap/DB_CONFIG
[root@kjh ~]# slapadd -l /root/conf_ldap/organisation.ldif 
bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
_#################### 100.00% eta   none elapsed            none fast!         
Closing DB...
[root@kjh ~]# /etc/init.d/slapd start
/var/lib/ldap/__db.006 is not owned by "ldap"              [AVERTISSEMENT]
/var/lib/ldap/__db.002 is not owned by "ldap"              [AVERTISSEMENT]
/var/lib/ldap/dn2id.bdb is not owned by "ldap"             [AVERTISSEMENT]
/var/lib/ldap/alock is not owned by "ldap"                 [AVERTISSEMENT]
/var/lib/ldap/id2entry.bdb is not owned by "ldap"          [AVERTISSEMENT]
/var/lib/ldap/objectClass.bdb is not owned by "ldap"       [AVERTISSEMENT]
/var/lib/ldap/__db.004 is not owned by "ldap"              [AVERTISSEMENT]
/var/lib/ldap/__db.005 is not owned by "ldap"              [AVERTISSEMENT]
/var/lib/ldap/log.0000000001 is not owned by "ldap"        [AVERTISSEMENT]
/var/lib/ldap/__db.001 is not owned by "ldap"              [AVERTISSEMENT]
/var/lib/ldap/__db.003 is not owned by "ldap"              [AVERTISSEMENT]
sed: can't read /etc/openldap/slapd.d//cn=config.ldif: No such file or directory
Vérification des fichiers de configuration pour slapd :    [ÉCHOUÉ]
bdb_db_open: database "dc=pedrono,dc=fr": alock package is unstable.
backend_startup_one (type=bdb, suffix="dc=pedrono,dc=fr"): bi_db_open failed! (-1)
slap_startup failed (test would succeed using the -u switch)
d'anciens fichiers verroux peuvent être présents dans /var/[AVERTISSEMENT]
[root@kjh ~]# chown ldap: /var/lib/ldap/*
[root@kjh ~]# /etc/init.d/slapd start
sed: can't read /etc/openldap/slapd.d//cn=config.ldif: No such file or directory
Vérification des fichiers de configuration pour slapd :    [AVERTISSEMENT]
bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
config file testing succeeded
Démarrage de slapd :                                       [  OK  ]

Nouveau ldapsearch:

[root@kjh ~]# ldapsearch -x -b "dc=pedrono,dc=fr"
# extended LDIF
#
# LDAPv3
# base <dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 32 No such object

# numResponses: 1

ATTENTION: à cause de nos ACL pour l'instant seul le rootdn peut interroger en s'authentifiant...

Nouveau ldapsearch:

[root@kjh ~]# ldapsearch -x -b "dc=pedrono,dc=fr" -D "cn=Manager,dc=pedrono,dc=fr" -W
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
# 

# pedrono.fr
dn: dc=pedrono,dc=fr
objectClass: dcObject
objectClass: organization
dc: pedrono
o: Pedrono Org
description: Organisation Pedrono.fr 

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

On a donc créé notre organisation avec les bonnes caractéristiques.

Création d'OU

On va créer 1 OU dans un nouveau fichier LDIF ou1.ldif:

dn: ou=utilisateurs,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: utilisateurs
postalCode: 44000
description: Unite organisationnelle des utilisateurs de Pedrono Organisation

Import de ce fichier LDIF:

[root@kjh conf_ldap]# ldapadd -f ./ou1.ldif -D 'cn=Manager,dc=pedrono,dc=fr' -W
Enter LDAP Password: 
adding new entry "ou=utilisateurs,dc=pedrono,dc=fr"

[root@kjh conf_ldap]# 

Test de l'import:

[root@kjh conf_ldap]# ldapsearch -x -b 'dc=pedrono,dc=fr' -D 'cn=Manager,dc=pedrono,dc=fr' -W
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# pedrono.fr
dn: dc=pedrono,dc=fr
objectClass: dcObject
objectClass: organization
dc: pedrono
o: Pedrono Org
description: Organisation Pedrono.fr

# utilisateurs, pedrono.fr
dn: ou=utilisateurs,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: utilisateurs
postalCode: 44000
description: Unite organisationnelle des utilisateurs de Pedrono Organisation

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

On va donc créer 2 autres OU:

  • une OU "groupes" dans ou2.ldif.
  • une OU "peripheriques" dans ou3.ldif.

ou2.ldif:

dn: ou=groupes,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: groupes
postalCode: 44000
description: Unite organisationnelle des groupes de Pedrono Organisation

ou3.ldif:

dn: ou=peripheriques,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: peripheriques
postalCode: 44000
description: Unite organisationnelle des peripheriques de Pedrono Organisation

Import de ces nouvelles OU:

[root@kjh conf_ldap]# ldapadd -f ./ou2.ldif -D 'cn=Manager,dc=pedrono,dc=fr' -W
Enter LDAP Password: 
adding new entry "ou=groupes,dc=pedrono,dc=fr"
[root@kjh conf_ldap]# ldapadd -f ./ou3.ldif -D 'cn=Manager,dc=pedrono,dc=fr' -W
Enter LDAP Password: 
adding new entry "ou=peripheriques,dc=pedrono,dc=fr"

Vérification:

[root@kjh conf_ldap]# ldapsearch -x -b 'dc=pedrono,dc=fr' -D 'cn=Manager,dc=pedrono,dc=fr' -W
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# pedrono.fr
dn: dc=pedrono,dc=fr
objectClass: dcObject
objectClass: organization
dc: pedrono
o: Pedrono Org
description: Organisation Pedrono.fr

# utilisateurs, pedrono.fr
dn: ou=utilisateurs,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: utilisateurs
postalCode: 44000
description: Unite organisationnelle des utilisateurs de Pedrono Organisation

# groupes, pedrono.fr
dn: ou=groupes,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: groupes
postalCode: 44000
description: Unite organisationnelle des groupes de Pedrono Organisation

# peripheriques, pedrono.fr
dn: ou=peripheriques,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: peripheriques
postalCode: 44000
description: Unite organisationnelle des peripheriques de Pedrono Organisation

# search result
search: 2
result: 0 Success

# numResponses: 5
# numEntries: 4

Ajout d'entrées dans l'annuaire

Ajout d'utilisateurs

Création d'un fichier LDIF pour la création des utilisateurs, qu'on ratachera à l'OU utilisateurs.

Détermination des objectClass: chercher quelque chose du style "account" ou "ccount" dans les schémas.

Plusieurs schémas peuvent correspondre, il faut faire un choix à cette étape.

Si on souhaite utiliser l'annuaire pour l'authentification linux, on va pouvoir choisir l'objectClass posixAccount du schéma nis.

ATTENTION: quand on sélectionne un objectClass, on ne peut pas n'utiliser qu'un objectClass AUXILIARY.

Ex:

objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
        DESC 'Abstraction of an account with POSIX attributes'
        SUP top AUXILIARY
        MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
        MAY ( userPassword $ loginShell $ gecos $ description ) )

Il faut utiliser un objectClass qui soit de type STRUCTURAL. Par exemple posixGroup dans notre cas, si on ne souhaite pas mélanger les objectClass de schémas différents.

Contenu d'un bloc du LDIF:

dn: uid=pierre,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Pierre Pierre
uid: pierre
uidNumber: 1000
gidNumber: 100
homeDirectory: /home/pierre
userPassword: $6$cz.MqrGuUVHz4yZG$6dOJYgmEJ8h6Tn0r.sYHPYrX.uM3xDH7xV7wTiq3OWOdtZnXXEkkVMG6inFjAyACNriflQdo.g.2Ejlig0CXR0
loginShell: /bin/bash
description: Pierre de la compta

Le fichier contenant les 4 utilisateurs créés est utilisateurs.ldif.

Import des utilisateurs, on respecte la logique habituelle:

  • arrêt du service
  • slapadd
  • démarrage du service

ATTENTION: une fois de plus comme on travaille en root, on crée des fichier bdb appartenant à root dans /var/lib/ldap, il ne faut donc pas oublier le chown ldap: /var/lib/ldap/* avant de démarrer le service.

/etc/init.d/slapd stop
slapadd -l /root/conf_ldap/utilisateurs.ldif 
chown ldap: /var/lib/ldap/*
/etc/init.d/slapd start

Vérification du résultat:

[root@kjh conf_ldap]# ldapsearch -x -b 'ou=utilisateurs,dc=pedrono,dc=fr' -D 'cn=Manager,dc=pedrono,dc=fr' -W
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <ou=utilisateurs,dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# utilisateurs, pedrono.fr
dn: ou=utilisateurs,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: utilisateurs
postalCode: 44000
description: Unite organisationnelle des utilisateurs de Pedrono Organisation

# pierre, utilisateurs, pedrono.fr
dn: uid=pierre,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Pierre Pierre
uid: pierre
uidNumber: 1000
gidNumber: 100
homeDirectory: /home/pierre
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Pierre de la compta

# paul, utilisateurs, pedrono.fr
dn: uid=paul,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Paul Paul
uid: paul
uidNumber: 1001
gidNumber: 100
homeDirectory: /home/paul
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Paul de la repro

# jacques, utilisateurs, pedrono.fr
dn: uid=jacques,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Jacques Jacques
uid: jacques
uidNumber: 1002
gidNumber: 100
homeDirectory: /home/jacques
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Jacques du courrier

# martine, utilisateurs, pedrono.fr
dn: uid=martine,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Martine Martine
uid: martine
uidNumber: 1003
gidNumber: 100
homeDirectory: /home/martine
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Martine la secretaire

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 5

Ajout de groupes

Notre OU groupes servira à stocker des groupes servant à faire une découpe "logique" de notre organisation.

On va donc chercher un objectclass correspondant à cette notion:

[root@kjh conf_ldap]# grep -i group /etc/openldap/schema/*.schema|grep -v SUP|grep objectclass
/etc/openldap/schema/core.schema:objectclass ( 2.5.6.9 NAME 'groupOfNames'
/etc/openldap/schema/core.schema:objectclass ( 2.5.6.17 NAME 'groupOfUniqueNames'
/etc/openldap/schema/nis.schema:objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup'
/etc/openldap/schema/nis.schema:objectclass ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup'

Il est à priori courant d'utiliser groupOfNames pour implémenter cette notion.

objectclass ( 2.5.6.9 NAME 'groupOfNames'
        DESC 'RFC2256: a group of names (DNs)'
        SUP top STRUCTURAL
        MUST ( member $ cn )
        MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )

Contenu du fichier LDIF groupes.ldif:

dn: cn=courrier,ou=groupes,dc=pedrono,dc=fr
objectClass:groupOfNames
member:uid=jacques,ou=utilisateurs,dc=pedrono,dc=fr
cn:courrier
description:Groupe des utilisateurs du service Courrier

dn: cn=compta,ou=groupes,dc=pedrono,dc=fr
objectClass:groupOfNames
member:uid=pierre,ou=utilisateurs,dc=pedrono,dc=fr
cn:compta
description:Groupe des utilisateurs du service Comptabilité

dn: cn=repro,ou=groupes,dc=pedrono,dc=fr
objectClass:groupOfNames
member:uid=paul,ou=utilisateurs,dc=pedrono,dc=fr
cn:repro
description:Groupe des utilisateurs du service Reprographie

dn: cn=secretariat,ou=groupes,dc=pedrono,dc=fr
objectClass:groupOfNames
member:uid=martine,ou=utilisateurs,dc=pedrono,dc=fr
cn:secretariat
description:Groupe des utilisateurs du service Secrétariat

Import des groupes:

[root@kjh conf_ldap]# /etc/init.d/slapd stop
Arrêt de slapd :                                           [  OK  ]
[root@kjh conf_ldap]# slapadd -l /root/conf_ldap/groupes.ldif 
_#################### 100.00% eta   none elapsed            none fast!         
Closing DB...
[root@kjh conf_ldap]# chown ldap: /var/lib/ldap/*
[root@kjh conf_ldap]# /etc/init.d/slapd start
sed: can't read /etc/openldap/slapd.d//cn=config.ldif: No such file or directory
Démarrage de slapd :                                       [  OK  ]

Vérification de l'import:

[root@kjh conf_ldap]# ldapsearch -x -b 'ou=groupes,dc=pedrono,dc=fr' -D 'cn=Manager,dc=pedrono,dc=fr' -W
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <ou=groupes,dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# groupes, pedrono.fr
dn: ou=groupes,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: groupes
postalCode: 44000
description: Unite organisationnelle des groupes de Pedrono Organisation

# courrier, groupes, pedrono.fr
dn: cn=courrier,ou=groupes,dc=pedrono,dc=fr
objectClass: groupOfNames
member: uid=jacques,ou=utilisateurs,dc=pedrono,dc=fr
cn: courrier
description: Groupe des utilisateurs du service Courrier

# compta, groupes, pedrono.fr
dn: cn=compta,ou=groupes,dc=pedrono,dc=fr
objectClass: groupOfNames
member: uid=pierre,ou=utilisateurs,dc=pedrono,dc=fr
cn: compta
description:: R3JvdXBlIGRlcyB1dGlsaXNhdGV1cnMgZHUgc2VydmljZSBDb21wdGFiaWxpdMOp

# repro, groupes, pedrono.fr
dn: cn=repro,ou=groupes,dc=pedrono,dc=fr
objectClass: groupOfNames
member: uid=paul,ou=utilisateurs,dc=pedrono,dc=fr
cn: repro
description: Groupe des utilisateurs du service Reprographie

# secretariat, groupes, pedrono.fr
dn: cn=secretariat,ou=groupes,dc=pedrono,dc=fr
objectClass: groupOfNames
member: uid=martine,ou=utilisateurs,dc=pedrono,dc=fr
cn: secretariat
description:: R3JvdXBlIGRlcyB1dGlsaXNhdGV1cnMgZHUgc2VydmljZSBTZWNyw6l0YXJpYXQ=

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 5

NB: les champs description:: signifient qu'ils sont encodés en base64 (conversion lié à l'utilisation d'UTF-8) car les chaines de caractères comportent des accents.

Mise en place d'ACL sur nos utilisateurs

On va attribuer des ACL spécifiques à nos nouveaux utilisateurs, en attribuant des droits en lecture à 2 d'entre eux, et en écriture aux 2 autres.

Il faut modifier slapd.conf.

...
access to *
        by dn.exact="uid=pierre,ou=utilisateurs,dc=pedrono,dc=fr" write
        by dn.exact="uid=paul,ou=utilisateurs,dc=pedrono,dc=fr" write
        by dn.exact="cn=secretariat,ou=groupes,dc=pedrono,dc=fr" read
        by dn.exact="cn=courrier,ou=groupes,dc=pedrono,dc=fr" read
...

Puis on redémarre ou on recharge la conf du démon.

ATTENTION: en principe les ACL en place dans slapd.conf ne permettent pas les ldapsearch sans authentification. Problème: plusieurs des serveurs installés lors de la formation ne demande aucune authentification.

FAQ sur le contrôle d'accès à slapd

Après tests, quand on désactive la directive database monitoring dans /etc/openldap/slapd.conf on ne peut plus interroger sans authentification. Reste quand même le problème du refus d'accès malgré les ACL en place, pour des utilisateurs de l'annuaire (autres que rootdn).

Piste: le mot de passe de mes utilisateurs dans l'annuaire est un copié/collé du mot de passe "admin" récupéré dans /etc/shadow

Changement du mot de passe via ldappasswd:

ldappasswd -D "cn=Manager,dc=pedrono,dc=fr" -x -W -s admin -d 128 -v "uid=pierre,ou=utilisateurs,dc=pedrono,dc=fr"

ATTENTION: l'emplacement du DN correspondant à l'utilisateur concerné est très important, et doit surtout venir après toutes les options pour que le changement de mot de passe soit bien fait (sinon erreur inconnue 80).


Sauvegarde des données de l'annuaire par la commande slapcat

Usage de la commande slapcat:

[root@kjh conf_ldap]# slapcat -?
slapcat: invalid option -- '?'
usage: slapcat [-v] [-d debuglevel] [-f configfile] [-F configdir] [-o <name>[=<value>]] [-c]
	[-g] [-n databasenumber | -b suffix] [-l ldiffile] [-a filter] [-s subtree] [-H url]

On procède comme avec toutes les commandes slap*:

  • arrêt du service
  • commande slapcat
  • démarrage du service

Exemple:

[root@kjh conf_ldap]# /etc/init.d/slapd stop
Arrêt de slapd :                                           [  OK  ]

[root@kjh conf_ldap]# slapcat -b dc=pedrono,dc=fr
dn: dc=pedrono,dc=fr
objectClass: dcObject
objectClass: organization
dc: pedrono
o: Pedrono Org
description: Organisation Pedrono.fr
structuralObjectClass: organization
entryUUID: 71c6f478-9bee-102f-8c03-29420d2afb4c
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101214165339Z
entryCSN: 20101214165339.378657Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101214165339Z

dn: ou=utilisateurs,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: utilisateurs
postalCode: 44000
description: Unite organisationnelle des utilisateurs de Pedrono Organisation
structuralObjectClass: organizationalUnit
entryUUID: c8bc1d2e-9bf0-102f-8097-9ba5be946944
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101214171024Z
entryCSN: 20101214171024.262851Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101214171024Z

dn: ou=groupes,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: groupes
postalCode: 44000
description: Unite organisationnelle des groupes de Pedrono Organisation
structuralObjectClass: organizationalUnit
entryUUID: af430758-9bf1-102f-8098-9ba5be946944
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101214171651Z
entryCSN: 20101214171651.022998Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101214171651Z

dn: ou=peripheriques,dc=pedrono,dc=fr
objectClass: organizationalUnit
ou: peripheriques
postalCode: 44000
description: Unite organisationnelle des peripheriques de Pedrono Organisation
structuralObjectClass: organizationalUnit
entryUUID: b4054760-9bf1-102f-8099-9ba5be946944
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101214171659Z
entryCSN: 20101214171659.006922Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101214171659Z

dn: uid=pierre,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Pierre Pierre
uid: pierre
uidNumber: 1000
gidNumber: 100
homeDirectory: /home/pierre
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Pierre de la compta
structuralObjectClass: posixGroup
entryUUID: 4aeca2f0-9c82-102f-9636-c30d47b24027
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101215103159Z
entryCSN: 20101215103159.710447Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101215103159Z

dn: uid=paul,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Paul Paul
uid: paul
uidNumber: 1001
gidNumber: 100
homeDirectory: /home/paul
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Paul de la repro
structuralObjectClass: posixGroup
entryUUID: 4b48cdd2-9c82-102f-9637-c30d47b24027
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101215103200Z
entryCSN: 20101215103200.314479Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101215103200Z

dn: uid=jacques,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Jacques Jacques
uid: jacques
uidNumber: 1002
gidNumber: 100
homeDirectory: /home/jacques
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Jacques du courrier
structuralObjectClass: posixGroup
entryUUID: 4b4d8638-9c82-102f-9638-c30d47b24027
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101215103200Z
entryCSN: 20101215103200.345415Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101215103200Z

dn: uid=martine,ou=utilisateurs,dc=pedrono,dc=fr
objectClass: posixAccount
objectClass: posixGroup
cn: Martine Martine
uid: martine
uidNumber: 1003
gidNumber: 100
homeDirectory: /home/martine
userPassword:: JDYkY3ouTXFyR3VVVkh6NHlaRyQ2ZE9KWWdtRUo4aDZUbjByLnNZSFBZclgudU0
 zeERIN3hWN3dUaXEzT1dPZHRablhYRWtrVk1HNmluRmpBeUFDTnJpZmxRZG8uZy4yRWpsaWcwQ1hS
 MA==
loginShell: /bin/bash
description: Martine la secretaire
structuralObjectClass: posixGroup
entryUUID: 4b53e9d8-9c82-102f-9639-c30d47b24027
creatorsName: cn=Manager,dc=pedrono,dc=fr
createTimestamp: 20101215103200Z
entryCSN: 20101215103200.387287Z#000000#000#000000
modifiersName: cn=Manager,dc=pedrono,dc=fr
modifyTimestamp: 20101215103200Z

L'intérêt étant de pouvoir reconstruire son annuaire sur la base de ce dump LDIF, on utilisera plutôt:

[root@kjh conf_ldap]# slapcat -b dc=pedrono,dc=fr > 20101215_bkp_global.ldif


Manipulation des données d'annuaire à l'aide des commandes ldap*

ldapsearch

On a déjà vu l'utilisation basique de ldapsearch, sur tout ou partie de notre annuaire.

Cf p90 du support de cours.

Il est possible d'utiliser des filtres à ce niveau pour n'obtenir que certaines informations dans certaines conditions, ex. ci dessous on ne cherche que l'attribut postalCode de notre OU utilisateurs:

[root@kjh conf_ldap]# ldapsearch -x -b 'ou=utilisateurs,dc=pedrono,dc=fr' -D 'cn=Manager,dc=pedrono,dc=fr' postalCode -W
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <ou=utilisateurs,dc=pedrono,dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: postalCode 
#

# utilisateurs, pedrono.fr
dn: ou=utilisateurs,dc=pedrono,dc=fr
postalCode: 44000

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

ldapmodify

Permet de modifier des entités dans l'annuaire.

Cf p91 du support de cours.

Outils complémentaires de parcours d'annuaire

JXplorer

Page officielle de JXplorer

Apache Directory Studio

Page Apache sur Apache Directory Studio

Applications concrètes de LDAP

Authentification Linux sur OpenLDAP

Un howto de mise en place de l'authentification Linux via LDAP

Tentative d'application tel que décrit dans le support

Cf page 93 du support de cours.

Principes généraux:

  • Possibilité de configuration via l'outil graphique system-config-authentication.
  • Sinon bonne vieille méthode en ligne de commande dans les fichiers linux gérant l'authentification:
    • /etc/pam.d/system-auth
    • /etc/nsswitch.conf
    • /etc/openldap/ldap.conf
  • Il est nécessaire d'installer les modules ldap pour pam:
yum install pam_ldap

ATTENTION: il faut également configurer le module LDAP via le fichier /etc/pam_ldap.conf.

Il peut être nécessaire, après modification des fichiers ci-dessous (surtout nsswitch.conf), de redémarrer le démon sssd:

/etc/init.d/sssd restart

Contenu de system-auth:

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
#auth        sufficient    pam_fprintd.so
#auth        sufficient    pam_unix.so nullok try_first_pass
auth        sufficient    pam_unix.so likeauth nullok
auth        sufficient    pam_ldap.so use_first_pass
#auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_ldap.so
#account     sufficient    pam_localuser.so
#account     sufficient    pam_succeed_if.so uid < 500 quiet
#account     required      pam_permit.so

#password    requisite     pam_cracklib.so try_first_pass retry=3 type=
password    required      pam_cracklib.so retry=3 minlen=2 dcredit=0 ucredit=0
#password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    sufficient    pam_unix.so nullok use_authtok md5 shadow
password    sufficient    pam_ldap.so use_authok
password    required      pam_deny.so

#session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     required      pam_unix.so
session     optional      pam_ldap.so
#-session     optional      pam_systemd.so
#session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid

Contenu de nsswitch.conf:

passwd:     files ldap
shadow:     files ldap
group:      files ldap

#hosts:     db files nisplus nis dns
hosts:      files dns

# Example - obey only what nisplus tells us...
#services:   nisplus [NOTFOUND=return] files
#networks:   nisplus [NOTFOUND=return] files
#protocols:  nisplus [NOTFOUND=return] files
#rpc:        nisplus [NOTFOUND=return] files
#ethers:     nisplus [NOTFOUND=return] files
#netmasks:   nisplus [NOTFOUND=return] files

bootparams: nisplus [NOTFOUND=return] files

ethers:     files
netmasks:   files
networks:   files
protocols:  files
rpc:        files
services:   files

netgroup:   nisplus

publickey:  nisplus

automount:  files nisplus
aliases:    files nisplus

Contenu de ldap.conf:

BASE    dc=pedrono,dc=fr
#URI    ldap://ldap.example.com ldap://ldap-master.example.com:666
URI     ldap://localhost
ldap_version 3

# Authentication
rootbinddn cn=Manager,dc=pedrono,dc=fr

# Pour NSS et PAM
pam_password MD5
nss_base_passwd ou=utilisateurs,dc=pedrono,dc=fr?one
nss_base_shadow ou=utilisateurs,dc=pedrono,dc=fr?one
nss_base_group ou=groupes,dc=pedrono,dc=fr?one

ATTENTION: dans le cadre de cette formation, ne pas oublier d'activer par défaut slapd sur le runlevel 5 (runlevel actuel):

[root@kjh bkp_auth_systeme]# chkconfig --level 5 slapd on

Application nouvelle mode pour Fedora 14

yum install pam_ldap

/etc/pam_ldap.conf:

  • binddn
  • rootbinddn
  • base (à faire pointer sur l'OU utilisateurs

Changer les droits de /etc/pam_ldap.secret en 600 (ce fichier contient le mot de passe en clair du rootdn de notre annuaire).

/etc/pam.d/system-auth:

  • copier les lignes pam_nss
  • remplacer pam_nss par pam_ldap
  • commenter pam_nss

En principe cela suffit.

Liens

Page wikipedia sur LDAP Tutorial INRIA

Lexique

  • rootdn: utilisateur gestionnaire du service, non soumis aux ACL
  • DN: Distinguished Name
  • RDN: Relative DN
  • Node: Noeud de l'arbre de l'annuaire (élément intermédiaire)
  • Leaf: Feuille de l'arbre de l'annuaire (élément terminal)