28 janvier 2021

Tuto Openldap, partie VI : Réplication

Sixième partie de la série de tuto sur OpenLDAP consacrée à la réplication.

Nous allons mettre en place une réplication Maitre-Maitre. L’idée est de faire en sorte que n’importe lequel de nos serveurs LDAP soit capable à la fois de lire les données, mais également de les modifier. De plus,nous allons mettre en place une réplication, à la fois sur l’arbre de données dc=debugo,dc=fr mais également sur l’arbre de configuration cn=config.

 

I – Prérequis

Sur un nouveau serveur, installez OpenLDAP, puis comme pour le serveur déjà en place:

# dpkg-reconfigure slapd

Mettez les informations que vous aviez renseignées.

Effectuez également la configuration de rsyslog.

Maintenant, sur le premier serveur, créez des sauvegardes de la configuration et des données (suivez ce tuto). Puis, depuis le premier serveur, nous allons envoyer les fichiers de sauvegarde sur le second serveur, ceci afin de gagner du temps. Pas de besoin de tout reconfigurer à l’identique.

maitre1# scp save_*.ldif root@maitre2:/root

Ensuite, réinjectez les sauvegardes en suivant la partie II de l’article Sauvegarde et restauration.

 

II – Configuration

Ce qui suit est à faire sur chaque serveur !

A – Activation Overlay

Nous allons commencer par activer l’Overlay Syncprov à l’aide d’un fichier 01-syncprov_act.ldif :

dn: cn=module,cn=config
cn: module
objectclass: olcModuleList
objectclass: top
olcmoduleload: syncprov.la
olcmodulepath: /usr/lib/ldap

On injecte :

ldapx# ldapadd -Y EXTERNAL -H ldapi:/// -f 01-syncprov_act.ldif

On peut vérifier avec :

ldapx# ldapsearch -LLLY external -H ldapi:/// -b "cn=config" "objectClass=olcModuleList"
ldapx# ldapsearch -LLLY external -H ldapi:/// -b "cn=module{6},cn=config"

B – ServerID

Sur chaque serveur, un fichier 02-serverid.ldif :

dn: cn=config
changetype: modify
add: olcServerID
olcServerID: x

Attention, sur le premier serveur olcServerID:1, sur le second  olcServerID: 2, etc…

On injecte :

ldapx# ldapmodify -Y EXTERNAL -H ldapi:/// -f 02-serverid.ldif

Pour vérifier :

ldapx# ldapsearch -LLLY external -H ldapi:/// -b "cn=config" "objectClass=olcGlobal" olcServerID

C – Création utilisateur réplication

Ensuite, nous allons créer un utilisateur pour la replication dans un fichier 03-replica_account.ldif :

dn: cn=replica,ou=system,dc=debugo,dc=fr
userPassword: password
cn: replica
objectclass: top
objectclass: person
sn: replica

On injecte :

ldapx#  ldapadd -x -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -y /root/pwdldap -f 03-replica_account.ldif

 

III – Réplication de la configuration

Ces manipulations sont toujours à effectuer sur les deux serveurs.

A – ACL

Nous allons donner à l’utilisateur cn=replica,dc=debugo,dc=fr le droit de modifier la configuration via un fichier 04-droit_conf.ldif :

dn: olcDatabase={0}config,cn=config
changeType: modify
add: olcAccess
olcAccess: to * by dn.exact=cn=replica,ou=system,dc=debugo,dc=fr manage by * break

On injecte

ldapx# ldapmodify -Y EXTERNAL -H ldapi:/// -f 04-droit_conf.ldif

B – Configuration

Créez un fichier 05-syncprov_conf_conf.ldif pour y mettre :

dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov

Injectez :

ldapx# ldapmodify -Y EXTERNAL -H ldapi:/// -f 05-syncprov_conf_conf.ldif

C – Paramétrage

Créez un fichier 06-repl_conf_conf.ldif pour y mettre :

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=01 provider=ldap://IPSERVEUR1
  binddn="cn=replica,ou=system,dc=debugo,dc=fr" bindmethod=simple
  credentials=password searchbase="cn=config"
  type=refreshAndPersist retry="5 5 300 5" timeout=1
olcSyncRepl: rid=02 provider=ldap://IPSERVEUR2
  binddn="cn=replica,ou=system,dc=debugo,dc=fr" bindmethod=simple
  credentials=password searchbase="cn=config"
  type=refreshAndPersist retry="5 5 300 5" timeout=1
-
add: olcMirrorMode
olcMirrorMode: TRUE

Les lignes binddn, credentials, et type doivent commencer avec deux espaces.

et injectez :

ldapx# ldapmodify -Y EXTERNAL -H ldapi:/// -f 06-repl_conf_conf.ldif

Vérifiez avec :

# ldapsearch -QLLLY external -H ldapi:/// -b "cn=config" "olcDatabase={0}config" olcSyncRepl

Et voila !

Si vous modifiez la configuration sur un serveur (des ACLs par exemple), cela sera répliqué sur l’autre.

Dans les logs, on doit voir des traces de la synchro. Et pour être sur que tout est bien configuré :

# ldapsearch -z1 -LLLQY EXTERNAL -H ldapi:/// -s base -b cn=config contextCSN

doit vous donner le même contextCSN sur chaque serveur.

 

IV – Réplication des données

Ces manipulations ne sont à faire que sur un serveur étant donné que la réplication de la configuration est en place !

A – ACL et limitation

Nos acls avaient déjà été établies.

Vérifiez sur les deux serveurs :

ldapx# ldapsearch -QLLLY external -H ldapi:/// -b "cn=config" "olcDatabase={1}mdb" olcAccess

Doit vous donner :

dn: olcDatabase={1}mdb,cn=config
olcAccess:
  {0}to attrs=userPassword
  by self write by anonymous auth
  by dn="cn=writer,ou=system,dc=debugo,dc=fr" write
  by dn="cn=viewer,ou=system,dc=debugo,dc=fr" read
  by dn="cn=admin,dc=debugo,dc=fr" write
  by * none
olcAccess:
  {1}to dn.base="dc=debugo,dc=fr"
  by users read
olcAccess:
  {2}to *
  by self write
  by dn="cn=admin,dc=debugo,dc=fr" write
  by * read
  by anonymous none

Nous allons les modifier avec un fichier 07-acl_replica.ldif pour donner le droit à l’utilisateur réplica de TOUT lire (y compris les passwords)  :

dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to attrs=userPassword by self write by anonymous auth by dn="cn=writer,ou=system,dc=debugo,dc=fr" write by dn="cn=viewer,ou=system,dc=debugo,dc=fr" read by dn="cn=admin,dc=debugo,dc=fr" write by dn.exact="cn=replica,ou=system,dc=debugo,dc=fr" read by * none
olcAccess: to dn.subtree="dc=debugo,dc=fr" by users read by * none
olcAccess: to * by self write by dn="cn=admin,dc=debugo,dc=fr" write by * read by anonymous none

On injecte :

ldap1# ldapmodify -Y EXTERNAL -H ldapi:/// -f 07-acl_replica.ldif

Vous pouvez vérifier sur chaque serveur, c’est à jour :

ldapx# ldapsearch -QLLLY external -H ldapi:/// -b "cn=config" "olcDatabase={1}mdb" olcAccess

Au passage, on va modifier les limitations dans un fichier 08-limit.ldif :

dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcLimits
olcLimits: dn.exact="cn=replica,ou=system,dc=debugo,dc=fr" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited

On injecte :

ldap1# ldapmodify -Y EXTERNAL -H ldapi:/// -f 08-limit.ldif

B – Index

On va indexer entryCSN et entryUUID à l’aide d’un fichier 09-index.ldif :

dn:olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: entryCSN,entryUUID eq

On injecte :

ldap1# ldapmodify -Y EXTERNAL -H ldapi:/// -f 09-index.ldif

C – Configuration

On va configurer l’overlay sur la base {1}mdb, qui correspond à notre dc=debugo,dc=fr, avec un fichier 10-syncprov_conf_data.ldif :

dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov

Injectez :

ldap1# ldapmodify -Y EXTERNAL -H ldapi:/// -f 10-syncprov_conf_data.ldif

D – Paramétrage

Créez un fichier 11-repl_conf_data.ldif et insérez :

dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=01 provider=ldap://IPSERVEUR1
  binddn="cn=replica,ou=system,dc=debugo,dc=fr"
  bindmethod=simple credentials=password
  searchbase="dc=debugo,dc=fr"
  type=refreshAndPersist retry="5 5 300 5" timeout=1
olcSyncRepl: rid=02 provider=ldap://IPSERVEUR2
  binddn="cn=replica,ou=system,dc=debugo,dc=fr"
  bindmethod=simple credentials=password
  searchbase="dc=debugo,dc=fr"
  type=refreshAndPersist retry="5 5 300 5" timeout=1
-
add: olcMirrorMode
olcMirrorMode: TRUE

Injectez :

ldap1# ldapmodify -Y EXTERNAL -H ldapi:/// -f 11-repl_conf_data.ldif

Pour vérifier la synchro, sur un des serveurs, effectuez par exemple une modification d’attribut sur un utilisateur, puis sur les deux serveurs, lancez la commande :

ldapx# ldapsearch -z1 -LLLQY EXTERNAL -H ldapi:/// -s base -b dc=debugo,dc=fr contextCSN

Celle ci doit vous donner la meme réponse. Il faut qu’il y ait eu une modification (changement d’attribut par exemple) sans quoi l’attribut contextCSN n’existera pas.

 

V – Dernier réglage

Dernier point, concernant un petit effet de bord du à la synchro des configurations :

Vos serveurs se retrouvent avec le meme ServerID :

ldapx# ldapsearch -x -LLL -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -w passadmin -b cn=config "objectClass=olcGlobal"

Pour modifier cela, pas le choix, nous allons devoir éditer le fichier directement (si on refait un ldif qu’on injecte ça va se répliquer…). C’est le mal d’éditer les configs ldap à la main, mais ce coup ci, on a guère le choix…

Du coup, sur les deux serveurs, on arrête slapd :

ldapx# service slapd stop

Puis on va éditer le fichier /etc/ldap/slapd.d/cn\=config.ldif pour renseigner :

olcServerID: X

Ou X sera égal à 1 sur le premier serveur et égal à 2 sur le second.

Puis on relance les deux serveurs: :

ldapx# service slapd start

Et maintenant sur chaque serveur, la commande :

ldapx# ldapsearch -x -LLL -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -w passadmin -b cn=config "objectClass=olcGlobal"

donne bien son ID propre.

 

Voila qui clos la partie sur la réplication à proprement parlé.

Dans la partie suivante, nous allons rajouter Keepalived, qui nous permettra d’avoir une IP virtuelle unique pour interroger nos LDAPs.

 


 

16 réflexions sur « Tuto Openldap, partie VI : Réplication »

    1. De rien 😉
      J’ai refais quelques modification à l’instant pour info.

      Aujourd’hui, je traiterais de la mise en place de Keepalived pour avoir une IP unique.

  1. Super merci ! Continue comme ça, ton blog est génial et surtout claire et DANS DES VERSIONS D’ACTUALITÉS ! Met en place une plateforme de don je n’hésiterai pas a te soutenir 🙂

    1. Merci !
      Ce genre de commentaires fait toujours plaisir.
      En effet, je tente toujours d’être un maximum didactique dans mes explications en mettant l’accent sur les points qui m’auraient posés soucis, en expliquant comment j’ai solutionné, etc…
      Bref, pas de panique, je continue. Sur le LDAP, il doit me rester trois articles.
      Ensuite, ce sera un tuto sur la messagerie et un autre sur se monter un NAS à domicile (avec système de gestion de films, séries, etc…)
      Pour la partie don, ce n’est pas idiot, je vais regarder à cela.

  2. Merci à toi 🙂 Si tu veux pousser sur le LDAP je pense que l’authentification avec Kerberos peutt-être super intéressant du fait que les docs sont assez pauvre sur le sujet 🙂
    La messagerie est intéressant, j’attends ça avec impatience 🙂

  3. Merci pour ce tuto.
    Je rencontre un souci après avoir tout passé.
    J’ai cette erreur dans les logs:
    do_syncrep2: rid=002 LDAP_RES_SEARCH_RESULT (32) No such object
    do_syncrep2: rid=002 (32) No such object
    do_syncrepl: rid=002 rc -2 retrying (4 retries left)

    Sauriez-vous me dire pourquoi svp?
    do_syncrep2: rid=001 LDAP_RES_SEARCH_RESULT (32) No such object
    do_syncrep2: rid=001 (32) No such object
    do_syncrepl: rid=001 rc -2 retrying (4 retries left)

    1. Hum…
      Les acls pour la réplication sont bonnes ?
      Les comptes réplication également ?

      Je vais tacher de le refaire en test, voir si je n’aurais pas zappé un truc.

      Par contre, je vais être honnête, je pense refaire ce tuto, mais avec juste une réplication Master-Slave.
      Au final, le Slave qui reste Slave en cas de Down du Master n’est pas embêtant dans le cas du service LDAP.
      N’ayant aucune application en écriture dessus (ça ne sert au final que pour la lecture des comptes), il assure toujours le service pour mes autres serveurs et je peux remonter le master quand je veux, n’en ayant besoin que pour faire mes écritures…
      Au passage (oui, je travaille deja sur l’article, mais il n’est pas le prochain, désolé 😉 ) j’ajoute un système qui fait que Xen change la Ram activement en fonction de qui est en charge du service.
      Ainsi au final, si LDAP1 tombe, LDAP2 prend la relève pour les lectures, et voit sa Ram augmentée dynamiquement…
      Arrivant à une trentaine de Domu, je commence à bidouiller un peu…

  4. encore une fois merci pour ce tuto qui rend l’entrée dans LDAP simple et claire.
    Après avoir mis en place la réplication, je vois qu’après quelques semaines d’arrêt de l’un des serveurs, la réplication est devenue unidirectionnelle.
    Lorsque je regarde contextCSN, j’ai bien les deux valeurs sur chaque serveur, correspondant à chaque RID, pour la base cn=config.
    Par contre, pour les données, le serveur qui ne réplique pas les modifs de son homologue n’affiche qu’une ligne contextCSN (correspondant à son propre RID).
    Aurais tu une idée de la source du problème?

    1. Encore une fois, de rien 😉

      Pour ton soucis, je pense que le pourquoi est dans la question : un des serveurs arreté trop longtemps.
      C’est toujours le problème avec les configs master-master.
      C’est lequel qui ne réplique pas ? Celui que tu as relancé ?

      Les logs disent quoi ?
      Au pire, je supprimerais la synchro et la remettrais en place.
      J’ai un article la dessus, mais c’est loin d’être terminé.

  5. Celui que j’ai relancé ne récupère pas en effet les modifs de celui resté allumé.
    J’ai un doute sur les logs. Je ne vois rien dans slapd.log. Je vais chercher faire mieux/

  6. Voici le log, en complément:
    Jan 11 01:00:17 lan-olp-001 slapd[13018]: do_syncrep2: rid=001 LDAP_RES_SEARCH_RESULT (4) Size limit exceeded
    Jan 11 01:00:17 lan-olp-001 slapd[13018]: do_syncrep2: rid=001 (4) Size limit exceeded
    Jan 11 01:00:17 lan-olp-001 slapd[13018]: do_syncrepl: rid=001 rc -2 quitting

    Cela semble se produire lorsqu’un serveur est éteint trop longtemps, en effet. La résolution consisterait à permettre au compte de réplication d’outrepasser via des droits supplémentaires (time.soft=unlimited time.hard=unlimited). Tu proposes déjà de lever cette limitation dans ton tuto. Je ne parviens pas à voir de manière détaillée si le log porte sur la configuration ou sur les données. Je sens que je vais supprimer puis refaire la sync

  7. Salut, et merci pour ce tuto !
    Je suis dans un cas particulier où je souhaite ne répliquer qu’une OU de mon master sur mon slave. J’ai eu l’idée de n’injecter qu’un dump de cette OU et de ne donner le droit en lecture/écriture de mon utilisateur de réplication qu’à cette OU.
    Mais je galère encore avec les ACLs. Est-ce que c’est la bonne méthode ? Si oui, comment bien mettre en place cela et quels sont les points de vigilance à surveiller ? Parce que là je tourne en rond :/

  8. Salut,
    J’ai réussi à m’en sortir après avoir potassé les ACL. J’avais un problème car je n’avais aps injecté le dump entier. Après l’avoir injecté et supprimé les OU qui ne m’intéressait pas, cela a fonctionné (je pense que c’est parce que le context n’était pas le même donc la réplication ne se faisait pas)
    En tout cas merci pour ce tuto précis et concis, c’est rare sur OpenLDAP ! 🙂

  9. Vraiment un très bon tutoriel :
    – très didactique, qui n’hésite pas à prendre les choses à la racine même si c’est évident
    pour un « sachant »
    – clair et complet
    – avec de vrais exemples

    Visiblement un très gros travail, la preuve il est toujours valable quelques années plus tard.

    Bravo et merci

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *