2. Service d'identité

Le service d'identité permet de fournir des services d'authentification et d'autorisation aux utilisateurs et aux services dans un réseau. Ceci peut être implémenté à travers plusieurs protocoles tout dépendant du type de client. Voici les protocoles disponibles :

L'utilisation LDAP avec Mandriva Corporate Server 4 est fortement recommandée psuiqu'il tente de l'utiliser pour le plus grand nombre de services possibles. Pour ce faire, utilisez le paquetage openldap-mandriva-dit. Ce paquetage installe un arbre LDAP de base prêt à héberger les services suivants :

Dans ce chapitre, nous nous concentrons sur l'authentification et l'autorisation en utilisant OpenLDAP puis, plus tard, Kerberos. Pour des renseignements supplémentaires sur comment utiliser DNS, DHCP ou sudo avec LDAP, veuillez consulter le chapitre correspondant.

Après avoir lu ce chapitre, vous serez en mesure d'exécuter les opérations suivantes :

2.1. Concepts généraux

Comptes, groupes administratifs et arborescence.

2.1.1. Annuaires

Nous présenterons ici quelques concepts généraux à propos de LDAP, la gestion des utilisateurs et des groupes.

Les serveurs d'annuaires peuvent être vus comme des bases de données stockant des renseignements. LDAP est le protocole utilisé pour accéder à ces services :

Figure 6.5. Protocole LDAP

Protocole LDAP

Le type de bases de données varie beaucoup entre les implémentations. Ce pourrait être une base de données relationnelle standard, une base de données plus spécialisées comme Berkeley DB, un script dynamique qui génère la sortie, etc.

Toutefois, LDAP tend à être comparé aux bases de données relationnelles (SQL). Il existe des différences importantes :

  • hiérarchie : au lieu d'utiliser des tables avec des entrées et des champs, il utilise des arbres et des notes, un peu comme un système de fichiers ;

  • optimisation pour la lecture : d'habitude, les annuaires affichent beaucoup plus d'accès en lecture que de tentatives d'écriture ;

  • distribué : l'arborescence permet aux branches d'être stockées ailleurs sans compromettre la vue d'ensemble ;

  • une forte standardisation : le type de donnée stocké dans un annuaire relève d'une forte standardisation, autant dans le nom des données que dans son type. Ceci s'appuie habituellement sur un RFC.

Voici un court exemple d'un arbre qui s'étend sur plus d'un serveur :

Figure 6.6. Arbre LDAP

Arbre LDAP

Les services d'authentification et d'autorisation sont de bons candidats pour l'utilisation d'un annuaire. Vu qu'ils ont besoin de performance de lecture maximale, ils subissent moins d'opérations d'écriture et peuvent être distribués dans une structure, tout en restant connectés.

L'ensemble de règles concernant les données stockées dans un annuaire s'appelle un schéma. Le schéma d'annuaire définit plusieurs éléments :

  • classes d'object : elles définissent la nature d'une entrée et le type d'information qu'elle contient ;

  • attributs : les données elles-mêmes, similaires à un champ dans une base de données standard ;

  • indexation et règles d'ordonnancement : spécifie comment doit fonctionner la recherche sur un attribut spécifique, et comment il doit être trié ;

  • type de valeur : définit le type de donnée que l'attribut devrait contenir (numérique, chaîne, objet binaire, etc).

Le schéma souffre du complexe amour/haine. Il est avantageux pour la standardisation, mais il est parfois difficile d'ajouter des données à un annuaire. Alors que dans une base de données, c'est aussi simple que d'ajouter un nouveau champ, dans un annuaire, vous devez obéir au schéma. Vous ne pouvez pas simplement ajouter n'importe quel type d'attribut à une entrée : seulement ceux alloués par les classes d'objet.

Par exemple, voici la définition d'une classe d'objet person :

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

Ceci nous dit :

  • cet objet est défini dans le RFC 2256 ;

  • c'est un objet structurel ;

  • les attributs sn et cn sont obligatoires ;

  • les attributs optionnels userPassword, telephoneNumber, seeAlso et description sont admissibles dans une entrée utilisant cette classe d'objet.

Figure 6.6, « Arbre LDAP » illustre aussi les attributs obligatoires et certains attributs optionnels de la classe d'objet person.

2.1.2. Arborescence, groupes et privilèges

Le paquetage openldap-mandriva-dit offre une arborescence qui peut héberger les services décrits, ainsi que l'authentification et l'autorisation. Voici l'arborescence :

Figure 6.7. Arborescence

Arborescence

La première entrée de l'annuaire, dc=example,dc=com, est substituée lors de l'installation par le domaine DNS détecté.

Chaque groupe possède un ensemble de privilèges assignés à ses membres, et ce par défaut. Le membre initial est l'administrateur du groupe dans la branche Comptes système. Les privilèges sont tels que chaque membre peut administrer la branche de service respective. Donc, les membres du groupe Sudo Admins peuvent lire et écrire sur la branche ou=Sudoers.

Les autres groupes qui ne sont pas directement associés à un service sont décrits plus bas :

  • LDAP Admins : peuvent lire et écrire sur n'importe quelle partie de l'arbre. Ils sont aussi exempts de limite de taille ou de temps.

  • DNS Readers : seul les membres de ce groupe peuvent lire la branche ou=DNS.

  • LDAP Replicators : les membres peuvent lire toutes les parties de l'annuaire et ne sont pas sujets à des limites de taille ou de temps.

  • Account Admins : les membres peuvent créer de nouveaux comptes (unix, samba ou kerberos) sous les branches ou=People, ou=Group et ou=Hosts.

  • MTA Admins : les membres peuvent écrire sur certains attributs spécifiques reliés au courriel :

    • tous les attributs utilisés par la classe d'objet inetLocalMailRecipient ;

    • l'attribut mail.

  • LDAP Monitors : les membres peuvent lire l'arbre spécial cn=Monitor, qui héberge des données statistiques en direct au sujet du serveur OpenLDAP.

Par défaut, deux comptes supplémentaires sont fournis avec cet arbre : smbldap-tools et nssldap. Le premier est utilisé par la suite d'outils smbldap-tools et est membre du groupe Account Admins. Le deuxième, nssldap, est un compte de lecture générique et n'est pas utilisé par défaut par un quelconque service. Il est fourni par commodité pour l'administrateur. Aucun ACL spécial n'est en place pour ce compte.

2.1.3. Installation

Fibric possède une option pour installer la pile « intergiciel d'identité » (Identity Middleware) qui installe l'arbre dont nous venons de traiter. Une configuration de base est également faite :

Figure 6.8. Installer la pile Identity

Installer la pile Identity

Dans la pile Identity, l'option kerberos installera MIT Kerberos, et non Heimdal. Si vous avez besoin de l'intégration Kerberos avec LDAP, jetez un coup d'œil à la section d'authentification par Kerberos, qui traite de ce type d'intégration.

Après que les paquetages de Identity Stack ont été installés, (openldap-server et krb5-server), la pile peut être configurée. L'écran de configuration, quoique simple, configure complètement un arbre LDAP, qui répond à quelques besoins :

Figure 6.9. Configurer la pile Identity

Configurer la pile Identity

Le paquetage openldap-mandriva-dit contient aussi un script d'installation qui peut être exécuté depuis une console. Le script est installé dans /usr/share/openldap/scripts/mandriva-dit-setup.sh et fait les mêmes modifications que Fibric, lesquelles sont :

  • parle au domaine DNS (en suggérant ce qui a été détecté automatiquement) ;

  • construit l'entrée de l'annuaire de premier niveau depuis ce domaine en utilisant des attributs de style dc ;

  • crée et importe un fichier ldif contenant les comptes et groupes décrits ici ;

  • installe de nouveaux fichiers slapd.conf et mandriva-dit-access.conf (faisant des sauvegardes des fichiers précédents) avec les ACL par défaut et d'autres configurations utiles (comme la cache) ;

  • charge le fichier ldif, faisant une sauvegarde de l'annuaire de base de données précédent.

Même si le script fait plusieurs tests et sauvegarde plusieurs fichiers avant de les écraser, nous avisons les administrateurs de faire une copie de sauvegarde de leurs données avant de l'exécuter.

Voici un exemple utilisant le domaine dc=example,dc=com :

# /usr/share/openldap/scripts/mandriva-dit-setup.sh
Please enter your DNS domain name [mycompany.com]:
example.com


Administrator account

The administrator account for this directory is
uid=LDAP Admin,ou=System Accounts,dc=example,dc=com

Please choose a password for this account:
New password: secretpass
Re-enter new password: secretpass


Summary
=======

Domain:      example.com
LDAP suffix: dc=example,dc=com

Confirm? (Y/n)            Y
config file testing succeeded
Stopping ldap service
Finished, starting ldap service
Running /usr/bin/db_recover on /var/lib/ldap
removing /var/lib/ldap/alock
Starting slapd (ldap + ldaps):                                  [  OK  ]

Your previous database directory has been backed up as /var/lib/ldap.1145397294
   

Maintenant le service ldap est fonctionnel. Vous pouvez utiliser le compte administrateur avec le mot de passe que nous venons de régler pour peupler l'arbre. C'est le seul compte activé dans l'arbre jusqu'à présent : tous les autres sont désactivés. Pour activer le compte d'administration, il doit posséder un mot de passe. Par exemple, activons le compte DNS Admin :

$ ldappasswd -x -D "uid=LDAP Admin,ou=System Accounts,dc=example,dc=com" \  
  -W -S "uid=DNS Admin,ou=System Accounts,dc=example,dc=com"
New password: newsecret
Re-enter new password: newsecret
Enter LDAP Password: here is the password for the bind (-D) user: LDAP Admin
Result: Success (0)
   

Maintenant, le compte DNS Admin possède un mot de passe et peut être utilisé pour administrer la branche ou=dns de l'arbre.

2.2. Authentification des utilisateurs UNIX

Cet arbre n'a rien de spécial en regard des comptes POSIX (comptes UNIX traditionnels) :

  • ou=People : branche qui contient les comptes de personnes (sauf kerberos). Donc, un compte utilisateur pourrait être quelque chose comme uid=john,ou=People,dc=example,dc=com. Ces entrées doivent posséder au moins la classe d'objet posixAccount.

  • ou=Group : les comptes de groupe vont dans cette branche. Par exemple, on pourrait avoir cn=marketing,ou=Group,dc=example,dc=com. Ces entrées doivent posséder au moins une classe d'objet posixGroup.

Le groupe qui peut écrire sur ces branches est cn=Account Admins,ou=System Groups,dc=example,dc=com. Le propriétaire et membre initial de ce groupe est uid=Account Admin,ou=System Accounts,dc=example,dc=com.

Par défaut, tous les comptes système sauf LDAP Admin sont bloqués. Pour en utiliser un, vous devez lui régler un mot de passe. L'exemple ci-dessous active le compte Account Admin en lui assignant un mot de passe :

$ ldappasswd -x -D "uid=LDAP Admin,ou=System Accounts,dc=example,dc=com" -W -S "uid=Account Admin,ou=System Accounts,dc=example,dc=com"
New password: password for account admin
Re-enter new password: retype it
Enter LDAP Password: 
Result: Success (0)
  

Ceci utilise le compte LDAP Admin (son mot de passe a été réglé durant l'installation, soit par Fibric ou par le script de réglage) pour régler un mot de passe pour Account Admin, qui est maintenant activé et peut être utilisé pour ajouter, supprimer ou modifier des utilisateurs et des groupes.

2.2.1. Créer un compte

Plusieurs frontaux (front-end) existent pour LDAP et ils peuvent créer des comptes POSIX. Voici un exemple rapide en utilisant le programme Luma. Il possède plusieurs greffons (plugins) et un de ceux-ci permet de gérer les utilisateurs :

Figure 6.10. Greffon Luma

Greffon Luma

Voici le greffon de gestion des utilisateurs :

Figure 6.11. Greffon de gestion des utilisateurs

Greffon de gestion des utilisateurs

Premièrement, il faut indiquer sur quel serveur et quelle branche vous voulez ajouter un utilisateur. Dans cet exemple, nous nous plaçons sur la branche ou=People :

Figure 6.12. Où ajouter un utilisateur

Où ajouter un utilisateur

Ensuite, nous entrons l'information nécessaire pour cet utilisateur :

Figure 6.13. Ajouter un utilisateur

Ajouter un utilisateur

Il est nécessaire de spécifier au moins un groupe primaire pour cet utilisateur. Les groupes POSIX LDAP seront automatiquement affichés, mais si vous n'en avez pas, alors la liste sera vide. Maintenant, nous sélectionnons gidNumber=100, qui appartient au groupe local users :

Figure 6.14. Groupes

Groupes

Voici à quoi ressemble notre nouvel utilisateur dans LDAP :

Figure 6.15. Peter dans LDAP

Peter dans LDAP

[Avertissement] Avertissement

Luma tentera de trouver un uidNumber libre pour l'allouer à cet utilisateur. Vous devriez toujours être prudent, toutefois, parce qu'il est incorrect que deux utilisateurs possèdent le même uidNumber.

2.2.2. Créer des groupes

Les groupes UNIX sont représentés dans LDAP en utilisant la classe posixGroup. Une entrée typique pour un groupe ressemble à :

    dn: cn=ldapusers,ou=Group,dc=example,dc=com
    objectClass: posixGroup
    gidNumber: 1024
    cn: ldapusers
    memberUid: peter
    memberUid: queen
   

Cette entrée définit un groupe appelé ldapusers avec un numéro d'identification de 1024 et, jusqu'à présent, deux membres appelés peter et queen.

Cette structure est assez simple pour être créée manuellement. Il faut simplement être prudent de ne pas donner le même numéro d'identification à plus d'un groupe.

[Note] Note

Les groupes système utilise une classe d'objet différente : groupOfNames. La différence principale est que l'adhésion est définie par un DN complet au lieu de seulement un nom, comme c'est le cas pour posixGroup. Malheureusement, posixGroup et groupOfUniqueNames ne peuvent pas être utilisés en même temps parce qu'ils tous les deux des classes structurelles. Nous nous attendons à ce que la révision du RFC2307 redéfinisse posixGroup en tant que classe auxiliaire.

2.2.3. Déléguer des privilèges d'administration

Tous les membres du groupe cn=Account Admins,ou=System Groups,dc=example,dc=com peuvent gérer des comptes utilisateur dans ou=People, ou=Group et ou=Hosts (pour Samba, qui est expliqué plus loin). Tout administrateur LDAP (LDAP Admin) ou l'utilisateur Account Admin lui-même peut ajouter des membres à ce groupe.

[Astuce] Astuce

Les groupes système ont des propriétaires, et par défaut, le propriétaire peut toujours éditer l'adhésion du groupe qu'il possède. Pour voir qui est le propriétaire, vérifiez l'attribut owner du groupe système en question.

Par exemple, ajoutons l'utilisateur Peter Pingus, que nous venons de créer, à ce groupe privilégié pour qu'il puisse gérer des comptes :

$ ldapmodify -x -D 'uid=Account Admin,ou=System Accounts,dc=example,dc=com' -W
Enter LDAP Password: secretpassword 
dn: cn=Account Admins,ou=System Groups,dc=example,dc=com
changetype: modify
add: member
member: uid=peter,ou=People,dc=example,dc=com

^D
modifying entry "cn=Account Admins,ou=System Groups,dc=example,dc=com"
   

La même opération peut être faite avec un client graphique. Ajoutez simplement l'attribut member en pointant vers l'utilisateur dn que vous voulez ajouter à ce groupe.

2.3. Authentification Samba

Pour utiliser ce DIT avec Samba, suivez cet exemple :

  • Disposition en LDAP

    Voici la disposition qui doit être configurée dans /etc/samba/smb.conf et /etc/smbldap-tools/smbldap.conf :

    • comptes machine : sous ou=Hosts ;

    • comptes utilisateur : sous ou=People ;

    • comptes groupe : sous ou=Group ;

    • branche idmap : sous ou=Idmap.

  • ldap admin dn

    Pour le paramètre de configuration ldap admin dn dans /etc/samba/smb.conf, utilisez un membre du groupe Account Admins. Par exemple :

         ldap admin dn = uid=Account Admin,ou=System Accounts,dc=example,dc=com
        
  • smbldap-tools

    Dans /etc/smbldap-tools/smbldap_bind.conf, utilisez l'utilisateur smbldap-tools au lieu du rootdn de l'annuaire :

         masterDN="uid=smbldap-tools,ou=System Accounts,dc=example,dc=com"
        

    Cet utilisateur est membre du groupe Account Admins. Si vous voulez utiliser un autre compte, assurez-vous qu'il est membre du même groupe. Sinon, les ACL OpenLDAP par défaut ne fonctionneront pas.

  • smbldap-populate

    Dans la version 0.9.2, le comportement par défaut de smbldap-populate est de créer un compte administrateur avec les attributs suivants :

    • uidNumber = 0

    • gidNumber = 0

    • name: root

    • membre de Domain Admins

    Ceci signifie que l'utilisateur root est créé dans LDAP. Nous ne vous recommandons pas d'utiliser cette commande avec smbldap-populate :

    # smbldap-populate -a Administrator -k 1000 -m 512
        

    Ceci crée un utilisateur dont le nom est Administrator, uidNumber 1000 et gidNumber 512. Vous pouvez aussi utiliser uidNumber 500 si vous voulez qu'il concorde avec le RID de Windows® pour ce type d'utilisateur.

    Plus tard, on pourrait donner des privilèges au groupe Domain Admins (voir la commande net rights grant), ou vos répertoires partagés pourraient utiliser le paramètre admin users.

  • IDMAP

    Si vous utilisez le système dorsal (backend) LDAP de IDMAP sur un serveur membre, réglez le paramètre de configuration ldap admin dn configuration dans /etc/samba/smb.conf au dn d'un membre du groupe Idmap Admins. Par exemple :

         ldap admin dn = uid=Idmap Admin,ou=System Accounts,dc=example,dc=com
        

    Sur les serveurs membres, il n'est pas nécessaire d'utiliser le compte Account Admin : le group Idmap Admins est celui à utiliser puisqu'il ne peut écrire qu'au conteneur ou=Idmap.

    [Avertissement] Avertissement

    Dans LDAP, il y a une vulnérabilité potentielle avec IDMAP. Vu que toutes les machines de domaine doivent avoir les droits d'écriture à cette branche de l'annuaire (et donc ont besoin d'un mot de passe en clair stocké en quelque part), un utilisateur malicieux ayant les privilèges de root pourrait obtenir le mot de passe root et créer n'importe quelle table de correspondance identique (identity mapping) dans ou=Idmap. Lisez ce fil sur la liste Samba pour plus de renseignements.

2.3.1. Créer des comptes Samba

La manière recommandée de créer des comptes Samba sur LDAP est d'utiliser le paquetage smbldap-tools. Ce paquetage possède plusieurs outils pour ajouter, supprimer ou modifier des utilisateurs et des groupes dans un arbre LDAP avec les attributs de Samba. Il peut même être utilisé avec les attributs de Samba et traiter avec ceux de POSIX.

2.4. Authentification Kerberos

OpenLDAP peut être utilisé en tant que système dorsal pour la base de données Heimdal, ce qui signifie que les comptes principaux peuvent être stockés sur LDAP. Dans cette section, nous présentons les étapes nécessaires pour intégrer le système dorsal LDAP de Heimdal avec OpenLDAP et openldap-mandriva-dit. Si vous n'avez pas besoin de cette caractéristique, vous pouvez utiliser le serveur Kerberos par défaut, qui utilise les paquetages MIT, et sauter le texte qui suit.

Nous commencerons avec un nouvel univers que nous appellerons EXAMPLE.COM. Nous assumons que openldap-mandriva-dit est installé et que le script fourni a été exécuté, soit manuellement ou via Fibric.

Lorsque vous utilisez le backend LDAP, nous vous recommandons d'avoir un script pour créer les utilisateurs, puisque Heimdal, par défaut, utilise la classe d'objet structurel account. Comme il est plus courant d'utiliser inetOrgPerson (ou une classe dérivée), l'entrée principale devrait être supprimée et ajoutée à nouveau plus tard avec inetOrgPerson.

Une autre approche est de créer en premier lieu l'utilisateur avec les outils standards (smbldap-tools, un script manuel, un modèle dans gq ou luma, etc.) et ensuite d'ajouter les attributs kerberos plus tard. Nous documentons les deux approches.

2.4.1. Paquetages

En raison de conflits avec le paquetage Kerberos de MIT, Heimdal est packagé comme suit dans Mandriva Corporate Server 4 :

  • heimdal-libs

  • heimdal-server

  • heimdal-workstation

  • heimdal-devel

Les conflits ont été résolus. Seulement heimdal-libs peut être installé concurremment avec les bibliothèques de MIT.

2.4.2. Survol des changements

Voici un survol rapide des changements nécessaires pour que Heimdal puisse utiliser OpenLDAP en tant que système dorsal de base de données, et utiliser le DIT openldap-mandriva-dit :

  • configurez Heimdal pour qu'il utilise LDAP en tant que backend ;

  • configurez OpenLDAP pour qu'il accepte les connexions depuis Heimdal via ldapi:// ;

  • testez cette table de correspondance ;

  • initialisez la base de données ;

  • gérez les comptes utilisateur.

2.4.3. Heimdal avec OpenLDAP

Afin d'obtenir une base de données sur LDAP, la section [kdc] suivante doit être utilisée dans le fichier /etc/krb5.conf de Heimdal :

    [kdc]
    database = {
    dbname = ldap:ou=People,dc=example,dc=com
    mkey_file = /var/heimdal/mkey
    acl_file = /var/heimdal/kadmind.acl
    }
   

Ceci donnera comme directive à Heimdal d'utiliser le serveur OpenLDAP installé sur le même hôte et d'utiliser la branche ou=People pour ces principaux. La méthode d'accès Heimdal utilise ldapi://, qui est une interface de connexion (socket) UNIX sur le système de fichiers local. L'authentification est gérée par SASL EXTERNAL, que nous configurerons à l'instant.

2.4.4. Utilisation de ldapi

OpenLDAP doit être configuré pour accepter les connexions via ldapi://. Il faut éditer le fichier /etc/sysconfig/ldap. Changez la liste SLAPD URL pour celle-ci :

    # SLAPD URL list
    SLAPDURLLIST="ldap:/// ldaps:/// ldapi:///"
   

OpenLDAP doit ensuite être redémarré.

2.4.5. Utilisation de SASL EXTERNAL

Heimdal utilise SASL EXTERNAL pour s'authentifier au serveur OpenLDAP lorsqu'il se connecte via une interface de connexion ldapi://. Ce faisant, le lien dn devient :

    # ldapwhoami -Y EXTERNAL -H ldapi:///var/run/ldap/ldapi
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn:gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    Result: Success (0)
   

Nous allons lier ce dn à un binddn plus significatif via authz-regexp. Le fichier slapd.conf fourni avec openldap-mandriva-dit fait déjà cela, mais dans un souci d'exhaustivité, le voici de toute manière :

    (...)
    ppolicy_default "cn=default,ou=Password Policies,dc=example,dc=com"
    
    authz-regexp "gidNumber=0\\\+uidNumber=0,cn=peercred,cn=external,cn=auth"
    "uid=Account Admin,ou=System Accounts,dc=example,dc=com"
    authz-regexp ^uid=([^,]+),cn=[^,]+,cn=auth$ uid=$1,ou=People,dc=example,dc=com
   

Avec cette modification et après avoir redémarré OpenLDAP, ldapwhoami sait maintenant que nous sommes le Account Admin :

    # ldapwhoami -Y EXTERNAL -H ldapi:///var/run/ldap/ldapi
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn:uid=account admin,ou=system accounts,dc=example,dc=com
    Result: Success (0)
   

Notez que tout processus connectant à l'interface de connexion ldapi:// en tant que root (uid=0, gid=0) sera traité comme un Account Administrator après ce changement!

2.4.6. Initialisation de ce nouvel univers

Nous pouvons maintenant initialiser l'univers Kerberos. Après que OpenLDAP aura été redémarré, exécutez la commande suivante :

    # kadmin -l
    kadmin> init EXAMPLE.COM
    Realm max ticket life [unlimited]:7d
    Realm max renewable ticket life [unlimited]:7d
    kadmin
   

Ceci créera quelques principaux par défaut sous ou=People :

ou=People
  krb5PrincipalName=krbtgt/EXAMPLE.COM@EXAMPLE.COM,ou=People,dc=example,dc=com
  krb5PrincipalName=kadmin/changepw@EXAMPLE.COM,ou=People,dc=example,dc=com
  krb5PrincipalName=kadmin/admin@EXAMPLE.COM,ou=People,dc=example,dc=com
  krb5PrincipalName=changepw/kerberos@EXAMPLE.COM,ou=People,dc=example,dc=co
  krb5PrincipalName=kadmin/hprop@EXAMPLE.COM,ou=People,dc=example,dc=com
  krb5PrincipalName=default@EXAMPLE.COM,ou=People,dc=example,dc=com
   

2.4.7. Gestion des comptes utilisateur et principal

Le schéma Heimdal permet aux comptes principaux d'être stockés sur une branche différente de celles des comptes utilisateurs. Par exemple, vous pourriez placer les comptes principaux sous ou=KerberosPrincipals et les comptes utilisateurs sous ou=People.

Cette façon de faire possède un désavantage évident, soit de créer un problème dans la gestion des utilisateurs : lorsqu'un utilisateur est supprimé, par exemple, le compte principal correspondant est aussi supprimé. En d'autres mots, nous aurions besoin d'un pointeur dans l'entrée utilisateur pour le compte principal (l'attribut seeAlso est couramment utilisé pour des manœuvres de ce genre). Et un script devrait suivre cet attribut et supprimer le compte principal.

L'avantage serait qu'un utilisateur peut être associé avec plusieurs principaux kerberos en utilisant l'attribut seeAlso, comme john@UNIVERS et john/admin@UNIVERS.

Le plus gros désavantage des schémas où les principaux sont séparés des utilisateurs est l'intégration avec Samba et Ldap simple binds : il est perdu ! Heimdal ne mettra à jour que le hash du mot de passe de Samba s'il est stocké dans la même entrée. La même chose se produit avec userPassword : vu qu'OpenLDAP utilise le module smbk5pwdi (compilé en prenant en charge kerberos), les liens simples ne pourront qu'utiliser le mot de passe de kerberos si tout est dans la même entrée.

Une autre option serait de stocker les clés principales et les attributs qui y sont relatifs juste sous l'entrée utilisateur. Nous pouvons faire cela car les classes d'objet kerberos sont auxiliaires. Donc, l'utilisateur John serait, par exemple : uid=john,ou=people,dc=example,dc=com, et les clés kerberos seraient stockées dans cette même entrée. Lorsque cet utilisateur est supprimé, le compte principal l'est aussi. Le désavantage est qu'un utilisateur ne peut avoir qu'un principal, et non plusieurs comme dans le cas précédent (où john pouvait avoir john@UNIVERS et john/admin@UNIVERS associés à la même entrée uid=john,ou=people,dc=example,dc=com).

Mais un problème surgit : qu'utilisons-nous pour créer cet utilisateur en premier lieu? Si nous utilisons kadmin, cela créera une entrée de la forme suivante : krb5PrincipalName=john@EXAMPLE.COM,ou=People,dc=example,dc=com, le compte étant la classe d'objet structurel. Comme nous tendons à utiliser une classe dérivée de person en tant que classe structurelle (comme inetOrgPerson), il y a conflit. Si nous utilisons kadmin, nous aurions à supprimer l'entrée et à l'ajouter à nouveau avec inetOrgPerson (et ses attributs obligatoires).

Nous pouvons changer la classe structurelle que Heimdal utilisera, mais cela n'ajoute pas les attributs obligatoires alors nous ne pouvons pas simplement changer pour inetOrgPerson dans la configuration de Heimdal : ça ne marchera pas.

Une meilleure option serait de créer en premier lieu l'utilisateur avec un autre outil comme smbldap ou un autre script, puis ajouter les attributs kerberos plus tard. Les avantages principaux sont :

  • le nommage RDN demeurera constant avec le reste des entrées (aucun krb5PrincipalName dans le RDN si nous n'en voulons pas) ;

  • le paramétrage de la classe d'objet structurel peut se faire comme bon nous semble (par exemple, inetOrgPerson) ;

  • les comptes utilisateur et principal sont ensemble sous ou=People.

Le plus gros désavantage est que la table de correspondance entre les utilisateurs et les principaux serait de 1:1, ce qui signifie qu'un utilisateur pourrait avoir au plus un principal kerberos associé avec son entrée.

Toutefois, les deux schémas peuvent être utilisés ensemble. La question qui nous préoccupe est plutôt comment allons nous gérer les comptes. Donc, les utilisateurs réguliers pourraient stockés leur clé kerberos dans l'entrée utilisateur, tandis que les clés d'administration et de service pourraient être stockés sous la même branche, mais qu'aucun utilisateur n'y soit associé. Ce n'est pas très constant en regard de l'arbre (après tout, ou=People était censé hébergé des personnes), mais ça marche.

Nous continuons avec deux exemples : l'utilisation de kadmin directement, et l'utilisation d'un autre script pour créer en premier lieu le compte utilisateur et ensuite, ajouter les attributs kerberos.

2.4.8. Utilisation de kadmin directement

Nous allons créer un compte kerberos pour l'utilisateur « john » en utilisant kadmin directement. Nous n'avons pas à démarrer Heimdal à ce stade puisque nous allons utiliser kadmin en mode local :

    # kadmin -l
    kadmin> add john
    Max ticket life [1 day]:10h
    Max renewable life [1 week]:1w
    Principal expiration time [never]:
    Password expiration time [never]:
    Attributes []:
    john@EXAMPLE.COM's Password: somesecretpassword
    Verifying - john@EXAMPLE.COM's Password: somesecretpassword
    kadmin>
   

Cela crée l'entrée suivante :

    dn: krb5PrincipalName=john@EXAMPLE.COM,ou=People,dc=example,dc=com
    objectClass: top
    objectClass: account
    objectClass: krb5Principal
    objectClass: krb5KDCEntry
    krb5PrincipalName: john@EXAMPLE.COM
    uid: john
    krb5KeyVersionNumber: 0
    krb5MaxLife: 36000
    krb5MaxRenew: 604800
    krb5KDCFlags: 126
    (...)
   

On peut obtenir un billet pour cet utilisateur :

    # service heimdal start
    Starting kdc:                                                  [  OK  ]
    # kinit john
    john@EXAMPLE.COM's Password: somesecretpassword
    # klist
    Credentials cache: FILE:/tmp/krb5cc_0
    Principal: john@EXAMPLE.COM

    Issued           Expires          Principal
    Jun 20 15:43:23  Jun 20 22:23:23  krbtgt/EXAMPLE.COM@EXAMPLE.COM
    #
   

Cependant, remarquez que l'utilisateur john n'a pas les attributs POSIX nécessaires pour devenir un utilisateur système. De toute façon, nous avons besoin d'autre chose pour créer cet utilisateur POSIX : ici, le rôle de Heimdal est terminé.

2.4.9. Ajouter des attributs kerberos à une entrée existante

Si le compte utilisateur existe déjà dans l'annuaire, nous n'avons qu'à ajouter les classes d'objet Heimdal nécessaires pour ce compte. Étant un auxiliaire, cela fait beaucoup de sens.

Donc, pour cet exemple, nous utiliserons un paquetage smbldap-tools préconfiguré pour créer un utilisateur modèle et ensuite, nous lui ajouterons les classes kerberos et les attributs, mais n'importe quel utilisateur POSIX déjà existant marcherait.

Remarquez que nous n'ajoutons pas les attributs Samba tout de suite :

    # smbldap-useradd mary
    # getent passwd mary
    mary:x:1001:513:System User:/home/mary:/bin/bash
   

L'utilisateur ressemble à ceci dans l'annuaire :

    dn: uid=mary,ou=People,dc=example,dc=com
    objectClass: top
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    objectClass: posixAccount
    objectClass: shadowAccount
    cn: mary
    sn: mary
    givenName: mary
    uid: mary
    uidNumber: 1001
    gidNumber: 513
    homeDirectory: /home/mary
    loginShell: /bin/bash
    gecos: System User
    userPassword: {crypt}x
   

Nous utiliserons la modification LDAP suivante pour ajouter les attributs et classes kerberos à cet utilisateur :


    $ ldapmodify -x -D 'uid=Account Admin,ou=System Accounts,dc=example,dc=com' -W
    Enter LDAP Password: somepassword
     dn: uid=mary,ou=people,dc=example,dc=com
     changetype: modify
     add: objectClass
     objectClass: krb5Principal
     objectClass: krb5KDCEntry
     -
     add: krb5PrincipalName
     krb5PrincipalName: mary@EXAMPLE.COM
     -
     add: krb5KDCFlags
     krb5KDCFlags: 126
     -
     add: krb5KeyVersionNumber
     krb5KeyVersionNumber: 0
    
    modifying entry "uid=mary,ou=people,dc=example,dc=com"
   

Maintenant, mary est reconnue en tant que principal kerberos. Heimdal peut ajouter les clés et autres attributs manquants en tapant la commande de changement de mot de passe en tant qu'administrateur ou en mode admin local :

    # kadmin -l
    kadmin> passwd mary
    mary@EXAMPLE.COM's Password: somesecretpass
    Verifying - mary@EXAMPLE.COM's Password:
    somesecretpass  kadmin>
   

Ceci ajoute les attributs manquants et maintenant, mary est un principal kerberos complet :

    $ kinit mary
    mary@EXAMPLE.COM's Password: somesecretpass
    $ klist
    Credentials cache: FILE:/tmp/krb5cc_500
    Principal: mary@EXAMPLE.COM

    Issued           Expires          Principal
    Jun 20 16:14:48  Jun 20 22:54:48  krbtgt/EXAMPLE.COM@EXAMPLE.COM $
   

mary est également un compte POSIX. À titre de rappel : dans une seule entrée LDAP, nous avons POSIX, Samba et Kerberos. Mais il existe toujours trois sources de mot de passe. Voyez la prochaine section.

2.4.10. Intégration des mots de passe

La fonction la plus recherchée dans un réglage où Heimdal utilise OpenLDAP en tant que système dorsal de base de données est l'intégration de mot de passe.

Sur un réseau, il existe trois sources d'authentification très communes, soit les mots de passe Samba, les mots de passe POSIX et les mots de passe Kerberos. L'utilisation de LDAP ne rend pas magique l'intégration des trois mots de passe : LDAP n'est qu'un espace de stockage et, en effet, chaque application l'utilise pour elle-même. Par exemple, voici les attributs utilisés pour le stockage de password ou secrets par Samba, Heimdal et POSIX :

  • Samba : sambaNTPassword, sambaLMPassword ;

  • Heimdal : krb5Key ;

  • posix : userPassword.

Donc, pam_ldap peut changer le userPassword lorsque l'utilisateur exécute la commande password depuis la console, mais la clé Heimdal et les hashs Samba ne seront pas changés. Donc, nous avons un problème de synchronisation.

Certains administrateurs exécutent des scripts pour régler ce problème, ou n'alloue qu'à l'utilisateur de changer son mot de passe via un frontal quelconque qui prendra en charge les détails concernant la mise à jour de tous les hashs. Une autre option consiste à utiliser le module smbk5pwd.

Le module smbk5pwd est disponible dans le répertoire contribs du tarball OpenLDAP et, lorsque compilé avec le support Samba et Kerberos, il permet cette intégration de mot de passe automatiquement. Ce module est disponible par défaut dans le paquetage openldap-servers.

L'intégration se déroule en trois temps :

  • Modifications des mots de passe EXOP

    Ce module intercepte les modifications de mot de passe OpenLDAP EXOP et met à jour la clé Kerberos et les hashs Samba pour la même entrée, s'ils sont présents. Ceci signifie qu'une commande ldappasswd, par exemple, changera les mots de passe Samba et Kerberos. Lorsque Samba utilise l'option ldap passwd sync dans smb.conf, il réalise également une modification de mot de passe EXOP et met à jour la clé Kerberos.

  • kpasswd

    Lorsque Heimdal reçoit une requête de changement de mot de passe à travers kadmin ou kpasswd, il vérifie si la l'entrée cible contient les hashs d'un mot de passe Samba. Si c'est le cas, ces entrées hash sont également mises à jour. L'attribut userPassword, utilisés pour les liens simples, n'est pas touché, mais voyez la prochaine entrée.

  • liens simples (userPassword)

    Les liens simples (simple binds) utilisent l'attribut userPassword pour la vérification du mot de passe. Si cet attribut contient le hash spécial {K5KEY}, la vérification du mot de passe sera faite contre la clé Kerberos de la même entrée. Donc, afin que les liens simples utilisent le mot de passe Kerberos, nous n'avons qu'à remplacer l'attribut userPassword avec {K5KEY}.

Les modifications de configuration suivantes sont nécessaires afin d'utiliser le module smbk5pwd :

    (...)
    modulepath      /usr/lib/openldap
    moduleload      back_monitor.la
    moduleload      syncprov.la
    moduleload      ppolicy.la
    moduleload      smbk5pwd.so
    password-hash   {K5KEY}
    (...)
    database bdb
    (...)
    overlay ppolicy
    ppolicy_default "cn=default,ou=Password Policies,dc=example,dc=com"
    
    overlay smbk5pwd
    (...)
   

Si nous ne changeons pas le mécanisme de hash du mot de passe serveur à {K5KEY}, alors les changements de mot de passe via EXOP écraseront l'attribut userPassword avec le nouvel hash au lieu de laisser {K5KEY}.

Le module smbk5pwd accepte certaines instructions de configuration comme smbk5pwd-enable et smbk5pwd-must-change. Veuillez lire le fichier README dans le répertoire de documentation openldap-servers pour plus de détails.

Si Samba est utilisé, alors l'option ldap passwd sync devrait être réglée à Only. Avec cette option, Samba ne fera que la modification de mot de passe EXOP, et attendez-vous à ce que le serveur OpenLDAP mette à jour les hashs de Samba, soit exactement ce que fait smbk5pwd.

Dans la section [global] de /etc/samba/smb.conf, ajoutez:

    ldap passwd sync = Only
   

Mainteneant, testez ldappasswd, smbpasswd et kpasswd : un changement de mot de passe réalisé par une ou l'autre de ces applciations devrait changer les trois sources d'authentification.

2.5. Ajustements

Nous verrons ici des ajustements à réaliser sur OpenLDAP. Il vous aideront à obtenir le meilleur de votre serveur d'annuaire.

2.5.1. DB_CONFIG

La fondation par défaut d'OpenLDAP se nomme BDB (Berkeley DataBase). C'est une base de donnée robuste utilisée par de nombreux projets hautement paramétrables avec le fichier DB_CONFIG.

OpenLDAP (la version packagée par Mandriva Linux) est livré par défaut avec un fichier DB_CONFIG, mais celui-ci devrait être ajusté pour chaque environnement spécifique. Une configuration incorrecte peut causer de sérieux problèmes de performances ainsi que des problèmes d'intégrité de données.

Nous présentons ici les options clés de DB_CONFIG que tout administrateur OpenLDAP devrait connaître.

set_cachesize <gbytes> <bytes> <ncache>

Ce paramètre établit la mémoire cache à utiliser :

  • <gigaoctet> : taille de la cache gigaoctets. Donc, 1 équivault à un gigaoctet.

  • <octets> : taille de la cache en octets. Par exemple, si la valeur précédente est établie à 1 et celle-ci à 536870912, la taille totale de la cache, constituée de la somme des deux valeure, serait de 1610612736 octets. La taille maximale d'une cache par segment (voir l'option suivante) est de 4 gigaoctets.

  • <ncache> : le nombre de cache. Chaque cache est alloué dans une région de mémoire continue. La valeur 0 ou 1 indique seulement 1 segment.

set_lg_bsize <octets>

La base de données BDB est transactionnelle. Ce qui signifie que chaque écriture est d'abord notée dans un log, puis exécutée par la suite. Le paramètre set_lg_bsize indique la taille de la mémoire tampon (en octet) pour ce fichier journal. Chaque fois que cette taille de mémoire est atteinte, le log est écrit sur le disque.

set_lg_dir <path>

Par défaut, le fichier journal des transactions est écrit dans le même répertoire que la base de données. Ce répertoire peut varier afin d'utiliser un autre disque pour améliorer les performances globales.

La plupart des configurations de DB_CONFIG prennent effet au chargement de la base de données, ce qui peut ête accompli avec la commande db_recover. Par exemple, pour rebâtir l'environement dans /var/lib/ldap, la commande serait db_recover -v -h /var/lib/ldap (-v pour voir plus de détails).

[Avertissement] Avertissement

Il faut toujours exécuter db_recover lorsque le démon slapd est arrêté.

Après avoir ajusté DB_CONFIG, particulièrement le paramètre relié à la cache, vous devriez utiliser la commande db_stat -m -h /var/lib/ldap pour en vérifier l'efficacité. Vous verrez alors un rapport du pourcentage de requêtes en cache. Vous voulez une valeur suppérieur à 90 %. Si votre serveur a assez de RAM, ceci peut-être gonflé jusqu'à 99 % ou même 100 %.

2.5.2. Cache OpenLDAP

En plus de la cache de BDB, OpenLDAP possède aussi sa propre cache. La paramètre de configuration cachesize prend une valeur comme argument qui détermine le nombre d'entrées qui doivent être conservées en cache. La valeur par défaut est 1000 (mille). C'est différent de la cache BDB et son impact est moindre sur les performances.

2.5.3. Index

Les index constituent la pierre angulaire de tous les types de bases de données, OpenLDAP inclus. Sans index, les recherches peuvent être longues à compléter, et avoir un impact important sur le CPU.

Le paramètre index dans la section database de slapd.conf est utilisé pour spécifier quel attribut doit être indexé avec quel type d'index. La syntaxe habituelle est :

    index <attr1[,attr2,...]> <[pres,eq,approx,sub]>
   

Le type d'index varie selon le type de recherche prévue pour cet attribut. Par exemple, les recherches de type (uid=*john*) auront besoin d'un index sub pour la rapidité. Voici les types d'index les plus communs :

pres

L'index de présence, utilisé par les tests pour vérifier la présence d'un attribut.

eq

L'index d'égalité (equality) pour tester l'égalité. Par exemple, (uid=john).

approx

L'index approximatif utilisé dans les recherches qui utilisent les tests approximatifs. Par exemple, (uid~=sisko).

sub

Cet index est utilisé pour des recherches utilisant des sous-chaînes comme (uid=*john*). Notez que par défaut, OpenLDAP n'appliquera pas d'index de sous-chaînes pour les attributs avec moins de 2 caractères (voir slapd.conf(5) pour plus de détails permettant de changer ceci).

Le prochain exemple utilise différents types d'index pour certains attributs :

    index   objectClass,uid,uidNumber,gidNumber,memberUid   eq
    index   ou                                              eq
    index   cn,mail,surname,givenname                       eq,sub
    index   entryCSN,contextCSN,entryUUID                   eq
   

Dès qu'une recherche est lancée sur les attributs qui n'ont pas d'index appropriés, un mise en garde sera écrite dans slapd :

    Jul 31 14:12:36 pandora slapd[15130]: conn=8 op=1 SRCH
    base="dc=example,dc=com" scope=2 deref=0 filter="(ou=remotes)" Jul 31
    14:12:36 pandora slapd[15130]: <= bdb_equality_candidates: (ou)
    index_param failed (18)
   

Dès que ceci arrive, cela indique que la recherche a été particulièrement lente. Soit l'attribut doit être indexé, soit la recherche doit être modifiée pour inclure cet attribut.

Lorsqu'un index est ajouté après que la base de données ait été peuplé, celle-ci doit être réindexée. Cette tâche est accomplie en arrêtant le service et en exécutant la commande slapindex. Ce processus réindexera tous les attributs, ce qui peut être long pour certaines bases de données volumineuses.

2.5.4. RAM

OpenLDAP peut bénéficier d'un serveur avec beaucoup de RAM. Lorsque c'est possible, ou si vous constatez que la cache n'est pas très performante, ajoutez de la RAM à votre serveur. L'annuaire s'en portera mieux et vos utilisateurs également...

2.6. Utlisation avancée

OpenLDAP propose plusieurs options de superposition qui peuvent vous aider à opérer un serveur d'identité. En voici quelques-unes, notamment :

  • Password policies : contrôle l'expiration, la qualité des mots de passe, les comptes gelés, etc.

  • Unique overlay : s'assure que certain attributs sont uniques.

  • Dynamic groups and lists : creation de groupe et de liste à la volée

  • Referential integrity : maintient la correspondance entre les entrées qui référencent d'autres entrées.

  • Replication with syncrepl : crée des copies de vos données sur un autre serveur OpenLDAP.

Le paquetage du serveur Mandriva OpenLDAP propose la plupart des superpositions et des fondations en tant que modules séparés dans le répertoire /usr/lib/openldap. Pour charger une superposition, vous devez éditer /etc/openldap/slapd.conf comme ceci :

   (...)
   modulepath      /usr/lib/openldap
   moduleload      overlay-filename
   (...)
   database bdb
   (...)
   overlay overlay-name
    overlay-specific-options
   (...)
  

Donc, chargez d'abord le module moduleload puis, à l'intérieur de la section database activez-la par la directive overlay. N'importe quelle option de configuration de superposition spécifique peut maintenant être utilisée.

2.6.1. Politique de mot de passe

La superposition politique de mot de passe (ppolicy.la) intercepte les changements de mots de passe LDAP et y applique plusieurs politiques telles que :

  • le vieillissement de mots de passe ;

  • l'historique des mots de passe ;

  • la longueur de mot de passe ;

  • l'expiration des mots de passe ;

  • les comptes barrés ;

  • le changement de mot de passe forcé.

Plusieurs politiques peuvent être définies sur le serveur et tous les usagers peuvent être assignés à n'importe quelle politique, ou recevoir celle par défaut.

[Astuce] Astuce

Les versions récentes de pam_ldap (182 ou plus) supporte ce module OpenLDAP. Pour l'activer, ajoutez pam_lookup_policy yes dans /etc/ldap.conf.

À titre d'exemple, nous allons configurer un compte avec un changement de mot de passe forcé, une longueur minimum avec un historique de mot de passe. La liste complète des politiques et leur usage sont documentés dans la page de man slapo-ppolicy(5).

  1. Le fichier /etc/openldap/slapd.conf créé par défaut par openldap-mandriva-dit a déjà le support des politiques de mot de passe. Afin d'être complet, nous avons mis l'emphase sur les changements nécessaires :

          (...)
          include /usr/share/openldap/schema/dyngroup.schema
          include /usr/share/openldap/schema/ppolicy.schema
          (...)
          modulepath      /usr/lib/openldap
          moduleload      back_monitor.la
          moduleload      syncprov.la
          moduleload      ppolicy.la # loads the module
          (...)
          database        bdb
          suffix          "dc=example,dc=com"
          (...)
          overlay ppolicy # activates the overlay
           ppolicy_default "cn=default,ou=Password Policies,dc=example,dc=com"
          (...)
         

    Après avoir redémarré le serveur, il va charger la politique de mot de passe et commencer à la diffuser dans la liste des capacités du serveur.

  2. Maintenant, vous devez définir une politique. Notez que dans le fichier de configuration, une politique par défaut est déjà définie. Son contenu est rudimentaire et aucune règle n'y est encore définie :

          dn: cn=default,ou=Password Policies,dc=example,dc=com
          cn: default
          objectClass: pwdPolicy
          objectClass: namedObject
          pwdAttribute: userPassword
         
    [Note] Note

    La classe d'objet namedObject est définie dans le fichier de schéma kolab.schema. Si vous décidez de ne pas charger de schéma, une politique de mot de passe cassera les namedObject inutiles et les définiront ailleurs.

    Si nous voulons appliquer les politiques listées plus tôt, nous devons changer cette entrée ou en créer une nouvelle. Nous allons changer cette entrée, la politique par défaut de notre base de données. Nous pourrons par la suite la clôner vers d'autres politiques, si nous le désirons.

    Ci-dessous, la commande pour ajouter la politique désirée. Les membres du groupe système Account Admins peuvent changer les politiques :

          $ ldapmodify -x -D 'uid=Account Admin,ou=System Accounts,dc=example,dc=com' -W
          Enter LDAP Password: secretpassword
          dn: cn=default,ou=Password Policies,dc=example,dc=com
           changetype: modify
           add: pwdMustChange
           pwdMustChange: TRUE
           -
           add: pwdCheckQuality
           pwdCheckQuality: 2
           -
           add: pwdInHistory
           pwdInhistory: 2
           -
           add: pwdMinLength
           pwdMinLength: 5
    
          modifying entry "cn=default,ou=Password Policies,dc=example,dc=com"
          
          ^D
         

    Explications :

    • pwdMustChange: TRUE

      Force les usagers dont le mot de passe est réinitialisé à changer leur mot de passe. Ses opérations LDAP seront restreintes jusqu'à ce que ce soit complété.

    • pwdCheckQuality: 2

      Active la validation de la qualité du mot de passe. Cette fonction va également activer pwdMinLength que nous établissons plus bas. La valeur 2 signifie que si pour une raison ou une autre la qualité du mot de passe ne peut être vérifiée (parce que le client l'assigne dans un hash, par exemple), la validation échouera.

    • pwdInHistory: 2

      Active l'historique de mot de passe et mémorise jusqu'à 2 vieux mots de passe.

    • pwdMinLength: 5

      Définit la taille minimum d'un mot de passe à 4 caractères. Si c'est moins, le nouveau mot de passe sera rejeté.

    Maintenant, toutes les entités qui n'ont pas d'instruction spécifique pour utiliser une autre politique seront asujetties à cette politique par défaut, même les comptes système !

  3. Nous allons débuter nos tests avec l'usager peter en le forçant à changer son mot de passe. La politique l'oblige déjà, donc nous avons seulement, en tant qu'admin, à identifier son mot de passe comme réinitialisé.

          $ ldapmodify -x -D 'uid=Account Admin,ou=System Accounts,dc=example,dc=com' -W
    Enter LDAP Password: secretpassword
    dn: uid=peter,ou=People,dc=example,dc=com
    changetype: modify
    add: pwdReset
    pwdReset: TRUE
    
    modifying entry "uid=peter,ou=People,dc=example,dc=com"
    
    ^D
         

    Voyons ce qui arive lorsque peter essaie, par exemple, de faire une recherche :

    $ ldapsearch -x -LLL -D uid=peter,ou=People,dc=example,dc=com -W uid=peter uid
    Enter LDAP Password: peter's password
    Insufficient access (50)
    Additional information: Operations are restricted to bind/unbind/abandon/StartTLS/modify password
         

    Donc, peter est maintenant obliger de changer son mot de passe. Si nous activons le support ppolicy dans le client, nous avons un indice de ce qui s'est passé :

    $ ldapsearch -x -LLL -D uid=peter,ou=People,dc=example,dc=com -W -e ppolicy uid=peter uid
    Enter LDAP Password: peter's password
    ldap_bind: Success (0); Password must be changed
    Insufficient access (50)
         

    Allez-y et changez le mot de passe pour 1234 :

    $ ldappasswd -x -D uid=peter,ou=People,dc=example,dc=com -W -s 1234 uid=peter,ou=People,dc=example,dc=com
    Enter LDAP Password: peter's password
    Result: Constraint violation (19)
    Additional info: Password fails quality checking policy
         

    Nous constatons que la politique pwdMinLength entre en fonction : nous avons utilisé un mot de passe de 4 caractères ou moins. Essayons avec 5 caractères :

    
          $ ldappasswd -x -D uid=peter,ou=People,dc=example,dc=com -W
           -s 12345 uid=peter,ou=People,dc=example,dc=com Enter LDAP
          Password: Result: Success (0)
         

    Ça fonctionne. Finalement, pour démontrer la politique d'historique de mot de passe, essayons de changer le mot de passe en utilisant la valeur précédente :

          $ ldappasswd -x -D uid=peter,ou=People,dc=example,dc=com -W -s peteroldpass uid=peter,ou=People,dc=example,dc=com
          Enter LDAP Password: 12345
          Result: Constraint violation (19)
          Additional info: Password is in history of old passwords
         

Pour assigner une politique différente selon l'usager, utilisez l'attribut pwdPolicySubentry et pointez le vers le dn de la politique à utiliser. Par exemple, pour appliquer la politique cn=marketing à l'usager peter, faites :

    $ ldapmodify -x -D 'uid=Account Admin,ou=System Accounts,dc=example,dc=com' -W
    Enter LDAP Password: secretpassword
     dn: uid=peter,ou=People,dc=example,dc=com
     changetype: modify
     add: pwdPolicySubentry
     pwdPolicySubentry: cn=marketing,ou=Password Policies,dc=example,dc=com
    
    modifying entry "uid=peter,ou=People,dc=example,dc=com"
    
    ^D
   

De cette façon, nous pouvons avoir différentes politiques appliquées à différents usagers. À l'heure actuelle, il n'est pas possible d'appliquer une politique à un groupe d'usagers, le changement doit être appliqué à chaque usager avec l'attribut pwdPolicySubentry.

[Avertissement] Avertissement

Soyez prudent lorsque vous utlisez les politiques de mots de passe de OpenLDAP avec des applications qui ont leur propre politique ou le propre hash de mots de passe. Samba est un bon exemple. L'utilisation des politiques de Samba et de OpenLDAP en même temps serait problématique, compte tenu que Samba utilise ses propres attributs de mot de passe, tandis que OpenLDAP surveille userPassword. Il est possible que Samba permette un changement de mot de passe pendant que OpenLDAP le refuse en raison de politiques divergentes.

2.6.2. Superposition unique

La superposition unique (unique overlay) est utilisée en prévention qu'une partie de l'arborescence ne répète une paire attribut-valeur. Par exemple, la branche ou=People pourrait surveillée les changements dans l'attribut uidNumber. Si un changement devait survenir demandant d'utiliser un numéro pour cet attribut qui est déjà utilisé ailleurs, le changement serait refusé. Donc, chaque écriture vers un attribut surveillé déclenche une recherche LDAP pour cet attribut et vérifie si cette valeur est assignée quelque part dans la branche surveillée.

[Avertissement] Avertissement

Il est très important que l'attribut surveillé ait l'index approprié !

À titre d'exemple, configurons le serveur pour prévenir la duplication de uidNumber et cn sous ou=People. Toutes les options sont décrites dans la page de man slapo-unique(5).

  1. Les changements à la configuration de slapd.conf :

          (...)
          modulepath      /usr/lib/openldap
          moduleload      back_monitor.la
          moduleload      syncprov.la
          moduleload      unique.la # loads the module
          (...)
          database        bdb
          suffix          "dc=example,dc=com"
          (...)
          overlay unique # activates the overlay
           unique_base		ou=People,dc=example,dc=com
           unique_attributes uidNumber cn
          
          (...)
         

    Après le rédémarrage du service OpenLDAP, le module sera chargé et nous pourrons faire des tests.

  2. Test :

    Voyons ce qui arrive lorsqu'on essaie de changer le uidNumber d'un usager pour une valeur déjà assignée à un usager :

          $ ldapmodify -x -D 'uid=Account Admin,ou=System
           Accounts,dc=example,dc=com' -W Enter LDAP Password:
          secretpassword dn: uid=queen,ou=People,dc=example,dc=com
           changetype: modify replace: uidNumber uidNumber: 1024
          
          modifying entry "uid=queen,ou=People,dc=example,dc=com"
          ldap_modify: Constraint violation (19)
          additional info: some attributes not unique
         

    Le changement a été refusé tel que prévu parce que le uidNumber qui a été choisi était déjà utilisé par un autre usager.

[Astuce] Astuce

Prenez soin de ne pas lister d'attributs qui pourraient avoir des valeurs doublées. gidNumber, par exemple, pendant qu'il est unique pour identifier un groupe POSIX, peut être utilisé plusieurs fois avec la même valeur sous ou=People : pensez aux usagers qui partagent le même groupe principal.

2.6.3. Groupes et listes dynamiques

Les groupes et les listes dynamiques sont très similaires et peuvent être utilisés pour peupler automatiquement une entrée avec des éléments.

Par exemple, nous pourrions avoir une liste dynamique qui s'étendrait automatiquement pour inclure toutes les addresses email que nous avons assignées à des utilisateurs. Ce serait notre alias email all@example.com.

De la même manière, nous pourrions avoir un groupe nommé allusers qui serait toujours à jour concernant les usagers de notre annuaire. Si un usager est supprimé ou ajouté, le groupe refléterait ce changement dès que recherché.

Dès qu'un entrée avec une classe surveillée est retournée suite à une requête, une recherche est lancée pour assembler les attributs qui doivent être retournés avec la requête. C'est cette recherche qui rend l'entrée dynamique. Les paramètres de recherche sont encodés dans un attribut de cette même entrée.

L'exemple suivant illustre comment configurer l'alias email automatique présenté plus haut, qui s'étendra toujours pour inclure tous les usagers de l'annuaire :

  1. Changements dans slapd.conf :

          (...)
          modulepath      /usr/lib/openldap
          moduleload      back_monitor.la
          moduleload      syncprov.la
          moduleload      dynlist.la # loads the module
          (...)
          database        bdb
          suffix          "dc=example,dc=com"
          (...)
          overlay dynlist # activates the overlay
           # dynlist-attrset <group-oc> <URL-ad> [<member-ad>]
           dynlist-attrset	nisMailAlias labeledURI
          
    (...)
         

    Le paramètre nisMailAlias est le nom de la classe qui lancera la recherche et labeledURI est le nom de l'attribut qui contient les spécifications de la recherche. C'est plus facile à comprendre en voyant l'entrée à la prochaine étape.

  2. Voici une entrée de notre alias email allusers :

          dn: cn=allusers,ou=Aliases,dc=example,dc=com
          cn: allusers
          objectClass: nisMailAlias
          objectClass: labeledURIObject
          labeledURI: ldap:///ou=People,dc=example,dc=com?mail?one?(objectClass=inetOrgPerson)
         
    [Astuce] Astuce

    L'arborescence par défaut n'offre pas la branche ou=Alias. Afin d'ajouter l'entrée cn=allusers, vous devez d'abord ajouter ou=Alias :

           dn: ou=Aliases,dc=example,dc=com
           objectClass: organizationalUnit
           ou: Aliases
          

    OK, prenez une grande respiration.

    Souvenez-vous que nisMailAlias est l'initiateur. Dès qu'une entrée avec cette classe est retournée, la recherche spécifiée dans labeledURI est lancée. Dans notre cas, la recherche signifie :

    • base: ou=People,dc=example,dc=com

    • scope: one

    • filter: (objectClass=inetOrgPerson)

    • returned attribute: mail

    Cette recherche retournera l'attribut mail pour chaque entrée sous ou=People qui possède la classe inetOrgPerson.

    Voici son fonctionnement :

          $ ldapsearch -x -LLL cn=allusers
          dn: cn=allusers,ou=Aliases,dc=example,dc=com
          cn: allusers
          objectClass: nisMailAlias
          objectClass: labeledURIObject
          labeledURI: ldap:///ou=People,dc=example,dc=com?mail?one?(objectClass=inetOrgPerson)
          mail: peter@example.com
          mail: queen@example.com
         

    Comparez ce résultat avec celui obtenu précédemment : voyez-vous la différence ?

    Il y a deux nouveaux attributs qui n'étaient pas dans l'entrée originale : l'adresse email pour peter et queen. Ces entrées ont été ajoutées dynamiquement grâce à la recherche réalisée lorsque cette entrée a été retournée. Si nous retirons l'attribut mail de queen, ou toute l'entrée, la prochaine recherche sous allusers n'affichera plus cette adresse.

Nous allons faire une configurations similaire, mais pour le groupe dynamique.

  1. Changements à slapd.conf :

          (...)
          modulepath      /usr/lib/openldap
          moduleload      back_monitor.la
          moduleload      syncprov.la
          moduleload      dynlist.la # loads the module
          (...)
          database        bdb
          suffix          "dc=example,dc=com"
          (...)
          overlay dynlist # activates the overlay
           # dynlist-attrset <group-oc> <URL-ad> [<member-ad>]
           dynlist-attrset groupOfNames labeledURI member
          
          (...)
         

    Surveillons maintenant une différente classe d'object : groupOfNames. Dès qu'une entrée l'incluant est retournée, la recherche spécifiée dans l'attribut labeledURI est lancée et toutes les entrées qui correspondent sont listées avec l'attribut member.

  2. L'entrée de groupe dynamique :

          dn: cn=allusers,ou=Group,dc=example,dc=com
          cn: allusers
          objectClass: groupOfNames
          objectClass: labeledURIObject
          member: uid=LDAP Admin,ou=System Accounts,dc=example,dc=com
          labeledURI: ldap:///ou=People,dc=example,dc=com??one?(objectClass=inetOrgPerson)
         

    Le filtre de recherche est très similaire au précédent. Mais maintenant nous ne sommes plus intéressé par le contenu de l'attribut mail. Nous voulons simplement liste toutes les personnes présentes dans la branche ou=People.

  3. Pour le tester, voyons le contenu de notre groupe dynamique :

          $ ldapsearch -x -LLL -b ou=Group,dc=example,dc=com cn=allusers
    dn: cn=allusers,ou=Group,dc=example,dc=com
    cn: allusers
    objectClass: groupOfNames
    objectClass: labeledURIObject
    member: uid=LDAP Admin,ou=System Accounts,dc=example,dc=com
    member: uid=john,ou=People,dc=example,dc=com
    member: uid=mary,ou=People,dc=example,dc=com
    member: uid=peter,ou=People,dc=example,dc=com
    member: uid=queen,ou=People,dc=example,dc=com
    labeledURI: ldap:///ou=People,dc=example,dc=com??one?(objectClass=inetOrgPerson)
         

    Aussi, lorsque nous comparons ceci avec le fichier original, le résultat inclut désormais ces nouveaux attributs member. Il ont été créés dynamiquement selon les résultats de la recherche. Si nous supprimons l'un d'eux de la base de données et que nous effectuons une recherche sur le groupe à nouveau, celui-ci sera à jour et n'affichera pas les usagers supprimés.

Notez cependant qu'une recherche comme celle présentée plus bas ne fonctionnerait pas sur un groupe dynamique.

$ ldapsearch -x -LLL -b ou=Group,dc=example,dc=com "(&(objectClass=groupOfNames)(member=uid=queen,ou=People,dc=example,dc=com))"
    $
   

Pour que cela fonctionne, le serveur devrait effectuer la recherche spécifiée dans labeledURI pour chaque groupe, ce qui n'est pas supporté présentement. Mais une comparaison fonctionne :

    $ ldapcompare -x cn=allusers,ou=group,dc=example,dc=com member:uid=queen,ou=People,dc=example,dc=com
TRUE
   

2.6.4. Intégrité référentielle

L'intégrité référentielle est une fonctionnalité commune dans les bases de données relationnelles. Ce concept signifie que lorsqu'une entrée qui est requise par une autre est supprimée, l'opération est refusée. Un scénario commun dans le monde LDAP serait de supprimer un compte utilisateur sans supprimer l'usager du groupe. Ce qui occasionnerait des usagers fantômes à l'intérieur de groupes, c'est-à-dire, des groups avec des usagers qui n'existent plus.

Pour gérer ce scénario, les administrateurs ont typiquement recours à des scripts ou des outils qui mettront les groupes à jour, ou n'importe quelle entité dépendante de l'entrée suprimée. Ceci n'est pas difficile, seulement quelques recherches et une mise à jour sont nécessaires.

La couche de superposition refint permet de réaliser une partie de ceci automatiquement. Poursuivons avec notre exemple de groupe. Cette superposition peut être configurée pour garder l'intégrité de l'attribut member, qui liste le membre du groupe. Dès qu'une entrée est supprimée de l'annuaire, une recherche est lancée sur tous les attributs member pointant vers cette entrée supprimée. Les entrées qui correspondent se verront l'attribut member retiré, maintenant ainsi l'intégrité.

Ceci démontre que la couche de superposition refint, plutôt que de refuser une opération qui briserait l'intégrité, va plutôt retirer ou renommer les attributs pour composer avec la suppression.

L'exemple suivant supprime un usager et montre comment le groupe est mis à jour automatiquement.

  1. Changements à slapd.conf :

    (...)
    modulepath      /usr/lib/openldap
    moduleload      back_monitor.la
    moduleload      syncprov.la
    moduleload      refint.la # loads the module
    (...)
    database        bdb
    suffix          "dc=example,dc=com"
    (...)
    overlay refint # activates the overlay
    refint_attributes member
    refint_nothing    "uid=LDAP Admin,ou=System Accounts,dc=example,dc=com"
    
    (...)
         

    La couche de supperposition a seulement deux paramètres de configuration 

    • refint_attributes : l'attribut d'intégrité. Si, par exemple, une entrée nommée uid=John,ou=People,dc=example,dc=com est retirée, une recherche est lancée pour member="uid=John,ou=People,dc=example,dc=com" et cet attribut est retiré pour les entrées correspondantes.

    • refint_nothing : il est possible que le dernier attribut d'une entrée soit supprimé par contrainte d'intégrité. Certaines classes d'objets, par contre, requièrent au moins un attribut. Si cette situation devait se présenter, la couche de superposition peuplera le dernier attribut avec le dn configuré ici. Donc, par exemple, si le dernier membre d'un groupe est uid=John,ou=People,dc=example,dc=com et que cet usager a été retiré de la base de données, afin de ne pas laisser le groupe sans membre (ce qui est interdit par la classe d'objet groupOfNames), la superposition va ajouter member=uid=LDAP Admin,ou=System Accounts,dc=example,dc=com au groupe.

    [Note] Note

    La couche de superposition d'integrité référentielle fonctionne avec le DN complet. Ce qui signifie qu'il n'est pas possible de l'utiliser pour maintenir l'intégrité des classes de groupe qui utilisent l'attribut memberUid, par exemple, parce que cet attribut tient juste un nom d'usager et non un DN.

  2. Test :

    Imaginons que nous avons le groupe suivant avec 2 utilisateurs :

          $ ldapsearch -x -LLL cn=mkt member
          dn: cn=mkt,ou=Group,dc=example,dc=com
          member: uid=peter,ou=People,dc=example,dc=com
          member: uid=queen,ou=People,dc=example,dc=com
         

    Si nous suprimons peter de la base de données, le groupe est automatiquement mis à jour pour refléter que cet usager est supprimé :

    $ ldapdelete -x -D 'uid=Account Admin,ou=System Accounts,dc=example,dc=com' -W uid=peter,ou=People,dc=example,dc=com
    Enter LDAP Password: secretpassword
    $ ldapsearch -x -LLL cn=mkt member
    dn: cn=mkt,ou=Group,dc=example,dc=com
    member: uid=queen,ou=People,dc=example,dc=com
         

Si nous supprimons le dernier usager du groupe, (queen), nous verrons alors la configuration refint_nothing s'activer :

    $ ldapdelete -x -D 'uid=Account Admin,ou=System Accounts,dc=example,dc=com' -W uid=queen,ou=People,dc=example,dc=com
Enter LDAP Password: secretpassword
$ ldapsearch -x -LLL cn=mkt member
dn: cn=mkt,ou=Group,dc=example,dc=com
member: uid=LDAP Admin,ou=System Accounts,dc=example,dc=com
   

Au lieu de laisser le groupe sans membres, ce qui est proscrit par la classe d'objet groupOfNames, le recouvrement est ajouté au DN refint_nothing en tant que son seul membre.

2.7. Réplication avec syncrepl

Afin d'assurer la disponibilité en cas de panne ou de problème majeur, il est particulièrement utile d'avoir plusieurs serveurs LDAP offrant les mêmes donnés. La réplication permet cette fonctionalité.

Il existe deux méthodes de réplication pour OpenLDAP : slurpd et syncrepl. slurpd est maintenant obsolète et son développement est arrêté. syncrepl est la solution de choix. Voici quelques avantages clés de syncrepl par rapport à slurpd :

  • le consommateur peut commencer vide, il sera synchroniser automatiquement ;

  • pousser ou tirer : la réplication commence toujours avec le consommateur, mais le producteur peut annoncer les changements ;

  • pas besoin de changer un producteur lorsqu'on ajoute un nouveau consommateur : aucun redémarrage, aucun changement de configuration ;

  • l'état de la réplication peut facilement être vérifié.

[Astuce] Astuce

En comparaison de la terminologie de syncrepl avec celle de slurpd, un consommateur est un serveur esclave et un producteur un serveur maître.

Pour illustrer d'avantage les avantages de syncrepl, voici un comparaison des étapes nécessaires pour ajouter un nouvel esclave/consommateur a un maître/producteur existant :

  • Avec slurpd :

    • arrêt du master (ou mis en lecture-seule) ;

    • verser la base de données maître dans un ldif ;

    • annoncer au maître le nouvel esclave (configurer slapd.conf) ;

    • copiez le fichier versé sur l'esclave et importez-le ;

    • démarrez l'esclave ;

    • démarrez le maître.

  • Avec syncrepl :

    • pointer le consommateur vers le producteur et démarrez-le (le consommateur)

Dans chaque implémentation, par contre, il est seulement possible d'avoir un consommateur/procducteur : il n'y a pas de support pour la réplication multi-maître dans OpenLDAP.

La réplication est assez flexible pour nous permettre de répliquer une base de données en entier ou juste un partie. Par exemple, imaginons qu'un serveur de couriel dans une zone DMZ a besoin d'accéder au server LDAP de l'entreprise pour valider un email. Une approche pourrait le laisser faire sa requête dans le server LDAP interne :

Figure 6.16. En utilisant un serveur LDAP interne

En utilisant un serveur LDAP interne

Une autre approche consiste serait de placer un serveur consommateur LDAP dans la DMZ. Ce serveur n'a pas besoin de l'ensemble de la BD, seulement les informations pertinentes pour le serveur de courriel (et potentiellement d'autres serveurs DMZ). Cette réplication filtrerait les autres attributs. En plus, un serveur mail peut continuer à livrer des messages même si le serveur interne principal est en panne :

Figure 6.17. En utilisant une réplique

En utilisant une réplique

2.7.1. Configuration du producteur

Le rôle du producteur est assigné par la couche de superposition syncprov. La configuration du paquetage openldap-mandriva-dit et ses scripts de démarrage ont déjà tous les détails nécessaires, mais nous les répéterons par souci d'intégrité.

Voici ce dont nous aurons besoin dans slapd.conf :

(...)
modulepath      /usr/lib/openldap
moduleload      back_monitor.la
moduleload      syncprov.la
(...)

database        bdb
suffix          "dc=example,dc=com"
(...)
overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100
			

Selon le fonctionnement de suncrepl (consultez OpenLDAP Admin Guide et le RFC 4533 pour plus de détails), les opérations d'écriture sont mieux suivies avec l'utilisation d'un log de session. Ce sont des valeurs suggérées qui varient selon le nombre d'écritures que l'annuaire reçoit dans une période donnée.

  • syncprov-checkpoint ops minutes : met contextCSN à jour dans la base de données après que l'opération d'écriture de ops ou plus de minutes minutes se sont écoulées depuis le dernier checkpoint. Notez que ces numéros ne sont pas vérifiés après une opération d'écriture.

  • syncprov-sessionlog ops : taille du log qui va enregistrer l'information à propos des opérations d'écriture.

Il nous reste un changement à faire : configurer les limites.

syncrepl fonctionne via une opération de recherche hiérarchique. Le consommateur lancera cette recherche sur le producteur et la réponse est la données en train d'être répliquée. Donc, si le consommateur commence vide, la réponse contiendra toutes le données à répliquer. Une fois synchronisé, la réponse ne contiendra que les entrées changées, ajoutées ou supprimées. Ce qui signifie ::

  • Le consommateur doit pouvoir lire les données : donc les ACL appropriées doivent être ne place pour permmettre cette lecture des données à être répliquées.

  • Les bonnes limites doivent être en place pour le consommateur sur le producteur : nous ne voulons pas que le consommateur atteigne une limite de taille durant la réplication et ainsi échouer la réplication de toutes les entrées.

Afin d'aborder tous ces enjeux, la solution habituelle est de créer un compte spécifique à la réplication et d'ajuster les ACL et les limites pour ce compte. openldap-mandriva-dit accomplit ceci à travers le groupe LDAP Replicators et ses membres :

    limits group="cn=LDAP Replicators,ou=System Groups,dc=example,dc=com"
        limit size=unlimited
        limit time=unlimited

    access to dn.subtree="dc=example,dc=com"
    by group.exact="cn=LDAP Admins,ou=System Groups,dc=example,dc=com" write
    by group.exact="cn=LDAP Replicators,ou=System Groups,dc=example,dc=com" read
    by * break
   

Cette configuration vérifie que les membres du groupe LDAP Replicators peuvent lire toutes les entrées et attributs, et n'a pas de limite de taille ou de temps appliquée, ce qui correspond exactement à ce dont nous avons besoin pour le support de la réplication avec syncrepl. Notez que les ACL peuvent être ajustés si vous préférez limiter les accès de lecture aux données qui ne seront jamais répliquées à votre avis.

Après avoir fait ces modifications et redémarré le service, ce serveur est prêt a recevoir des consommateurs avec des données répliquées. Aucun autre changement n'est nécessaire (mise à part de l'optimisation) pour ajouter un autre consommateur.

2.7.2. Configurer le consommateur

La configuration au niveau consommateur est plus complexe et ressemble au processus de slurpd. Il y a deux types de réplications :

  • refreshOnly : le consommateur initie la réplication en contactant le producteur et en demandant des données. Une fois les données reçues, cela arrête la connexion et le consommateur se met en mode veille pour une durée spécifiée. Une fois ce délai expiré, il se réveille, contacte le serveur et répète l'opération.

  • refreshAndPersist : encore un fois, le consommateur initie la réplication en contactant le producteur. La diférence, c'est qu'une fois les données reçues, la connexion reste ouverte. Le producteur utilisera désormais cette connexion pour avertir le consommateur des changements. Donc, au lieu d'un appel comparable à cron, les consommateurs qui utilisent refreshAndPersist obtiennent des nouvelles données dès qu'elles sont disponibles sur le producteur.

pour la réplication refresh, voici ce dont on a besoin :

syncrepl    rid=001
            provider=ldap://provider.example.com
            starttls=critical
            type=refreshOnly
            interval=00:01:00:00
            searchbase="dc=example,dc=com"
            scope=sub
            filter="(objectClass=*)"
            attrs="*,+"
            bindmethod=simple
            binddn="uid=LDAP Replicator,ou=System Accounts,ou=global,dc=example,dc=com"
            credentials="ldapreplicator"
   

Pour refreshAndPersist, la configuration est comme ceci :

syncrepl rid=001 provider=ldap://provider.example.com
    starttls=critical type=refreshAndPersist retry="60 +"
    searchbase="dc=example,dc=com" scope=sub
    filter="(objectClass=*)" attrs="*,+" bindmethod=simple
    binddn="uid=LDAP Replicator,ou=System
    Accounts,ou=global,dc=example,dc=com"
    credentials="ldapreplicator"
    
    updateref   ldap://provider.example.com
   

Les paramètres plus importants sont décris plus bas. Vous trouverez plus de détails dans la page de man de slapd.conf(5).

rid

Spécifie un identifiant unique pour cet instance consommateur.

producteur

URI du producteur.

starttls

Lorsque les opérations START TLS doivent être utilisées, (yes) et si c'est critique ou non (critical). Passer si pas requis.

type

Le type de cette réplication : soit refreshOnly ou refreshAndPersist.

interval

Dans le mode refreshOnly, ce paramètre spécifie l'intervalle entre les tentatives de réplication. Le format est dd:hh:mm:ss.

retry

Dans le mode refreshAndPersist, ce paramètre spécifie comment gérer la situation lorsque le producteur est non-disponible. La syntaxe est une liste d'intervalle retry interval et number of retries en paire. Si le symbole + est utilisé à la place de number of retries, cela signifie « indéfiniment ».

searchbase, scope, filter, attrs

Ces paramètres ont le même comportement que les opérations régulières de recherche LDAP, et peuvent être utilisés pour choisir en détail les données à répliquer. Les valeurs par défaut sont suffisantes pour toute la searchbase, avec tous les attributs disponibles.

bindmethod

Quelle méthode de liaison utiliser : simple ou sasl.

binddn

Dans le cas de la liaison simple, cette option spécifie la liaison dn qui doit être utilisée.

credentials

Spécifie le secret associé avec la liaison simple et sasl.

[Avertissement] Avertissement

N'utilisez pas un hash de mot de passe (hashed password) pour le paramètre credentials, ce doit être du texte clair ! Souvenez-vous que dans ce cas, le consommateur est u client LDAP comme tous les autres. Lorsque vous vous authentifier avec votre serveur, tapez-vous votre mot de passe en texte clair ou la version hash ?

2.7.3. Test de réplication

Pour tester la réplication, la façon la plus simple est de vider la base de données et de la redémarrer en étant vide. Les fichiers journaux de producteur producer logs (au loglevel 256) devraient afficher les connexions des consommateurs (nous avons supprimé quelques colonnes pour que ce soit plus clair) :

conn=1 fd=27 ACCEPT from IP=10.0.4.29:4479 (IP=0.0.0.0:389) 
conn=1 op=0 BIND dn="uid=LDAP Replicator,ou=System Accounts,dc=example,dc=com" method=128 
conn=1 op=0 BIND dn="uid=LDAP Replicator,ou=System Accounts,dc=example,dc=com" mech=SIMPLE ssf=0 
conn=1 op=0 RESULT tag=97 err=0 text= 
conn=1 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)" 
conn=1 op=1 SRCH attr=* + 
conn=1 op=2 UNBIND 
conn=1 fd=27 closed 
   

Après un court instant, et tout dépendant de la taille de la base de données, le consommateur devrait être synchro avec le producteur.

2.8. Tâches d'entretien

Nous listons quelques tâches d'entretien qui devraient être faites périodiquement pour assurer que votre service d'identité fonctionne correctement.

2.8.1. Efficacité de la cache

Pour surveiller l'efficacité de la cache BDB, vous devez lancer la commande db_stat. Voici un exemple :

    # db_stat -m -h /var/lib/ldap/ | head -n 6
    40MB 1KB 604B   Total cache size.
    1       Number of caches.
    40MB 8KB        Pool individual cache size.
    0       Requested pages mapped into the process' address space.
    975     Requested pages found in the cache (98%).
    19      Requested pages not found in the cache.
    (...)
   

L'écran précédent montre la taille actuelle de la cache (40MB) et le pourcentage de réponse pertinente (hit percentage) de la base de données principale (98%). Une façon rapide de faire un survol des réponses de la base de données est d'utiliser la commande db_stat -m -h /var/lib/ldap | grep %.

Si le pourcentage de réponse pertinente est peu élevé (disons sous les 90 %), vous devriez accroître la cache. Souvenez-vous d'exécuter db_recover après pendant que le service est arrêté afin que ces changements deviennent effectifs.

Notez que vous devriez toujours prendre en considération le nombre de requêtes qu'un fichier de base de données a reçu. S'il y a peu de requêtes, le pourcentage de réponse pertinente pourrait être déformé et il n'est pas nécessaire de faire quoi que ce soit.

2.8.2. Gestion des transactions dans les fichiers journaux

OpenLDAP utilise le support pour les transactions qu'utilise BDB. Cela veut dire qu'en temps voulu, le répertoire de base de données se remplira de fichiers journaux :

    # l /var/lib/ldap/log.*
    -rw-------  1 ldap ldap 170K Ago 18 17:40 /var/lib/ldap/log.0000000001
   

Par défaut, chaque fichier journal grossira jusqu'à une taille de 10 Mo et sera pivoté, ce qui signifie qu'un nouveau fichier commencera. Cahque fichier journal contient toutes les opérations d'écriture faites sur la base de données. Il serait donc possible de la reconstruire depuis zéro si tous les fichiers journaux sont disponibles. C'est ce qu'on appelle une « restauration extraordinaire » (catastrophic recovery).

Un fichier journal peut contenir des transactions ouvertes, c'est-à-dire des changements qui n'ont pas encore été envoyés à la base de données. La commande db_archive peut être utilisée pour lister les fichiers journaux qui ne sont plus en utilisation et qui pourraient être supprimés (ou sauvegardés ailleurs si vous voulez pouvoir exécuter une restauration extraordinaire dans le futur) :

    # db_archive -h /var/lib/ldap
    #
   

Dans cet exemple, aucun fichier journal n'a été imprimé par db_archive, ce qui signifie que tous les fichiers journaux sont en fonction. Voici une sortie différente possible :

# db_archive -h /var/lib/ldap
log.0000000001
log.0000000002
log.0000000003
#
   

Ceci signifie que les fichiers journau affichés ne sont plus en usage et peuvent être supprimés ou sauvegardés. L'outil peut supprimer ces fichiers journaux automatiquement à travers l'option -d.

En option, les fichiers journaux peuvent être supprimés automatiquement par la bibliothèque elle-même, lorsqu'ils sont pivotés. Pour que cela arrive, vous devez spécifier au drapeau DB_LOG_AUTOREMOVE dans le fichier DB_CONFIG :

    (... other DB_CONFIG options ...)
    set_flags DB_LOG_AUTOREMOVE
   

2.8.3. Vérification des index

Les index sont importants pour toutes les bases de données, incluant les serveurs de répertoires. Lorsque OpenLDAP reçoit une requête de recherche sur des attributs dont l'index est incorrect, une mise en garde est inscrite dans le fichier journal. Particulièrement dans les prochains jours de mise en fonction, il est important de regarder les fichiers journaux périodiquement et de repérer ces mises en garde, de réindexer les attributs ou de changer les paramètres de recherche :

    # grep index_param /var/log/ldap/ldap.log
    Aug 24 10:04:43 cs4 slapd[27399]: <= bdb_equality_candidates: (ou) index_param failed (18) 
    Aug 24 10:04:45 cs4 slapd[27399]: <= bdb_equality_candidates: (ou) index_param failed (18)
    (...)
    Jul 21 15:43:59 cs4 slapd[29666]: <= bdb_equality_candidates: (sambaSIDList) index_param failed (18) 
    Jul 21 15:43:59 cs4 slapd[29666]: <= bdb_equality_candidates: (sambaSIDList) index_param failed (18) 
    (...)
   

Ceci montre qu'au moins deux recherches étaient faites sur des attributs non indexés. Dans les deux cas, l'index manquant était de type égalité equality type (donc, bdb_equality_candidates). Pour remédier à la situation, ces index doivent être ajourés et la base de données doit être réindexée.

2.9. Dépannage

Voici quelques trucs pour vous dépanner lorsque des problèmes connus dans OpenLDAP surviendront.

2.9.1. Reconnaître les utilisateurs dans LDAP

Le symptôme classique est d'excuter getent passwd john et que l'utilisateur john n'existe pas, mais il est dans LDAP. Plusieurs sont impliqués dans cette vérification pourtant simple, ce qui veut dire que plusieurs éléments peuvent en être la cause.

Le checmin à travers lequel cette commande passe est plus ou moins celui-ci : glibc, nss, nss_files, nss_ldap, ldap, user entry (classe d'objet posixAccount). Jetons-y un œil :

  • Fichiers journaux du serveur : premièrement, vérifiez les fichiers journaux du serveur OpenLDAP pour voir si une requête de recherche s'y rend. Si tel est le cas, alors le problème se trouve probablement dans les données elles-mêmes (pas présentes ou incorrectes) ou dans la recherche de base.

  • /etc/nsswitch.conf : vérifiez si ldap est correctement ajouté à la table de correspondance passwd et toute autre table que vous interrogez.

  • nss_ldap : vérifiez que le paquetage nss_ldap est installé.

  • /etc/ldap.conf : vérifiez la recherche de base sur le serveur et si SSL est utilisé, ou non. S'il fonctionne, vérifiez l'information relative au certificat sur le serveur et le client.

  • Données utilisateur : vérifiez si l'utilisateur existe sur le serveur LDAP et que les données sont correctes (classe d'objet posixAccount). Vérifiez les ACL. Essayez de faire manuelleent la commande de recherche que nss_ldap fait.

2.9.2. Fichiers journaux du serveur

OpenLDAP vous donne un niveau exhaustif de détails en ce qui concerne les fichiers journaux du serveur. Celui qui est le plus utilisé, et celui que nous recommandons pour commencer à déboguer, est le 256. Donc, lorsque vous déboguez, assurez-vous de commencer avec loglevel 256 dans slapd.conf. D'autres niveaux sont disponibles, lisez la page de man de slapd.conf(5) pour une liste complète.

2.9.3. Cas divers

Pour qu'un serveur d'identité fonctionne correctement, plusieurs services sont nécessaires. Voici une liste non exhaustive :

  • Protocole de temps réseau (NTP) : obligatoirement requis par le serveur Kerberos, c'est toutefois une bonne idée d'exécuter ce service sur tous les serveurs afin d'assurer qu'ils soient tous à la même heure.

  • Service de nom de dommaine (DNS) : il est aussi obligatoire d'avoir un service DNS bien configuré et disponible sur le réseau. PLueisurs services échoueront probablement de façon bizarre si le DNS n'est pas disponible ou mal configuré.

  • Permission de système de fichiers : le démon slapd est exécuté en tant qu'utilisateur non privilégié. Parfois, on exécute la commande db_recover en tant que root et on oublie de changer le propriétaire des fichiers qui ont été touchés par ldap. L'initscript s'occupe de ceci automatiquement, mais parfois on exécute des choses en mode de débogage sans l'initscript, et cela échouera si le démon ne peut pas lire les fichiers de la base de données. La même logique s'applique au fichier de configuration principal et aux certificats SSL : ils doivent être lisibles par l'utilisateur ldap.

  • Si slapd échoue soudainement au démarrage lorsque le recouvrement (overlay) vient d'être ajouré, la cause probable est que /var/heimdal a des permissions strictes et que l'utilisateur ldap ne peut pas entrer dans le répertoire. Donnez simplement au groupe ldap les permissions r-x pour ce répertoire et tout devrait fonctionner.