Depuis la version 2.4, le moteur de stockage recommandé par défaut pour OpenLDAP est MDB ou LMDB (Lightning Memory-Mapped Database). Dans les distributions Red Hat par contre, c'est toujours le moteur BDB (Berkeley DataBase), ou son évolution HDB (Hierarchical Database) qui est recommandé et utilisable, vu la version ancienne utilisé : 2.4.23.
HDB est une variante du backend BDB. HDB utilise un modèle hiérarchique, qui supporte notamment le renommage d'un sous-arbre. Etant basé sur BDB, les mêmes options de configurations sont présentes.
OpenLDAP recommande d'utiliser la version la plus récente de l'annuaire, qui corrige des bugs et apporte des améliorations. En cette fin d'année 2013, c'est actuellement la version 2.4.38.
Si l'on a installé un OpenLDAP depuis plusieurs années, on peut vouloir changer le moteur, afin d'améliorer les performances et de s'assurer du support OpenLDAP.
Instanciation d'une base BDB (ou HDB)
On peut facilement créer un suffixe avec une base BDB ou HDB, via la commande :
ldapadd -c -x -D cn=admin,cn=config -w password -f newbdb.ldif
Si on utilise une authentification système (par défaut), la commande sera la suivante :
ldapadd -Y EXTERNAL -H ldapi:/// -f newbdb.ldif
Le contenu du fichier newbdb.ldif étant le suivant :
dn: olcDatabase=bdb,cn=config objectClass: olcDatabaseConfig objectClass: olcBdbConfig olcDatabase: bdb olcSuffix: dc=example,dc=bdb olcDbDirectory: /data/openldap/example-bdb olcRootDN: cn=Manager,dc=example,dc=bdb olcRootPW: secret olcDbIndex: uid pres,eq olcDbIndex: cn,sn pres,eq,approx,sub olcDbIndex: objectClass eq olcDbCacheSize: 20000 olcDbCheckpoint: 512 30 olcDbConfig: set_cachesize 0 10485760 0 olcDbConfig: set_lg_bsize 2097512 olcDbConfig: set_flags DB_LOG_AUTOREMOVE olcAccess: to attrs=userPassword by self write by anonymous auth by dn.base="cn=Manager,dc=example,dc=bdb" write by * none olcAccess: to * by self write by dn.base="cn=Manager,dc=example,dc=bdb" write by * read
Idem pour un backend HDB :
dn: olcDatabase=hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: hdb olcSuffix: dc=example,dc=hdb olcDbDirectory: /data/openldap/example-hdb olcRootDN: cn=Manager,dc=example,dc=hdb olcRootPW: secret olcDbIndex: uid pres,eq olcDbIndex: cn,sn pres,eq,approx,sub olcDbIndex: objectClass eq olcDbCacheSize: 20000 olcDbCheckpoint: 512 30 olcDbIDLcacheSize: 320000 olcDbConfig: set_lg_bsize 2097512 olcDbConfig: set_flags DB_LOG_AUTOREMOVE olcAccess: to attrs=userPassword by self write by anonymous auth by dn.base="cn=Manager,dc=example,dc=hdb" write by * none olcAccess: to * by self write by dn.base="cn=Manager,dc=example,dc=hdb" write by * read
Les options olcDbConfig permettent de générer le fichier DB_CONFIG dans le répertoire des données.
Note : pour une database de type hdb, la valeur idlcachesize doit être importante pour avoir de bonnes performances en lecture / recherche, typiquement 3 fois ou plus la taille du cache d'entrées.
Note : il faut auparavant avoir créer le répertoire correspondant à olcDbDirectory, et mettre le compte ldap comme propriétaire de ce répertoire. Par exemple :
mkdir -p /data/openldap/example-hdb chown ldap:ldap /data/openldap/example-hdb
Cohabitation HDB / BDB
Si on utilise les 2 backends conjointement sur le même serveur, le démarrage du daemon slapd donne un message d'avertissement :
back-bdb/back-hdb monitor: "olmBDBAttributes" previously defined "1.3.6.1.4.1.4203.666.1.55.0.1.1" back-bdb/back-hdb monitor: "olmBDBObjectClasses" previously defined "1.3.6.1.4.1.4203.666.3.16.0.1.1"
Avantage de HDB
Le modèle HDB permet de renommer un sous-arbre complet via l'opération modrdn, mais pas BDB. Par exemple, si on a le fichier ldif suivant :
dn: ou=BACKEND-HDB,ou=users,dc=example,dc=corp changetype: modrdn newrdn: ou=BACKEND-RENAMED deleteoldrdn: 1
Sur l'annuaire 121 cette database utilise BDB. On a alors :
ldapmodify -x -h 192.168.56.121 -D "cn=admin,dc=example,dc=corp" -w secret modrdn.ldif ldap_initialize( ldap://192.168.56.121 ) modifying rdn of entry "ou=BACKEND-HDB,ou=users,dc=example,dc=corp" new RDN: "ou=BACKEND-RENAMED" (do not keep existing values) ldap_rename: Operation not allowed on non-leaf (66) additional info: subtree rename not supported
Sur l'annuaire 122, la database utilise HDB. Le résultat est différent :
ldapmodify -x -h 192.168.56.122 -D "cn=admin,dc=example,dc=corp" -w secret modrdn.ldif ldap_initialize( ldap://192.168.56.122 ) modifying rdn of entry "ou=BACKEND-HDB,ou=users,dc=example,dc=corp" new RDN: "ou=BACKEND-RENAMED" (do not keep existing values) rename complete
Réplication HDB / BDB
On peut tout à fait avec deux moteurs différents sur 2 serveurs qui se répliquent. Ceci permet par exemple de procéder par étape pour un changement de backend sur une architecture avec de multiples serveurs.
Les tests effectués en mode master / miroir ont montré que la réplication fonctionnait de manière tout à fait normale, sauf dans un cas : le renommage de subtree sur l'annuaire utilisant HDB. Dans ce cas, l'opération n'est pas répliquée sur le serveur utilisant BDB.
Instanciation MDB
Le backend MDB peut être instancié avec peu d'éléments :
dn: olcDatabase=mdb,cn=config objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: mdb olcSuffix: dc=example,dc=mdb olcDbDirectory: /data/openldap/example-mdb olcRootDN: cn=Manager,dc=example,dc=mdb olcRootPW: secret olcDbMaxSize: 1073741824
La variable olcDbMaxSize doit être égale (ou supérieure) à la taille des données de l'annuaire, car le moteur MDB travaille en mémoire.
Procédure de migration
Les backends n'étant pas compatible physiquement, il n'est pas possible de modifier uniquement la configuration de la Database. Le changement de type de backend comporte également une migration de données, qui doit s'effectuer de manière "logique" :
- Arrêt du daemon slapd
- Export des données en LDIF (via slapcat)
- Sauvegarde de l'ancien répertoire (pour le retour arrière)
- Changement de la configuration de la database
- Chargement des données (via slapadd)
- Redémarrage du daemon et contrôle
Changement de configuration
Deux options peuvent être envisagées :
- Modification des fichiers LDIF de configuration (dans le répertoire slapd.d/cn=config)
- Création de la nouvelle base, via un fichier LDIF et un ldapadd
Option 1 : modification du fichier de configuration
Dans ce cas, on copie / renomme les fichiers /etc/openldap/slapd.d/cn=config/olcDatabase={X}bdb.ldif en /etc/openldap/slapd.d/cn=config/olcDatabase={X}hdb.ldif et on modifie les instances bdb par hdb :
dn: olcDatabase={2}bdb objectClass: olcBdbConfig olcDatabase: {2}bdb structuralObjectClass: olcBdbConfig
devient
dn: olcDatabase={2}hdb objectClass: olcHdbConfig olcDatabase: {2}hdb structuralObjectClass: olcHdbConfig
Les modifications doivent être faites une fois l'annuaire arrêté.
Si on a mis en place des overlays, il faut également renommer le répertoire content la définition de ces overlays. Dans notre cas, le répertoire
/etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb
sera renommé en
/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb
Option 2 : ajout de la DB par LDIF
Dans cette option, il faut supprimer la database déclarée avec bdb, et ajouter la même database utilisant hdb. En effet, il n'est pas possible d'utiliser 2 databases pour le même root Suffix.
Il faut tout d'abord identifier le numéro de la database utilisée :
ldapsearch -D 'cn=admin,cn=config' -w secret -x -b "cn=config" "objectclass=olcbdbconfig" # {4}bdb, config dn: olcDatabase={4}bdb,cn=config objectClass: olcDatabaseConfig objectClass: olcBdbConfig olcDatabase: {4}bdb olcDbDirectory: /product/openldap/data/example-bdb olcSuffix: dc=example-bdb,dc=com olcAccess:: ezB9dG8gYXR0cnM9dXNlclBhc3N3b3JkIGJ5IHNlbGYgd3JpdGUgIGJ5IGFub255bW 91cyBhdXRoICBieSBkbi5iYXNlPSJjbj1BZG1pbixkYz1leGFtcGxlLWJkYixkYz1jb20iIHdyaXR lIGJ5ICogbm9uZSA= olcAccess: {1}to * by self write by dn.base="cn=Admin,dc=example-bdb,dc=com" w rite by * read olcRootDN: cn=Manager,dc=example-bdb,dc=com olcRootPW: secret olcDbIndex: uid pres,eq olcDbIndex: cn,sn pres,eq,approx,sub olcDbIndex: objectClass eq
Dans notre exemple, c'est la database numéro 4 qu'il faudra supprimer.
La suppression n'est pas (a priori) faisable via une commande ldap. Il faut donc arrêter le service slapd, et supprimer le fichier manuellement.
Il faut également se positionner dans le répertoire des données, et supprimer tous les fichiers (que l'on aura sauvegardé auparavant, bien sûr).
La nouvelle database peut être crée via un fichier LDIF, une fois le service redémarré. Dans notre exemple, le fichier LDIF est :
dn: olcDatabase=hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: hdb olcSuffix: dc=example-bdb,dc=com olcDbDirectory: /product/openldap/data/example-bdb olcRootDN: cn=Manager,dc=example-bdb,dc=com olcRootPW: secret olcDbIndex: uid pres,eq olcDbIndex: cn,sn pres,eq,approx,sub olcDbIndex: objectClass eq olcAccess: to attrs=userPassword by self write by anonymous auth by dn.base="cn=Admin,dc=example-bdb,dc=com" write by * none olcAccess: to * by self write by dn.base="cn=Admin,dc=example-bdb,dc=com" write by * read
La création s'effectue de la manière suivante :
service slapd start ldapadd -D 'cn=admin,cn=config' -w secret -x -f hdb-conf.ldif
Chargement des données
On peut alors charger les données issues du slapcat, après avoir arrêté le daemon via la commande :
service slapd stop slapadd -b BASE -q -l FICHIER.ldif
Il faut ensuite remettre les droits corrects sur les données.
Points à vérifier
Si on passe d'un serveur à un autre, il faut également récupérer toutes les définitions de schéma.
De même, il faut s'assurer que les overlays soient en place sur les 2 configurations, sinon l'import des données risque de tombe en erreur. Notamment les attributs liés aux password policy
Note : Le core.ldif ne contient plus l'attribut userPassword ? (commenté dans /etc/ldap/schema/core.ldif). Il faut alors modifier : pwdAttribute: userPassword
en pwdAttribute: 2.5.4.35
syntaxe de pwdAttribute = OID