Les problèmes liés à la réplication LDAP Sync
La réplication LDAP Sync est un mécanisme de réplication basé sur l’objet ou autrement dit par entrée d’annuaire. Lorsque la valeur d’un attribut d’une entrée de l’annuaire à répliquer est modifiée, chaque consumer recopie entièrement l’entrée modifiée. Ce qui implique que les valeurs d’attribut inchangées sont également resynchronisées... pour rien.
Un avantage de cette méthode est que lorsque plusieurs changements multiples se produisent sur une même entrée, leur séquence précise n’a pas besoin d’être reproduite  ; seul l’état final de l’entrée est suffisant pour effectuer l’opération de synchronisation. Cependant, cette approche peut avoir des inconvénients lorsque des modifications se produisent sur un très grand nombre d’entrées de l’annuaire.
Par exemple, pour un annuaire composé d’une centaine de milliers d’entrées (ex. 100000 entrées) totalisant en moyenne 1 KB d’information chacune, une opération quotidienne modifie la valeur d’un attribut (représentant 1 ou 2 Bytes) pour chacune de ces entrées, cela signifie que le consumer transférera la totalité des entrées, soit 100 MB de données, alors que les modifications n’auront totalisé qu’1 ou 2 Mb de données seulement... Tout cela sans compter les données utilisées par les protocoles LDAP et TCP/IP utilisées pour le transfert des informations. Il y a donc dans ce cas de figure un gaspillage de transmission et de traitement pour les 98 % d’informations qui n’ont pas été modifiées.
Bien que cette situation soit particulière, elle sert à démontrer une faiblesse de ce mécanisme de réplication, à prendre en considération selon l’environnement de production concerné.
Sans parler aussi de problèmes qui pourraient survenir lors de changement de valeur d’attribut d’une même entrée sur deux annuaires en réplication, dans ce cas, le changement de valeur d’un attribut serait perdu.
OpenLDAP fournit deux méthodes pour améliorer ces problèmes : le journal de session (sessionlog) et le journal de changement (changelog). L’objectif de ces deux méthodes étant bien entendu de minimiser le transfert de données entre un provider et un consumer et de résoudre les problèmes d’accès aux mêmes entrées au même moment.
1. SessionLog
Le journal de session (sessionlog) est chargé en mémoire et conserve toutes les opérations effectuées (sauf les opérations d’ajout) sur le DIT à répliquer du provider. Selon la période couverte par le journal de la session, il peut permettre au provider de sauter la present phase facultative - ce qui accélère considérablement le processus de synchronisation. Si, par exemple, aucun changement n’a eu lieu dans le journal des sessions depuis la dernière synchronisation, il n’est pas nécessaire d’avoir une present phase. Le journal des sessions peut être utilisé avec n’importe quel type de réplication (refreshOnly ou refreshAndPersist), mais est clairement le plus utile avec refreshOnly. Si le journal des sessions n’est pas assez grand pour couvrir la période depuis la dernière demande de synchronisation du consumer, une séquence de resynchronisation complète (y compris la present phase) est invoquée. Aucun paramètre spécial olcSyncrepl n’est requis chez le consumer lors de l’utilisation du journal des sessions.
Exemple de configuration au niveau du provider :
dn: olcOverlay=syncprov, olcDatabase={1}bdb,cn=config 
objectclass: olcSyncProvConfig 
olcOverlay: syncprov 
olcSpSessionlog: 100 
olcSpCheckpoint: 100 10
2. Delta-syncrepl ou AccessLog
Le mécanisme de réplication "Delta-syncrepl" est une variante du mécanisme de réplication "syncrepl", permettant de résoudre le problème évoqué précédemment. En effet, il fonctionne en maintenant un journal de changement (changelog ou accesslog) stocké dans un annuaire dédié du provider. Chaque entrée de ce journal enregistre les modifications survenues sur les entrées du DIT ou de la partie du DIT à répliquer. Ainsi, le consumer consultant le "changelog" du provider, ne rapatriera pas les modifications sur son propre annuaire. Cependant, si une réplique (un DIT du consumer) a été trop longtemps désynchronisée (arrive lors d’une rotation où des entrées du changelog ont été écrasées pour être remplacées par de nouvelles) ou se retrouve complètement vide, alors le "syncrepl" conventionnel sera utilisé pour mettre à niveau le réplica, puis le mode "delta-syncrepl" sera à nouveau utilisé comme mode de réplication quotidien.
¬
Puisque l’état de l’annuaire est stocké à la fois dans le DIT du "changelog" et dans le DIT principal, il est important de sauvegarder/restaurer les deux à la fois à l’aide des outils d’administration "slapcat/slapadd" lors du rétablissement d’une connexion de réplication sur un consumer.
¬
Figure 15-3 : Delta-syncrepl
La configuration de ce mécanisme étant assez complexe, son utilité doit donc être étudiée afin de juger s’il est réellement nécessaire. Si l’ensemble des conditions ci-dessous sont rencontrées dans votre architecture alors il faudra envisager son utilisation :
	•	La taille des entrées est en moyenne supérieure à une dizaine de kilo-octets.
	•	Le volume de modification d’objets est supérieur à, par exemple, 20 % de DIT par jour ou à toute période de pointe ET le pourcentage d’entrée modifié est inférieur à, par exemple, 50 % .
	•	La bande passante du réseau est limitée occasionnant de la congestion.
a. Exemple de configuration
L’utilisation de cette forme de réplication nécessite la création d’un DIT sur le provider, dédié à l’enregistrement des actions effectuées sur le DIT à répliquer et l’utilisation des paramètres logbase, logfilter et syncdata de l’attribut olcSyncrepl dans la configuration du consumer.
L’exemple qui va suivre proposera la configuration d’une réplication en mode ’Delta-syncrepl’ entre un provider et un consumer. Bien sûr, cette configuration pourra être également utilisée dans une configuration multimaître.
Au niveau du provider
1.	Il faut tout d’abord créer un utilisateur de liaison qui sera utilisé par le consumer pour établir la connexion de réplication. Cet utilisateur se verra attribuer le droit de lecture sur tous les DIT de l’annuaire (car défini au niveau de cn=config).	
dn: cn=config 
changetype: modify 
add: olcAccess 
olcAccess: {x} to * 
     by dn.base="cn=admin,ou=people,dc=example,dc=com" read 
     by * break 
2.	Puis définir des index afin d’améliorer les performances (optionnel).	
dn: olcDatabase={1}bdb,cn=config 
changetype: modify 
add: olcDbIndex 
olcDbIndex: entryCSN eq 
olcDbIndex: entryUUID eq
3.	Ensuite, ajouter l’entrée accesslog en tant que fonctionnalité (overlay) avec les paramètres suivants :	
	•	efface les entrées de plus de 2 jours,
	•	enregistre les écritures (ajout, suppression et modification),
	•	enregistre uniquement les opérations réussies,
	•	fixe la base du DIT (cn = deltalog).
dn: olcOverlay={0}accesslog,olcDatabase={1}bdb,cn=config 
objectclass: olcAccessLogConfig 
olcOverlay: {0}accesslog 
olcAccessLogDb: cn=deltalog 
olcAccessLogOps: writes 
olcAccessLogSuccess: TRUE 
olcAccessLogPurge: 2+00:00 1+00:00
4.	Ajouter l’entrée syncprov en tant que fonctionnalité (overlay) et définir la gestion du cookie "point de contrôle" (ici mise à jour toutes les 100 opérations ou toutes les dix minutes).	
dn: olcOverlay={1}syncprov, olcDatabase={1}bdb,cn=config 
objectclass: olcSyncProvConfig 
olcOverlay: {1}syncprov 
olcSpCheckpoint: 100 10
5.	Création de l’entrée définissant le DIT cn=deltalog utilisé pour y stocker les enregistrements de synchronisation.	
dn: olcDatabase={2}bdb,cn=config 
objectClass: olcBdbConfig 
olcDatabase: bdb 
olcSuffix: cn=deltalog 
olcDbDirectory: /var/db/delta 
olcDbIndex: entryCSN,objectClass, reqEnd, reqResult, reqStart eq
6.	Ajout également de la fonctionnalité de provider (overlay: syncprov) pour le DIT de l’accesslog avec les attributs :	
	•	OlcSpNoPresent: TRUE obligatoire pour la synchronisation delta.
	•	OlcSpReloadHint: TRUE obligatoire pour la synchronisation delta.
dn: olcOverlay={0}syncprov, olcDatabase={2}bdb,cn=config 
objectclass: olcSyncProvConfig 
olcOverlay: {0}syncprov 
olcSpCheckpoint: 100 10 
olcSpNoPresent: TRUE 
olcSpReloadHint: TRUE
¬
Lors de l’étape (1) : il est toujours conseillé d’utiliser un utilisateur de liaison dédié à la réplication plutôt que d’utiliser le "rootDN" de l’annuaire. En effet, l’activité de réplication nécessite seulement le droit de "lire" sur le DIT ciblé.
Au niveau du consumer
Dans la configuration du consumer, il faudra ajouter les paramètres logbase, logfilter et syncdata comme dans l’exemple ci-dessous :
dn: olcDatabase={1}bdb,cn=config 
changetype: modify 
add: olcSyncrepl 
olcSyncRepl: {0}rid=000  
  provider=ldap://ldap1.example.com 
  type=refreshAndPersist 
  retry="5 5 300 +"  
  searchbase="dc=example,dc=com" 
  attrs="*,+" 
  bindmethod=simple 
  binddn="cn=admin,ou=people,dc=example,dc=com" 
  credentials=dirtysecret 
  logbase="cn=deltalog" 
  logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" 
  syncdata=accesslog 
	•	Le paramètre logfilter= (& (objectClass = auditWriteObject) (reqResult = 0)) lit toutes les entrées du DIT de l’accesslog qui ont réussi (reqResult = 0). La valeur de ce paramètre peut sembler redondante puisque nous avons défini dans le provider le paramètre : olcAccessLogSuccess: TRUE qui enregistre seulement les opérations qui ont réussi.
	•	Le consumer peut être initialisé avec un DIT vide, celui-ci se remplira lors de la synchronisation initiale, puis les opérations de mises à jour seront appliquées par le mécanisme d’accesslog.