opendj https://www.vincentliefooghe.net/index.php/ fr Forgerock OpenDJ / DS - Supprimer les contrôles de syntaxe https://www.vincentliefooghe.net/index.php/content/forgerock-opendj-ds-supprimer-les-contr%C3%B4les-syntaxe <span class="field field--name-title field--type-string field--label-hidden">Forgerock OpenDJ / DS - Supprimer les contrôles de syntaxe</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Par défaut les nouveaux annuaires LDAP issus des sources OpenDS (tels que OpenDJ / DS chez Forgerock, mais aussi Ping Directory) renforcent les contrôles sur la syntaxe des attributs, le schéma, etc.</p> <p>Ceci empêche par exemple d'avoir un objet avec de multiples classes structurelles non hiérarchiques (par exemple <em>inetorgperson</em> et <em>country</em>).</p> <p>Par contre lorsqu'on importe des données d'un annuaire un peu moins strict (type Sun / Oracle DSEE), on se heurte souvent à des erreurs.</p> <p>La solution la plus propre est de modifier le fichier LDIF pour remettre au carré les données :</p> <ul> <li>supprimer / modifier les attributs non conformes</li> <li>modifier le schéma pour éviter les héritages multiples</li> </ul> <p>Mais ceci n'est pas toujours faisable.</p> <p>On peut alors relâcher les contrôles effectuer, en utilisant l'utilitaire <em>dsconfig </em>(testé depuis la version OpenDJ 2.6 jusque DS 7) :</p> <pre> #!/bin/bash PORT=5444 HOST=djlyreco BINDPASS="SuperPa$$w0rd" cd /path/to//opendj # Do not check schema bin/dsconfig set-global-configuration-prop --hostname $HOST --port ${PORT} --bindDN "cn=Directory Manager" \ --bindPassword ${BINDPASS} --set check-schema:false --trustAll --no-prompt # Allows multiple structural object classes (warning only) bin/dsconfig set-global-configuration-prop --hostname $HOST --port ${PORT} --bindDN "cn=Directory Manager" \ --bindPassword ${BINDPASS} --set single-structural-objectclass-behavior:warn --trustAll --no-prompt # Allows invalid attribute syntax bin/dsconfig set-global-configuration-prop --hostname $HOST --port ${PORT} \ --bindDN "cn=Directory Manager" --bindPassword ${BINDPASS} --set invalid-attribute-syntax-behavior:warn --trustAll --no-prompt # Allow pre-encoded passwords : pour l'import de compte avec des mots de passe existant bin/dsconfig -p ${PORT} -h $HOST -D "cn=Directory Manager" -w ${BINDPASS} \ set-password-policy-prop --policy-name "Default Password Policy" --set allow-pre-encoded-passwords:true -X -n</pre><p> </p> <p>La dernière ligne permet également d'importer des mots de passe pré-encodés. C'est utile en cas de migration de données entre annuaires, pour garder les mêmes mots de passe.</p> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/user/1" typeof="schema:Person" property="schema:name" datatype="">Vincent</span></span> <span class="field field--name-created field--type-created field--label-hidden">mer 09/12/2020 - 11:30</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/ldap" hreflang="fr">ldap</a></div> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> <h2 class="title comment-form__title">Ajouter un commentaire</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=208&amp;2=comment_node_book&amp;3=comment_node_book" token="FCUJHl0s_eMjKa8Cw3DvkSQUZ310pub5HrSmdbeosj4"></drupal-render-placeholder> </section> Wed, 09 Dec 2020 10:30:28 +0000 Vincent 208 at https://www.vincentliefooghe.net Upgrade Forgerock OpenDJ / DS https://www.vincentliefooghe.net/index.php/content/upgrade-forgerock-opendj-ds <span class="field field--name-title field--type-string field--label-hidden">Upgrade Forgerock OpenDJ / DS</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Deux scénarios de migration / upgrade seront étudiés :</p> <ul> <li>upgrade "en place" d'un annuaire en version inférieure</li> <li>ajout dans la topologie de réplication d'un annuaire en version supérieure.</li> </ul> <p>Dans cet exemple, on va procéder à une migration de la version OpenDJ 3.5.1 à la version DS 6.5.</p> <h2>Environnement</h2> <p>L'environnement de test est le suivant :</p> <p>3 serveurs : <em>dj1.id-num.com</em>, <em>dj2.id-num.com</em>, <em>dj3.id-num.com</em>.</p> <p>Dans un premier temps, seuls les serveurs dj1 et dj2 sont installés, en mode multi-maîtres :</p> <ul> <li>O.S. CentOS 7</li> <li>Java jre 1.8</li> <li>OpenDJ 3.5.1, avec 2 annuaires répliqués</li> <li>Schéma de données <em>custom</em> avec attributs et classes d'objets spécifiques</li> <li>Annuaire installé dans le répertoire <code>/opt/opendj</code></li> <li>Index créé sur le serveur dj2, sur l'attribut <em>company</em></li> </ul> <h3>Script d'installation</h3> <p>L'installation sur les 2 serveurs a été faite avec le script suivant :</p> <pre><code>#!/bin/sh # # Installation Forgerock OpenDJ 3.5.1 # #--------------------------------------- LDAPPORT=1389 PASS=ldapMaster REPLADM=replicationAdmin REPLPASS=replicationPassword ADMINPORT=4445 HOST1=dj1.id-num.com HOST2=dj2.id-num.com HOST3=dj3.id-num.com JAVAHOME=/opt/jre1.8.0_144 BASEDN="o=example" BASEDIR=/opt/opendj BINDIR=${BASESDIR}/bin export JAVA_HOME=${JAVAHOME} export OPENDJ_JAVA_HOME=${JAVAHOME} ${BASEDIR}/setup \ --cli \ --baseDN ${BASEDN} \ --addBaseEntry \ --ldapPort ${LDAPPORT} \ --adminConnectorPort ${ADMINPORT} \ --rootUserDN cn=Directory\ Manager \ --rootUserPassword ${PASS} \ --acceptLicense \ --no-prompt \ --noPropertiesFile </code></pre><h3>Script de réplication</h3> <p>La réplication est mise en place entre les serveurs <strong>dj1</strong> et <strong>dj2</strong>, via la commande :</p> <pre><code>${BINDIR}/dsreplication enable \ --host1 ${HOST1} --port1 ${ADMINPORT} \ --bindDN1 "cn=Directory Manager" \ --bindPassword1 ${PASS} \ --replicationPort1 8989 \ --host2 ${HOST2} --port2 ${ADMINPORT} \ --bindDN2 "cn=Directory Manager" \ --bindPassword2 ${PASS} \ --replicationPort2 8989 \ --adminUID ${REPLADM} \ --adminPassword ${REPLPASS} \ --baseDN ${BASEDN} \ --trustAll \ --no-prompt </code></pre><p>On peut ensuite lancer l'init, pour tous les serveurs de la topologie :</p> <pre><code>${BINDIR}/dsreplication \ initialize-all \ --adminUID ${REPLADM} \ --adminPassword ${REPLPASS} \ --baseDN ${BASEDN} \ --hostname $(hostname) \ --port ${ADMINPORT} \ --trustAll \ --no-prompt </code></pre><p>On vérifie, avec l'option <em>status</em> :</p> <pre><code>${BINDIR}/dsreplication status \ --adminUID ${REPLADM} \ --adminPassword ${REPLPASS} \ --port ${ADMINPORT} \ --trustAll \ --no-prompt Suffix DN : Server : Entries : Replication enabled : DS ID : RS ID : RS Port (1) : M.C. (2) : A.O.M.C. (3) : Security (4) ---------------------:---------------------:---------:---------------------:-------:-------:-------------:----------:--------------:------------- cn=Directory Manager : dj2.id-num.com:4445 : : : : : : : : o=example : dj1.id-num.com:4445 : 45 : true : 14774 : 27576 : 8989 : 0 : : false o=example : dj2.id-num.com:4445 : : true : 29513 : 481 : 8989 : 0 : : false </code></pre><h3>Schéma spécifique</h3> <p>Le schéma est modifié avec l'ajout de 2 attributs et une classe d'objet :</p> <pre><code>dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( partneruid-oid NAME 'partneruid' SUP name X-ORIGIN 'user Defined' ) attributeTypes: ( company-oid NAME 'company' SUP name X-ORIGIN 'user Defined' ) - add: objectclasses objectClasses: ( partnerperson-oid NAME 'partnerPerson' SUP inetorgperson MUST ( company ) MAY ( partneruid) ) </code></pre><h3>Version OpenDJ / DS</h3> <p>On peut vérifier la version actuelle avec la commande :</p> <pre><code>/opt/opendj/bin/dsconfig --version 3.5.1 (revision 23b322a7502f029b6d3725212c162de36f038122) </code></pre><h2>Upgrade "en place"</h2> <p>Il faut tout d'abord vérifier la trajectoire de migration supportée.</p> <p>Pour <em>Directory Services 6.5</em>, sorti fin 2018, la migration est supportée depuis la version OpenDJ 2.6 et supérieure.</p> <p>La version de Java est également à vérifier : Java 8 ou 11 pour DS 6.5. Nous utilisons une version 8 ce qui convient donc.</p> <p>Forgerock recommande de faire une sauvegarde <strong>physique</strong> du serveur à <em>upgrader</em>, en arrêtant l'annuaire et en faisant un <em>backup</em> de toute l'arborescence :</p> <pre><code>/opt/opendj/bin/stop-ds tar zcf opendj-3.5.tgz opendj </code></pre><p><strong>Note</strong> : l'upgrade en place nécessite d'arrêter l'instance d'annuaire qui va être migrée.</p> <h3>Procédure de migration</h3> <p>La procédure est simple ; elle consiste essentiellement à :</p> <ul> <li>extraire l'archive de la nouvelle version au dessus de l'ancienne</li> <li>lancer la commande <strong>upgrade</strong></li> <li>vérifier et éventuellement adapter le paramétrage.</li> </ul> <p>En détail :</p> <pre><code>cd /opt unzip /path/to/Software/Forgerock/DS-6.6.0.zip Archive: DS-6.6.0.zip creating: opendj/legal-notices/third-party-licenses/ creating: opendj/template/extlib/ creating: opendj/template/setup-profiles/ .../... creating: opendj/template/setup-profiles/IDM/repo/6.5/ creating: opendj/template/setup-profiles/IDM/repo/6.5/schema/ replace opendj/snmp/mib/rfc2605.txt? [y]es, [n]o, [A]ll, [N]one, [r]ename: y </code></pre><p>Répondre "A" pour écraser / remplacer les anciennes versions de fichiers.</p> <p>Lancer ensuite l'upgrade :</p> <pre><code>/opt/opendj/upgrade &gt;&gt;&gt;&gt; OpenDJ Upgrade Utility * OpenDJ configuration will be upgraded from version 3.5.1.23b322a7502f029b6d3725212c162de36f038122 to 6.5.0.e2a029a050cc6908fd144a6ca9c687e01ad56ea3 * OpenDJ data will be upgraded from version 6.0.0 to 6.5.0.e2a029a050cc6908fd144a6ca9c687e01ad56ea3 * See '/opt/opendj/logs/upgrade.log' for a detailed log of this operation &gt;&gt;&gt;&gt; Preparing to upgrade OpenDJ 5.5.0 changed the indexing algorithm for JSON equality matching rules. All JSON based attribute indexes must be rebuilt which may take a long time. Do you want to rebuild the indexes automatically at the end of the upgrade? (yes/no) [no]: yes OpenDJ 6.5.0 changed the indexing algorithm for replication metadata. Its index must be rebuilt which may take a long time; without a working index every server start will take longer than normal. Do you want to rebuild the index automatically at the end of the upgrade? (yes/no) [no]: yes The upgrade is ready to proceed. Do you wish to continue? (yes/no) [yes]: &gt;&gt;&gt;&gt; Performing upgrade Adding configuration for schema providers........................... 100% Adding configuration entry 'dn: cn=Core Schema,cn=Schema Providers,cn=config'................................................ 100% Removing top configuration entry for matching rules................. 100% Removing configuration for syntaxes................................. 100% .../... Replacing schema file '02-config.ldif'.............................. 100% Archiving concatenated schema....................................... 100% Migrating replication changelog files to 6.5.0 format............... 100% &gt;&gt;&gt;&gt; OpenDJ configuration was successfully upgraded from version 3.5.1.23b322a7502f029b6d3725212c162de36f038122 to 6.5.0.e2a029a050cc6908fd144a6ca9c687e01ad56ea3 &gt;&gt;&gt;&gt; OpenDJ data was successfully upgraded from version 6.0.0 to 6.5.0.e2a029a050cc6908fd144a6ca9c687e01ad56ea3 &gt;&gt;&gt;&gt; Performing post upgrade tasks Rebuilding index(es) '[.caseIgnoreJsonQueryMatch, .caseExactJsonQueryMatch, ds-sync-hist.changeSequenceNumberOrderingMatch]' for base dn(s) '[o=example]'....................................................... 100% &gt;&gt;&gt;&gt; Post upgrade tasks complete </code></pre><p>Les logs de la migration se trouvent dans <code>$DSHOME/logs/upgrade.log</code>.</p> <p>On peut ensuite démarrer l'instance, via la commande <code>bin/start-ds</code></p> <p>L'annuaire est bien passé en version supérieure :</p> <pre><code>/opt/opendj/bin/dsconfig --version 6.5.0 (revision e2a029a050cc6908fd144a6ca9c687e01ad56ea3) </code></pre><h3>Post Upgrade</h3> <p>Si on part d'une version inférieure à la version 5.5, Forgerock rcommande de donner des privilèges spécifiques au compte de réplication. Les privilèges à ajouter sont les suivants :</p> <ul> <li>bypass-lockdown</li> <li>monitor-read</li> <li>server-lockdown</li> </ul> <p>Ceci peut être fait en LDIF. Dans notre cas, le compte utilisé est <em>replicationAdmin</em> :</p> <pre><code>dn: cn=replicationAdmin,cn=Administrators,cn=admin data changetype: modify add: ds-privilege-name ds-privilege-name: bypass-lockdown ds-privilege-name: monitor-read ds-privilege-name: server-lockdown </code></pre><p>La modification n'est à faire qu'une seule fois, les données étant répliquées.</p> <p>L'upgrade peut ensuite être fait pour tous les serveurs de la topologie.</p> <h2>Ajout d'un nouveau serveur dans la topologie</h2> <p>Dans cette option, on va ajouter un nouveau serveur dans la topologie de réplication. Ceci peut donc être fait sans interruption de service.</p> <h3>Installation de DS 6.5</h3> <p>L'installation ds DS 6.5 se fait quasiment de la même manière que OpenDJ 3.5. Les seules différences : pas d'option <em>--cli</em> et l'option <em>--hostname</em> qui est obligatoire.</p> <pre><code>LDAPPORT=1389 PASS=ldapMaster REPLADM=replicationAdmin REPLPASS=replicationPassword ADMINPORT=4445 HOST1=dj1.id-num.com HOST2=dj2.id-num.com HOST3=dj3.id-num.com JAVAHOME=/opt/jre1.8.0_144 BASEDN="o=example" BASEDIR=/opt/opendj BINDIR=${BASESDIR}/bin export JAVA_HOME=${JAVAHOME} export OPENDJ_JAVA_HOME=${JAVAHOME} /opt/opendj/setup \ --hostname ${HOST3} \ --baseDN ${BASEDN} \ --addBaseEntry \ --ldapPort ${LDAPPORT} \ --adminConnectorPort ${ADMINPORT} \ --rootUserDN cn=Directory\ Manager \ --rootUserPassword ${PASS} \ --acceptLicense </code></pre><p>A ce stade, on a donc un annuaire en mode "standby". Nous pouvons l'inclure dans le domaine de réplication.</p> <h3>Ajout dans la réplication</h3> <p>Forgerock recommande d'utiliser la commande <em>dsreplication</em> du nouveau serveur pour l'ajouter dans une topologie de réplication existante.</p> <p>La commande pour configurer une nouvelle réplication utilise maintenant l'option <em>configure</em> plutôt que <em>enable</em> :</p> <pre><code>${BINDIR}/dsreplication configure \ --host1 ${HOST1} --port1 4445 \ --bindDN1 "cn=Directory Manager" \ --bindPassword1 ${PASS} \ --replicationPort1 8989 \ --host2 ${HOST3} --port2 4445 \ --bindDN2 "cn=Directory Manager" \ --bindPassword2 ${PASS} \ --replicationPort2 8989 \ --adminUID ${REPLADM} \ --adminPassword ${REPLPASS} \ --baseDN ${BASEDN} \ --trustAll \ --no-prompt </code></pre><h3>Initialisation de la réplication</h3> <p>On peut maintenant lancer l'initialisation de la réplication sur un seul serveur. Avec l'option <em>initialize</em> plutôt que <em>initialize-all</em> il faut préciser les serveurs sources et destinations :</p> <pre><code>${BINDIR}/dsreplication initialize \ --adminUID ${REPLADM} \ --adminPassword ${REPLPASS} \ --baseDN ${BASEDN} \ --hostSource ${HOST1} \ --portSource ${ADMINPORT} \ --hostDestination ${HOST2} \ --portDestination ${ADMINPORT} \ --trustAll \ --no-prompt </code></pre><p>On peut ensuite vérifier :</p> <pre><code>Suffix DN : Server : Entries : Replication enabled : DS ID : RS ID : RS Port (1) : Delay (ms) : Security (2) ----------:---------------------:---------:---------------------:-------:-------:-------------:------------:------------- o=example : dj1.id-num.com:4445 : 2025 : true : 14774 : 27576 : 8989 : N/A : false o=example : dj2.id-num.com:4445 : 2025 : true : 29513 : 481 : 8989 : 0 : false o=example : dj3.id-num.com:4445 : 2025 : true : 706 : 30128 : 8989 : 0 : false </code></pre><p>Une fois que l'on a ajouté le nouveau serveur, il faut éventuellement paramétrer les éléments propres à l'instance (par exemple les index) qui sont positionnés via l'utilitaire <em>dsconfig</em>.</p> <h3>Adaptations et différences</h3> <p>On peut trouver quelques différences entre OpenDJ 3.5 et DS 6.5. A première vue, on peut citer :</p> <ul> <li>les options des commandes <em>dsconfig</em> ou <em>dsreplication</em></li> <li>les fichiers de définition du schéma qui ont migré de <code>DJ_HOME/config/schema</code> à <code>DS_HOME/db/schema</code></li> </ul> <h2>Synthèse</h2> <p>Nous avons vu que deux possibilités sont offertes pour faire un <em>upgrade</em>, de manière assez simple.</p> <p>L'upgrade "en place" est intéressant pour récupérer toute la configuration spécifique de l'instance (paramètres positionnés par l'utilitaire <strong>dsconfig</strong> et qui ne sont pas répliqués). Dans ce cas, on garde le même serveur, et donc la même version d'O.S., de java, et d'adresse IP.</p> <p>Cependant, ceci nécessite d'arrêter l'une des instances de la topologie de réplication.</p> <p>L'ajout d'une nouvelle instance peut se justifier si on veut changer de version d'O.S. et/ou limiter au maximum les interruptions de service. Cela permet aussi d'adapter les scripts aux nouvelles versions d'outils (<strong>même si l'environnement de Test est fait pour cela</strong>). Par contre, ceci implique de reprendre le paramétrage de la configuration.</p> <table> <tbody> <tr> <th>Méthode</th> <th>Avantages</th> <th>Inconvénients</th> </tr> <tr> <th>Upgrade en place</th> <td>Pas de changement d'adresse IP<br />Récupération de la configuration</td> <td>Arrêt de l'instance</td> </tr> <tr> <th>Ajout d'une nouvelle instance</th> <td>Possibilité de monter de version d'O.S.<br />Pas d'arrêt de serveur<br />Possibilité de tester les outils</td> <td>Nouveau serveur à provisionner<br />Nouvelle adresse IP à gérer<br />Pas de récupération du paramétrage spécifique</td> </tr> </tbody> </table> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span class="field field--name-created field--type-created field--label-hidden">ven 14/12/2018 - 22:06</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> </section> Fri, 14 Dec 2018 21:06:26 +0000 vincentl 197 at https://www.vincentliefooghe.net LDAP : les types de groupes https://www.vincentliefooghe.net/index.php/content/ldap-les-types-groupes <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">LDAP : les types de groupes</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Les annuaires LDAP sont principalement utilisés pour gérer 2 types d'objets :</p> <ul> <li>les comptes utilisateurs (qui vont permettre une authentification centralisée)</li> <li>des groupes d'utilisateurs (qui vont permettre une gestion de droits).</li> </ul> <p>D'autres objets annexes sont souvent ajoutés, qui ont un rôle de <em>"listes de valeurs"</em>.</p> <p>Nous allons voir dans cet article les différents types de groupes qui peuvent être utilisés, sachant que selon les RFC LDAP 4519, seuls les premiers sont vraiment standardisés.</p> <h2>Groupes statiques</h2> <p>A l'origine, les groupes statiques, définis par les classes d'objet <em>groupOfNames</em> et <em>groupOfUniqueNames</em> sont juste une liste de membres (donnés par leur DN).</p> <p>Dans un groupe de type <em>groupOfNames</em>, l'attribut utilisé est <em>member</em>, et on peut avoir plusieurs fois le même membre.</p> <p>Dans un groupe de type <em>groupOfUniqueNames</em>, l'attribut utilisé est <em>uniqueMember</em>, et on peut avoir une seule occurence pour chaque membre.</p> <p>Exemple :</p> <pre><code>dn: cn=firstGroup,ou=Groups,dc=example,dc=com objectclass: top objectclass: groupofnames member: uid=john.doe,ou=People,dc=example,dc=com cn: firstGroup </code></pre><p>On peut donc récupérer facilement tous les membres d'un groupe statique, en listant les valeurs de l'attribut <em>uniqueMember</em> ou <em>member</em>, selon le cas. De même, pour connaître les groupes affectés à un utilisateur, on utilisera une recherche du type :</p> <pre><code>ldapsearch -b "dc=example,dc=com" -s sub "(|(&amp;(objectClass=groupOfNames)(member=uid=john.doe,ou=People,dc=example,dc=com)) \ (&amp;(objectClass=groupOfUniqueNames) (uniqueMember=uid=john.doe,ou=People,dc=example,dc=com)) </code></pre><h3>Avantages</h3> <p>C'est le seul type de groupe standardisé, et qui peut donc être utilisé par la plupart des applications ou équipements. Certains équipements réseaux par exemple peuvent utiliser les groupes pour valider les habilitations.</p> <h3>Inconvénients</h3> <p>Le principal inconvénient est la maintenance de ces groupes, puisque l'ajout ou le retrait des membres se fait de manière unitaire. Par défaut il n'y a pas de contrôle de cohérence, on peut donc ajouter comme membre d'un groupe un DN inexistant ; et si on supprime un utilisateur, son DN peut encore apparaître dans la liste des membres.</p> <p><strong>Note</strong> : certains annuaires utilisent un <em>plugin</em> d'intégrité référentiel, qui permet, à la suppression de l'entrée utilisateur, d'aller supprimer le DN correspondant des membres des groupes.</p> <h2>Groupes dynamiques</h2> <p>Il n'y a pas de définition formelle de type RFC pour les groupes dynamiques. L'implémentation dépend du fournisseur d'annuaire. Sur OpenLDAP par exemple, on trouve un <em>overlay</em> <strong>dynlist</strong> qui permet d'apporter cette fonctionnalité.</p> <p>Sur les annuaires tels que Sun/Oracle DSEE, OpenDS et ses descendants (Forgerock OpenDJ, Oracle OUD, UnboundID/Ping Drectory), on utilise un groupe de type <em>groupOfUrls</em>.</p> <p>Les groupes dynamiques utilisent un attribut <em>memberURL</em> qui permet de définir une requête LDAP, de la forme ldap:///BASE_DN?ATTRIBUTS?SCOPE?FILTRE.</p> <p>Exemples de filtres :</p> <pre><code>ldap:///ou=People,dc=example,dc=com?uid,cn,sn?sub?(departmentNumber=IT) </code></pre><p>Recherche à partir de la base DN <code>ou=People,dc=example,dc=com</code>, avec un <em>scope</em> de type <code>subtree</code>, les utilisateurs qui sont dans le département IT, et récupère uniquement les attributs <em>uid, sn</em> et <em>cn</em>.</p> <p>Exemple :</p> <pre><code>dn: cn=IT-Staff,ou=Groups,dc=example,dc=com objectclass: top objectclass: groupOfURLs cn: IT-staff memberURL: ldap:///ou=People,dc=example,dc=com??sub?(departmentNumber=IT) </code></pre><h3>Avantages</h3> <p>Une fois que le filtre est défini, la gestion des membres est automatique, puisque basée sur les attributs de l'utilisateur.</p> <h3>Inconvénients</h3> <p>Par défaut, ce sont les clients qui doivent interpréter la requête LDAP présente dans l'attribut <em>memberURL</em>. On ne peut pas avoir la liste des membres rien qu'en faisant une requête sur le groupe, et on ne peut pas non plus avoir la liste des groupes d'un utilisateur en cherchant son DN dans les membres.</p> <p>Pour pallier ce problème, la plupart des annuaires qui implèmentent les groupes dynamiques gèrent aussi un attribut virtuel <strong>isMemberOf</strong>, qui contient la liste des groupes dont l'utilisateur est membre.</p> <h2>Exemples</h2> <p>Si on injecte le contenu du fichier LDIF suivant dans un annuaire :</p> <pre><code>dn: ou=staff,ou=people,dc=example,dc=com objectClass: organizationalunit objectClass: top ou: staff dn: uid=john.doe,ou=staff,ou=people,dc=example,dc=com givenName: John objectClass: person objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: top uid: john.doe cn: John Doe sn: Doe departmentNumber: Finance dn: uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com givenName: Elliot objectClass: person objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: top uid: elliot.alderson cn: Elliot Alderson sn: Alderson departmentNumber: IT dn: uid=angela.moss,ou=staff,ou=people,dc=example,dc=com givenName: Angela objectClass: person objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: top uid: angela.moss cn: Angela Moss sn: Moss departmentNumber: IT dn: ou=Groups,dc=example,dc=com objectClass: organizationalunit objectClass: top ou: Groups dn: cn=Staff,ou=Groups,dc=example,dc=com objectclass: top objectclass: groupofnames member: uid=john.doe,ou=staff,ou=people,dc=example,dc=com member: uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com member: uid=angela.moss,ou=staff,ou=people,dc=example,dc=com cn: Staff dn: cn=IT-Staff,ou=Groups,dc=example,dc=com objectclass: top objectclass: groupOfURLs cn: IT-staff memberURL: ldap:///ou=People,dc=example,dc=com??sub?(departmentNumber=IT) </code></pre><p>La recherche des groupes liés à Elliot Anderson donne le résultat suivant :</p> <pre><code>ldapsearch -b ou=groups,dc=example,dc=com member=uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com dn dn: cn=Staff,ou=Groups,dc=example,dc=com </code></pre><p>On ne trouve pas le groupe dynamique lié. Par contre, si on utilise l'attribut <em>isMemberOf</em>, on va avoir tous les groupes :</p> <pre><code>ldapsearch -b ou=people,dc=example,dc=com uid=elliot.alderson ismemberof dn: uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com ismemberof: cn=Staff,ou=Groups,dc=example,dc=com ismemberof: cn=IT-Staff,ou=Groups,dc=example,dc=com </code></pre><h2>Groupes statiques virtuels</h2> <p>Pour tenter de concilier les avantages des deux types de groupes, certains annuaires implémentent un nouveau type de groupe : le groupe Virtuel Static <em>Virtual Static Groups</em>).</p> <p>Les groupes virtuels statiques utilisent une classe d'objet spécifique, <em>ds-virtual-static-group</em>, et font référence à un groupe dynamique (qu'il faudra donc créer auparavant).</p> <p>Exemple :</p> <pre><code>dn: cn=VS-IT-staff,ou=Groups,dc=example,dc=com cn: VS-IT-staff objectclass: top objectclass: groupOfNames objectclass: ds-virtual-static-group ds-target-group-dn: cn=IT-Staff,ou=Groups,dc=example,dc=com </code></pre><p>Si on ajoute le groupe, on le récupère dans l'attribut <em>isMemberOf</em> de l'utilisateur. Par exemple ;</p> <pre><code>/opt/opendj/bin/ldapsearch -b ou=staff,ou=people,dc=example,dc=com uid=elliot.alderson ismemberof dn: uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com ismemberof: cn=Staff,ou=Groups,dc=example,dc=com ismemberof: cn=IT-Staff,ou=Groups,dc=example,dc=com ismemberof: cn=VS-IT-staff,ou=Groups,dc=example,dc=com </code></pre><p>Par contre par défaut le groupe virtuel statique ne donne pas la liste de ses membres :</p> <pre><code>ldapsearch -b ou=Groups,dc=example,dc=com cn=VS-IT-staff dn: cn=VS-IT-staff,ou=Groups,dc=example,dc=com cn: VS-IT-staff ds-target-group-dn: cn=IT-Staff,ou=Groups,dc=example,dc=com objectClass: groupOfNames objectClass: ds-virtual-static-group objectClass: top </code></pre><h3>Pour récupérer la liste des membres</h3> <p>La récupération de la liste des membres d'un groupe virtuel statique se fait à la volée, et peut donc être consommatrice de ressources, surtout sur de grosses volumétrie. La fonctionnalité est désactivée par défaut. On peut l'activer avec l'utilitaire <strong>dsconfig</strong> :</p> <pre><code>dsconfig set-virtual-attribute-prop --name "Virtual Static member" --set allow-retrieving-membership:true </code></pre><p>Si on recherche directement le groupe , on a bien la liste des membres :</p> <pre><code>ldapsearch -b ou=Groups,dc=example,dc=com cn=VS-IT-staff dn: cn=VS-IT-staff,ou=Groups,dc=example,dc=com member: uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com member: uid=angela.moss,ou=staff,ou=people,dc=example,dc=com cn: VS-IT-staff ds-target-group-dn: cn=IT-Staff,ou=Groups,dc=example,dc=com objectClass: groupOfNames objectClass: ds-virtual-static-group objectClass: top member: uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com member: uid=angela.moss,ou=staff,ou=people,dc=example,dc=com </code></pre><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Ce type de groupe peut donc être utilisé si une application cliente veur récupérer la liste des membres, à partir du nom du groupe. Par contre, si on fait une recherche sur les membres, le groupe n'apparaît pas non plus :</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> <pre style="margin: 0px; text-indent: 0px;">ldapsearch -b ou=groups,dc=example,dc=com member=uid=elliot.alderson,ou=staff,ou=people,dc=example,dc=com dn dn: cn=Staff,ou=Groups,dc=example,dc=com</pre><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Seul l'attribut <em>isMemberOf</em> contient l'ensemble des groupes affectés à la personne.</p> <style type="text/css"> <!--/*--><![CDATA[/* ><!--*/ <!--/*--><![CDATA[/* ><!--*/ p, li { white-space: pre-wrap; } /*--><!]]]]><![CDATA[>*/ /*--><!]]>*/ </style><pre><code> </code></pre></div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2018-04-30T09:20:07+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">lun 30/04/2018 - 11:20</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/ldap" hreflang="fr">ldap</a></div> <div class="field__item"><a href="/index.php/tags/ping-directory" hreflang="fr">ping directory</a></div> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Mon, 30 Apr 2018 09:20:07 +0000 vincentl 192 at https://www.vincentliefooghe.net Création de comptes Administrateurs dans OpenDJ / Ping Directory https://www.vincentliefooghe.net/index.php/content/cr%C3%A9ation-comptes-administrateurs-dans-opendj-ping-directory <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Création de comptes Administrateurs dans OpenDJ / Ping Directory</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Lorsqu'on installe un annuaire LDAP, on crée un compte (souvent "<em>cn=Directory Manager</em>" par défaut) qui a tous les privilèges, qui n'est pas soumis aux ACI, bref, un superAdmin avec tous les privilèges.</p> <p>Il vaut donc mieux éviter d'utiliser ce compte pour des opérations. On peut toujours utiliser des comptes "utilisateurs", mais dans ce cas, le DN du compte change selon le baseDN.</p> <p>Si on veut industrialiser le monitoring de l'annuaire, par exemple, il est intéressant d'avoir toujours le même compte, quel que soit l'instance et donc le baseDN.</p> <p>C'est ici qu'interviennent les Root DNs, qui sont stockés dans la configuration (le <em>cn=config</em>).</p> <ul> <li>Avantage : le DN sera le même sur tous les annuaires</li> <li>Inconvénient : le cn=config n'étant pas répliqué, il faut répéter la création sur chaque instance</li> </ul> <p>OpenDJ et Ping Directory sont des annuaires "cousins", bâtis sur les sources de OpenDS après le rachat de Sun Microsystems par Oracle. Les deux produits ont divergé au fil du temps, mais les principes restent similaires. Nous allons voir les commandes à lancer sur les 2 produits.</p> <h2>OpenDJ</h2> <p>Avec OpenDJ, il faut ajouter une entrée dans le cn=config, via un fichier LDIF et un ldapmodify :</p> <pre>cat /tmp/monitor.ldif dn: cn=LDAP Monitoring,cn=Root DNs,cn=config changetype: add objectClass: ds-cfg-root-dn-user objectClass: top objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person sn: Monitoring cn: LDAP Monitoring givenName: LDAP ds-privilege-name: config-read ds-privilege-name: metrics-read ds-privilege-name: unindexed-search ds-cfg-alternate-bind-dn: cn=ldapMonitoring userPassword: Ld@pM0n|T0R1n6 </pre><p>On intègre ensuite les données :</p> <pre>/opt/opendj/bin/ldapmodify -D "cn=Directory Manager" -w secret -f /tmp/monitor.ldif</pre><p>A ce niveau on peut se connecter avec cn=ldapMonitoring, sans devoir passer le DN complet.</p> <p>On peut par exemple récupérer les informations du <em>cn=monitor</em> :</p> <pre>ldapsearch -x -h localhost -p 1389 -D cn=ldapMonitoring -w Ld@pM0n|T0R1n6 -b cn=monitor (objectclass=ds-monitor-entry)</pre><h2>Ping Directory</h2> <p>Ping Directory a nettement enrichi l'utilitaire <em>dsconfig</em>, en ajoutant des dizaines d'option par rapport à ses prédécesseurs.</p> <p>La création d'un compte de type Root DN passe maintenant par l'utilitaire dsconfig, avec l'option create-root-dn-user.</p> <pre>/opt/ping/bin/dsconfig create-root-dn-user --bindDN "cn=Directory Manager" --bindPassword secret --user-name ldapMonitoring \ --set alternate-bind-dn:cn=ldapMonitoring --set first-name:LDAP --set inherit-default-root-privileges:false --set last-name:Monitoring \ --set 'password:Ld@pM0n|T0R1n6' --set privilege:config-read --set privilege:metrics-read --set privilege:unindexed-search --no-prompt</pre><p>Par rapport à OpenDJ, sur lequel tous les utilisateurs authentifiés peuvent accéder aux données de cn=monitor, Ping Directory ne donne pas d'accès par défaut. Il faut donc ajouter une global ACI sur cette entrée :</p> <pre>/opt/ping/bin/dsconfig set-access-control-handler-prop --bindPassword secret \ --add global-aci:'(target="ldap:///cn=monitor")(targetattr="*")(version 3.0; acl "Allow access to the monitor tree by ldapMonitoring"; allow(all) userdn="ldap:///cn=ldapMonitoring,cn=Root DNS,cn=config";)' --no-prompt</pre><p> </p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2018-04-04T08:08:30+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">mer 04/04/2018 - 10:08</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> <div class="field__item"><a href="/index.php/tags/ping-directory" hreflang="fr">ping directory</a></div> <div class="field__item"><a href="/index.php/tags/unboundid" hreflang="fr">unboundid</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Wed, 04 Apr 2018 08:08:30 +0000 vincentl 191 at https://www.vincentliefooghe.net OpenDJ : mise en place du suivi des connexions https://www.vincentliefooghe.net/index.php/content/opendj-mise-place-du-suivi-des-connexions <span class="field field--name-title field--type-string field--label-hidden">OpenDJ : mise en place du suivi des connexions</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Par défaut, il n'est pas possible de déterminer la date de dernière connexion réussie sur un annuaire LDAP (last login time). Seules les erreurs de connexion peuvent être détectées dans les politiques de mots de passe.</p> <p>Parfois cependant, il est intéressant de connaître la date de dernière connexion, afin de pouvoir supprimer - ou bloquer - des comptes inutilisés depuis plusieurs mois.</p> <p>Certains annuaire permettent de modifier les politiques de mots de passe pour tracer les connexions réussies, mais ceci a un impact sur les authentifications. En effet, à chaque authentification réussie, l'annuaire doit écrire la date de connexion sur l'objet utilisateur. On passe donc d'une suite d'opérations <em>search and bind</em> à une suite <em>search and bind and mod</em>.</p> <p>Quel est donc l'impact de ce suivi sur les performances d'un annuaire ? C'est l'objet de ce test, réalisé sur un annuaire LDAP Forgerock Opendj (DS 5.5).</p> <h2>Configuration utilisée</h2> <p>La configuration utilisée est la suivante :</p> <ul> <li>2 vCPU Intel(R) Xeon(R) CPU E5-2698 v3 @ 2.30GHz</li> <li>16 Go de RAM</li> </ul> <p>Le jeu de test est constitué d'un fichier LDIF de 481 Mo, comprenant 220 000 entrées utilisateur.</p> <p>Parmi ces 220 000 entrées, 50 000 sont situées dans une OU (<em>organizational unit</em>) spécifique : ou=People,ou=FR,o=example.</p> <h2>Politique de mots de passe par défaut</h2> <p>La politique de mot de passe par défaut est utilisée, avec le chargement des entrées.</p> <pre><code>Property : Value(s) ------------------------------------------:------------------------------------ account-status-notification-handler : - allow-expired-password-changes : false allow-multiple-password-values : false allow-pre-encoded-passwords : false allow-user-password-changes : true default-password-storage-scheme : Salted SHA-512 deprecated-password-storage-scheme : - expire-passwords-without-warning : false force-change-on-add : false force-change-on-reset : false grace-login-count : 0 idle-lockout-interval : 0 s java-class : org.opends.server.core.PasswordPolicyFactory last-login-time-attribute : - last-login-time-format : - lockout-duration : 0 s lockout-failure-count : 0 lockout-failure-expiration-interval : 0 s max-password-age : 25 w 5 d max-password-reset-age : 0 s min-password-age : 0 s password-attribute : userPassword password-change-requires-current-password : false password-expiration-warning-interval : 5 d password-generator : Random Password Generator password-history-count : 5 password-history-duration : 0 s password-validator : Length-Based Password Validator previous-last-login-time-format : - require-change-by-time : - require-secure-authentication : false require-secure-password-changes : false skip-validation-for-administrators : false state-update-failure-policy : reactive </code></pre><h2>Outils de benchmark</h2> <p>Les tests sont lancés avec les utilitaires <em>authrate</em> et <em>searchrate</em>, qui sont intégrés aux binaires de l'annuaire.</p> <p>Pour la recherche :</p> <p><style type="text/css"> <!--/*--><![CDATA[/* ><!--*/ <!--/*--><![CDATA[/* ><!--*/ p, li { white-space: pre-wrap; } /*--><!]]]]><![CDATA[>*/ /*--><!]]>*/ </style></p> <pre style="margin: 0px; text-indent: 0px;">/opt/opendj/bin/searchrate -h 10.150.29.161 -p 1389 -D 'uid=user.1,ou=people,ou=fr,o=example' -w password -F -c 10 -b o=example -m 300000 -g 'rand(100,49000)' '(uid=user.%d)'</pre><p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p> <p>Pour les authentifications, en mode search + bind :</p> <pre><code>/opt/opendj/bin/authrate -h 10.150.29.161 -p 1389 -D '%2$s' -w password -f -c 10 -b ou=people,ou=fr,o=example -s sub -m 300000 -g 'rand(100,49000)' '(uid=user.%d)' </code></pre><h2>Procédure de tests</h2> <p>La procédure de tests est la suivante :</p> <ul> <li>démarrage de l'annuaire</li> <li>lancement d'un premier test de type <em>searchrate</em>, qui permet de cacher les entrées en RAM</li> <li>lancement d'un test d'authentification avec <em>authrate</em> en mode search + bind</li> </ul> <h2>Mesures sans suivi de la date de dernière connexion</h2> <p>Avec le paramétrage par défaut, on obtient un débit moyen de 4283 authentifications par seconde, avec un temps de réponse moyen de 2.131 millisecondes.</p> <pre><code>------------------------------------------------------------------------------ Throughput Response Time (ops/second) (milliseconds) recent average recent average 99.9% 99.99% 99.999% err/sec bind time % ------------------------------------------------------------------------------ 3901.6 3907.1 2.573 2.573 25.304 162.729 167.620 0.0 44.4 4186.4 4047.8 2.372 2.469 26.546 166.949 195.819 0.0 46.6 4540.4 4212.9 2.183 2.365 23.388 166.223 195.819 0.0 44.2 4624.0 4315.7 2.147 2.307 22.435 162.729 195.819 0.0 42.6 4609.7 4374.6 2.156 2.275 22.083 160.540 172.100 0.0 43.0 4663.1 4422.7 2.130 2.250 21.634 158.399 172.100 0.0 42.5 4765.9 4471.7 2.088 2.225 21.431 154.617 172.100 0.0 42.8 4764.9 4508.4 2.089 2.207 20.982 141.395 172.100 0.0 42.0 4864.1 4547.9 2.050 2.188 21.024 39.778 169.393 0.0 42.2 4811.6 4574.2 2.077 2.177 20.934 34.832 169.393 0.0 42.0 4777.0 4592.6 2.091 2.169 20.525 32.932 169.393 0.0 41.8 4825.5 4611.9 2.072 2.160 20.090 32.724 169.393 0.0 41.9 4101.4 4572.6 1.898 2.142 19.807 32.213 169.393 0.0 41.7 530.8 4283.0 0.869 2.131 19.703 32.118 167.620 0.0 41.0 </code></pre><p>La CPU est utilisée à 90 % environ sur le serveur cible (qui dispose de 2 vCPU).</p> <h2>Mise en place du suivi du <em>last login time</em></h2> <h3>Création d'un attribut spécifique</h3> <p>La mise en place du suivi demande tout d'abord de créer un attribut qui sera utilisé pour stocker la date de dernière connexion. La documentation donne justement un exemple de politique de mots de passe qui met en oeuvre le suivi.</p> <pre><code>dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( lastLoginTime-oid NAME 'lastLoginTime' DESC 'Last time the user logged in' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'OpenDJ example documentation' ) </code></pre><p>On ajoute l'attribut au schéma via la commande <em>ldapmodify</em> :</p> <pre><code>ldapmodify \ --hostname localhost \ --port 1389 \ --bindDN "cn=Directory Manager" \ --bindPassword password \ lastLoginTime.ldif </code></pre><h3>Création d'une politique de mots de passe spécifique</h3> <p>Si on veut cibler certains comptes utilisateurs, on peut créer une politique de mots de passe spécifiquement pour cet usage :</p> <pre><code>/opt/opendj/bin/dsconfig \ create-password-policy \ --hostname localhost --port 4444 \ --bindDN "cn=Directory Manager" \ --bindPassword password \ --policy-name "Track Last Login Time" \ --type password-policy \ --set default-password-storage-scheme:"Salted SHA-512" \ --set password-attribute:userPassword \ --set last-login-time-attribute:lastLoginTime \ --set last-login-time-format:"yyyyMMddHH'Z'" \ --trustAll \ --no-prompt </code></pre><h3>Modification de la politique de mots de passe</h3> <p>On peut créer une nouvelle politique de mots de passe, ou modifier la politique existante. Dans ce cas, la commande à utiliser est la suivante :</p> <pre><code>/opt/opendj/bin/dsconfig set-password-policy-prop \ --policy-name Default\ Password\ Policy \ --set last-login-time-attribute:lastLoginTime \ --set last-login-time-format:"yyyyMMddHH'Z'" \ --hostname localhost \ --port 4444 \ --bindDn cn=Directory\ Manager \ --bindPassword password \ --trustAll \ --no-prompt </code></pre><h2>Test sur une entrée</h2> <p>Si on fait une requête avec un utilisateur en se connectant, on peut ensuite récupérer la date de dernière connexion sur son entrée, à condition de disposer des droits adéquats.</p> <p>Par exemple :</p> <pre><code>ldapsearch -x -h localhost -p 1389 -D 'cn=Directory Manager' -w password -b o=example '(uid=user.2)' lastLoginTime dn: uid=user.2,ou=People,ou=FR,o=example lastLoginTime: 2017121909Z </code></pre><p>On constate que la date est bien au format déclaré, c'est à dire comprenant l'année, le mois, le jour et l'heure. En effet, il n'est pas nécessaire de suivre les connexions à la minute près.</p> <h2>Mesures AVEC suivi de la date de dernière connexion</h2> <p>Avec le nouveau paramétrage, incluant la mise à jour de la dernière date de connexion, on obtient un débit maximum de 2860 authentifications par seconde en moyenne, avec un temps de réponse moyen de 3.382 millisecondes.</p> <p>La charge CPU sur le serveur d'annuaire oscille entre 50 et 95%, avec des I/O wait.</p> <p>On a bien un impact assez fort, avec notamment des phases pendant laquelle l'annuaire est en I/O wait, révélateur des mises à jour effectuées sur les entrées.</p> <pre><code>------------------------------------------------------------------------------ Throughput Response Time (ops/second) (milliseconds) recent average recent average 99.9% 99.99% 99.999% err/sec bind time % ------------------------------------------------------------------------------ 1570.3 1573.1 6.421 6.421 152.833 177.026 177.026 0.0 63.6 2308.4 1942.2 4.325 5.170 53.701 176.974 177.026 0.0 57.0 2479.4 2122.0 4.023 4.722 49.889 165.267 177.026 0.0 53.3 1025.2 1847.4 3.712 4.581 48.670 165.267 177.026 0.0 51.6 0.0 1477.0 - 4.581 48.670 165.267 177.026 0.0 NaN 1013.4 1399.8 25.871 7.149 50.589 11195.648 11204.023 0.0 93.5 2996.8 1627.5 3.332 6.147 46.142 11193.992 11204.023 0.0 49.8 3301.1 1836.1 3.028 5.447 44.262 11187.622 11204.023 0.0 48.4 3329.9 2001.8 2.737 4.948 41.735 11165.580 11204.023 0.0 47.0 0.0 1800.9 - 4.948 41.735 11165.580 11204.023 0.0 NaN 92.4 1645.4 226.166 6.078 43.042 11156.315 11204.023 0.0 99.2 4024.9 1843.1 2.485 5.426 39.488 10339.090 11203.705 0.0 45.4 4193.7 2023.6 2.382 4.942 38.478 10328.566 11203.705 0.0 44.3 4487.2 2199.3 2.227 4.547 36.814 10316.059 11203.705 0.0 43.1 4496.0 2352.3 2.222 4.251 35.540 10313.618 11203.705 0.0 43.3 4530.5 2488.3 2.207 4.018 34.530 10213.330 11203.705 0.0 43.0 4535.5 2608.8 2.204 3.833 33.649 168.792 11202.112 0.0 43.3 4479.8 2712.7 2.230 3.686 33.112 163.941 11202.112 0.0 42.7 4722.0 2818.5 2.116 3.547 32.285 160.038 11202.112 0.0 42.6 4710.9 2913.1 2.108 3.431 31.666 79.285 11202.112 0.0 42.5 1816.5 2860.5 1.834 3.382 31.418 75.221 11195.866 0.0 42.9 </code></pre><p><em>Note</em> : ceci est cependant à modérer, puisque notre première campagne de tir va déclencher une écriture pour chaque utilisateur qui s'authentifie. Si on relance un deuxième tir dans l'heure (qui est l'unité minimale de suivi de la date de connexion), on retrouve des résultats quasiment identiques au premier cas : un débit de 4291 authentifications par seconde, et un temps de réponse de 2.195 ms. Si on regarde la charge sur le serveur d'annuaire, on ne constate plus d'écritures sur disque.</p> <pre><code>------------------------------------------------------------------------------ Throughput Response Time (ops/second) (milliseconds) recent average recent average 99.9% 99.99% 99.999% err/sec bind time % ------------------------------------------------------------------------------ 3988.3 3994.8 2.514 2.514 23.066 163.522 167.640 0.0 42.6 .../... 4628.0 4525.7 2.159 2.206 18.978 28.433 158.819 0.0 42.9 4327.2 4510.4 2.219 2.207 19.051 28.221 158.819 0.0 43.0 1450.9 4291.0 1.721 2.195 18.968 28.071 158.406 0.0 42.1 </code></pre><h2>Conclusion</h2> <p>Si l'impact du suivi de la date de dernière connexion n'est pas anodin, surtout dans le cas d'un test, en situation réelle, l'impact peut être relativement négligeable, notamment si les authentifications se font au fil de l'eau.</p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span class="field field--name-created field--type-created field--label-hidden">mar 19/12/2017 - 10:42</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> <div class="field__item"><a href="/index.php/tags/ldap" hreflang="fr">ldap</a></div> <div class="field__item"><a href="/index.php/tags/performances" hreflang="fr">performances</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> </section> Tue, 19 Dec 2017 09:42:42 +0000 vincentl 187 at https://www.vincentliefooghe.net OpenDS / OpenDJ - Problème de recherche "Unindexed search" https://www.vincentliefooghe.net/index.php/content/opends-opendj-probl%C3%A8me-recherche-unindexed-search <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">OpenDS / OpenDJ - Problème de recherche &quot;Unindexed search&quot;</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Suite à l'installation d'une instance OpenDS 2.3 sur une pré-production, sur RHEL 7 et java 1.6, un utilisateur se plaignait de ne plus pouvoir faire fonctionner son application.</p> <p>Lorsqu'il lançait sa recherche, il n'avait aucun résultat, mais un message d'erreur :</p> <pre>SEARCH operation failed Result Code: 50 (Insufficient Access Rights) Additional Information: You do not have sufficient privileges to perform an unindexed search </pre><p>La résolution du problème a pris quelques heures, le temps d'écumer le guide d'administration (plutôt complet) et les différents sites internet (dont celui de <a href="https://ludopoitou.com">Ludovic Poitou</a>, toujours très utile).</p> <p>La requête de base est la suivante :</p> <ul> <li>Scope : wholeSubTree</li> <li>Base ou=site,ou=p1,ou=repository,o=rootSuffix</li> <li>Filter : (id=*).</li> </ul> <p>Sachant qu'il y a 9400 objets dans l'ou=site, et que l'attribut <em>id</em> est le RDN de l'objet, tous les objets ont donc un id.</p> <h2>Debug de l'utilisation des requêtes</h2> <p>Le blog de Ludovic Poitou comprenait un article qui parlait des indexes dans OpenDJ (très compatible avec OpenDS), et notamment un attribut opérationnel <em>debugsearchindex</em> qui permet d'avoir les comportement de l'annuaire par rapport aux index.</p> <p>Exemple :</p> <pre>ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=*)' debugsearchindex dn: cn=debugsearch debugsearchindex: filter=(id=*)[NOT-INDEXED] scope=singleLevel[LIMIT-EXCEEDED:94 17] final=[NOT-INDEXED]</pre><p>L'attribut n'est pas indexé. On va donc ajouter un index, de type substring.</p> <h2>Création d'un index</h2> <pre>dsconfig create-local-db-index --port 4444 --hostname localhost --bindDN "cn=Directory Manager" \ --bindPassword password --backend-name userRoot \ --index-name id --set index-type:substring \ --trustAll --no-prompt</pre><p>Puis on lance le <em>rebuild-index</em></p> <pre>rebuild-index --port 4444 -h localhost -D "cn=directory manager" -w password --baseDN o=rootSuffix --index id --start 0 --trustAll </pre><p>A ce stade, si on lance la même requête, on a toujours le même souci.</p> <p>Par contre, avec un sous-ensemble, ça fonctionne :</p> <pre>ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=ne*)' debugsearchindex dn: cn=debugsearch debugsearchindex: filter=(id=ne*)[INDEX:id.substring][COUNT:76] scope=singleLeve l[LIMIT-EXCEEDED:9417] final=[COUNT:76]</pre><p><strong>Note</strong> : la recherche en (id=*) nécessite un index de type présence. Il faut donc créer un index de type substring ET presence.</p> <p>Après avoir faire la création et le rebuilt, on peut vérifier les index :</p> <pre>bin/dbtest list-index-status -b "o=rootSuffix" -n userRoot Index Name Index Type JE Database Name Index Status ---------------------------------------------------------------------------------------- id2children Index o_rootSuffix_id2children true id2subtree Index o_rootSuffix_id2subtree true uid.equality Index o_rootSuffix_uid.equality true id.presence Index o_rootSuffix_id.presence true id.substring Index o_rootSuffix_id.substring true </pre><p>Cependant, la recherche sur id=* ne fonctionne toujours pas avec un compte "normal"</p> <pre>bin/ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=*)' debugsearchindex dn: cn=debugsearch debugsearchindex: filter=(id=*)[INDEX:id.presence][LIMIT-EXCEEDED] scope=singleL evel[LIMIT-EXCEEDED:9417] final=[LIMIT-EXCEEDED:9417]</pre><h2>Changement de la limitation sur les index</h2> <p>Il faut alors jouer avec la propriété  <em>index-entry-limit</em>, qui spécifie le nombre maximum des entrées garder dans un index. Dans notre cas, sachant qu'on a actuellement 9400 entrées de type site, et d'autres objets qui ont également un attribut id, on va fixer la valeur à 12 000.</p> <pre>bin/dsconfig set-local-db-index-prop --port 4444 --hostname localhost --bindDN "cn=Directory Manager" \ --bindPassword password --backend-name userRoot \ --trustAll --no-prompt \ --index-name id \ --set index-entry-limit:12000</pre><p><br />Après avoir lancé le <em>rebuild</em>,</p> <pre>bin/ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=*)' debugsearchindex dn: cn=debugsearch debugsearchindex: filter=(id=*)[INDEX:id.presence][COUNT:10084] scope=singleLeve l[LIMIT-EXCEEDED:9417] final=[COUNT:10084] </pre><p> </p> <p>A ce niveau, la recherche fonctionne, mais on se heurte à une autre limite :</p> <pre>SEARCH operation failed Result Code: 4 (Size Limit Exceeded) Additional Information: This search operation has sent the maximum of 1000 entries to the client</pre><h2>Modification des limites du compte</h2> <p>Par défaut, on a des limites sur le nombre de résultats retournés :</p> <ul> <li>ds-rlim-lookthrough-limit : 5000</li> <li>ds-rlim-size-limit : 1000</li> </ul> <p>Il faut donc modifier ces valeurs. Par exemple via un fichier LDIF :</p> <pre>dn: cn=VliPre, ou=account, ou=security, o=rooutSuffix changetype:modify add: ds-rlim-size-limit ds-rlim-size-limit: 15000 - add: ds-rlim-lookthrough-limit ds-rlim-lookthrough-limit: 15000 </pre><p><br />Après toutes ces modifications, le compte peut bien récupérer toutes les entrées.</p> <p>Par contre, on peut se poser la question sur l'intérêt de récupérer des milliers d'entrées.</p> <h2>Désactivation globale du privilège</h2> <p>En derner recours, il est possible de désactiver globalement le privilège <em>unindexed-search</em>, en passant par <em>ds-config</em>.</p> <p>On peut voir configuration en cours :</p> <pre>/opt/OpenDS-2.3.0/bin/dsconfig get-global-configuration-prop \ --port 4444 --hostname localhost --trustAll --bindDN "cn=Directory Manager" --bindPassword password --no-prompt Property : Value(s) --------------------------------------:------------------------ bind-with-dn-requires-password : true default-password-policy : Default Password Policy disabled-privilege : - entry-cache-preload : false etime-resolution : milliseconds idle-time-limit : 0 ms lookthrough-limit : 5000 max-allowed-client-connections : 0 proxied-authorization-identity-mapper : Exact Match reject-unauthenticated-requests : false return-bind-error-messages : false save-config-on-successful-startup : true size-limit : 1000 smtp-server : - time-limit : 1 m workflow-configuration-mode : auto writability-mode : enabled</pre><p><br />Il est possible de modifier la valeur avec ds-config :</p> <pre>/opt/OpenDS-2.3.0/bin/dsconfig set-global-configuration-prop \ --port 4444 --hostname localhost --trustAll --bindDN "cn=Directory Manager" --bindPassword password --no-prompt \ --set disabled-privilege:unindexed-search </pre><p><br />Ceci supprimer les avertissements et erreurs, au détriment des performances, puisque le paramétrage autorise n'importe qui à faire des recherches non indexées.</p> <p>On peut voir la nouvelle configuration :</p> <pre>/opt/OpenDS-2.3.0/bin/dsconfig get-global-configuration-prop \ --port 4444 --hostname localhost --trustAll --bindDN "cn=Directory Manager" --bindPassword password --no-prompt Property : Value(s) --------------------------------------:------------------------ bind-with-dn-requires-password : true default-password-policy : Default Password Policy disabled-privilege : <strong>unindexed-search</strong> entry-cache-preload : false etime-resolution : milliseconds idle-time-limit : 0 ms</pre><p><br /> </p> <p> </p> <p> </p> <p> </p> <p><br /> </p> <p> </p> <p> </p> <p> </p> <p> </p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2017-08-21T15:46:07+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">lun 21/08/2017 - 17:46</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> <div class="field__item"><a href="/index.php/tags/index" hreflang="fr">index</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Mon, 21 Aug 2017 15:46:07 +0000 vincentl 180 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/opends-opendj-probl%C3%A8me-recherche-unindexed-search#comments OpenDJ : personnalisation du schéma https://www.vincentliefooghe.net/index.php/content/opendj-personnalisation-du-sch%C3%A9ma <span class="field field--name-title field--type-string field--label-hidden">OpenDJ : personnalisation du schéma</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Il est d'usage courant de personnaliser le schéma de données, en ajoutant des attributs et des classes d'objets spécifiques au client.</p> <p>OpenDJ permet bien évidemment de définir son propre schéma de données. La déclaration des attributs et classes d'objets est faite dans différents fichiers LDIF, chargés au démarrage de l'instance, et qui se trouvent dans <code>$DJHOME/config/schema</code>.<br />Par défaut, après l'installation, on y trouve une quinzaine de fichiers:</p> <pre>cd $DJHOME ls config/schema/ 00-core.ldif 03-changelog.ldif 03-rfc2739.ldif 03-rfc3712.ldif 05-rfc4876.ldif 06-compat.ldif 01-pwpolicy.ldif 03-rfc2713.ldif 03-rfc2926.ldif 03-uddiv3.ldif 05-samba.ldif 02-config.ldif 03-rfc2714.ldif 03-rfc3112.ldif 04-rfc2307bis.ldif 05-solaris.ldif </pre><p>Les classes d'objets usuelles (organizationalUnit, inetOrgPerson, groupOfNames, etc.) sont définies dans le fichier 00-core.ldif.</p> <p>Pour ajouter des attributs ou classes d'objets spécifiques, on dispose de plusieurs options :</p> <ul> <li>Ajouter un fichier <code>99-user.ldif</code> dans le répertoire <code>config/schema</code></li> <li>Utiliser <em>ldapmodify</em> pour ajouter le contenu d'un fichier ldif</li> <li>Utiliser la console</li> </ul> <p>Imaginons que nous voulions ajouter une classe auxiliaire <em>customPerson</em>, qui contiendra les attributs :</p> <ul> <li>customAccesWeb : flag utilisé par un proxy pour donner ou non l'accès Web. Mono valeur</li> <li>customStartDate : date de début de contrat</li> <li>customEndDate : date de fin de contrat</li> <li>customManagerID : ID / matricule du manager</li> </ul> <h2>Modification via le fichier 99-user.ldif</h2> <p>Cette modification doit se faire lorsque l'annuaire est arrêté, puisque les fichiers sont chargés au démarrage de l'instance.<br />On va créer un fichier <code>$DJHOME/config/schema/99-user.ldif</code>, qui contient :</p> <pre>dn: cn=schema objectClass: top objectClass: ldapSubentry objectClass: subschema cn: schema attributeTypes: ( customStartDate-oid NAME 'customStartDate' DESC 'Date de debut de contrat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) attributeTypes: ( customManagerID-oid NAME 'customManagerID' DESC 'ID du manager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) attributeTypes: ( customAccesWeb-oid NAME 'customAccesWeb' DESC 'Acces Web via Proxy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) attributeTypes: ( customEndDate-oid NAME 'customEndDate' DESC 'Date de fin de contrat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) objectClasses: ( customPerson-oid NAME 'customPerson' DESC 'Person custom' SUP top AUXILIARY MAY ( customAccesWeb $ customStartDate $ customEndDate $ customManagerID) X-ORIGIN 'user defined' ) </pre><p>Une fois l'instance OpenDJ démarrée, on peut vérifier que la nouvelle classe d'objet est créée, en interrogeant la base <em>cn=schema</em> :</p> <pre>$DJHOME/bin/ldapsearch -D "cn=Directory Manager" -w secret -h localhost -p 1389 -b cn=schema -s base "objectclass=ldapSubentry" objectclasses </pre><p><strong>Note</strong> : la commande ci-dessus récupère toutes les classes d'objet. Il n'est pas possible de filtrer directement sur la classe qui nous intéresse.</p> <h2>Modification via ldapmodify</h2> <p>Avec cette option, on va créer un fichier LDIF, qui contient des instructions de modification du schéma. Par exemple :</p> <pre>dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( customAccesWeb-oid NAME 'customAccesWeb' DESC 'Acces Web via Proxy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( customStartDate-oid NAME 'customStartDate' DESC 'Date de debut de contrat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( customEndDate-oid NAME 'customEndDate' DESC 'Date de fin de contrat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( customManagerID-oid NAME 'customManagerID' DESC 'ID du manager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: objectClasses objectClasses: ( customPerson-oid NAME 'customPerson' DESC 'Person custom' SUP top AUXILIARY MAY ( customAccesWeb $ customStartDate $ customEndDate $ customManagerID) X-ORIGIN 'user defined' ) </pre><p><strong>Note</strong> : on utilise ici des OID alphabétiques (tel que customPerson-oid). Si on veut utiliser des "vrais" OID, on peut les déclarer sur le site de l'IANA (<a href="http://www.iana.org/assignments/enterprise-numbers/enterprise-numbers">http://www.iana.org/assignments/enterprise-numbers/enterprise-numbers</a>), ou utiliser une plage d'adresse propre, afin d'avoir des OID plus structurés. La tranche <em>1.3.6.1.4.1</em> est réservée aux codes privés pour les entreprises. On peut ensuite décliner les numéros par typologie. Par exemple :</p> <ul> <li>1.3.6.1.4.36733 : Forgerock</li> <li>1.3.6.1.4.XXXX : Société XX</li> <li>1.3.6.1.4.XXXX.1 : Schéma LDAP Société XX</li> <li>1.3.6.1.4.XXXX.1.1 : Attributs du schéma LDAP Société XX</li> <li>1.3.6.1.4.XXXX.1.2 : Classes d'objets du schéma LDAP Société XX</li> </ul> <p>Dans ce schéma de numérotation, on aurait donc</p> <pre>dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( 1.3.6.1.4.XXXX.1.1.1 NAME 'customAccesWeb' DESC 'Acces Web via Proxy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( 1.3.6.1.4.XXXX.1.1.2 NAME 'customStartDate' DESC 'Date de debut de contrat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: objectClasses objectClasses: ( 1.3.6.1.4.XXXX.1.2.1 NAME 'customPerson' DESC 'Person custom' SUP top AUXILIARY MAY ( customAccesWeb $ customStartDate $ customEndDate $ customManagerID) X-ORIGIN 'user defined' ) </pre><p>La modification du schéma se fait ensuite via une commande <em>ldapmodify</em> :</p> <pre>$DJHOME/bin/ldapmodify -h {host} -p {port} -D {bindDN} -w {password} -f {path to ldif} </pre><p>Par exemple :</p> <pre>bin/ldapmodify -f ldif/customPerson.ldif -D "cn=Directory Manager" -w secret -h localhost -p 1389 -c </pre><p>On utilise ici le port LDAP (1389 dans notre exemple) car il s'agit bien d'opérations LDAP et pas d'une opération de configuration de OpenDJ.</p> <p>On peut vérifier dans le répertoire <code>$DJHOME/config/schema</code> qu'il existe maintenant un fichier <code>99-user.ldif</code> :</p> <pre>cat $DJHOME/config/schema/99-user.ldif dn: cn=schema objectClass: top objectClass: ldapSubentry objectClass: subschema cn: schema attributeTypes: ( customStartDate-oid NAME 'customStartDate' DESC 'Date de debut de contrat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) attributeTypes: ( customManagerID-oid NAME 'customManagerID' DESC 'ID du manager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) attributeTypes: ( customAccesWeb-oid NAME 'customAccesWeb' DESC 'Acces Web via Proxy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) attributeTypes: ( customEndDate-oid NAME 'customEndDate' DESC 'Date de fin de contrat' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) objectClasses: ( customPerson-oid NAME 'customPerson' DESC 'Person custom' SUP top AUXILIARY MAY ( customAccesWeb $ customStartDate $ customEndDate $ customManagerID) X-ORIGIN 'user defined' ) modifiersName: cn=Directory Manager,cn=Root DNs,cn=config modifyTimestamp: 20150702081653Z </pre><h2>Modification par la console</h2> <p>Avec OpenDJ, on peut bien évidemment utiliser la console d'administration pour réaliser ces modifications.</p> <p>Une fois connecté, choisir Schéma / Gérer le schéma :</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_011.png" title="Forgerock_011.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_011.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_011.png?itok=IVQ_tm9g" width="466" height="480" alt="Forgerock_011.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p>On peut alors choisir de gérer les attributs ou les classes d'objets. On peut créer un nouvel attribut ou une nouvelle classe d'objet avec un clic droit :</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_013.png" title="Forgerock_013.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_013.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_013.png?itok=YyLglBf8" width="480" height="315" alt="Forgerock_013.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p>La fenêtre de saisie permet de rentrer les informations de base : nom de l'attribut, OID, description et type. Mais elle présente également d'autres options : type (mono / Multi-valué), attribut parent, alias, fichier de définition, Matching Rules.</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_015.png" title="Forgerock_015.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_015.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_015.png?itok=9sflF5nK" width="401" height="480" alt="Forgerock_015.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p>Cerise sur le gateau : lorsque l'on confirme, la console affiche l'équivalent de la commande utilisée en ligne de commande :</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_016.png" title="Forgerock_016.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_016.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_016.png?itok=k8OkUOko" width="480" height="362" alt="Forgerock_016.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p>L'ajout d'une classe d'objet se faire de la même manière. Ici aussi le formulaire permet de saisie quelques options, telles que le fichier de configuration ou le type de classe d'objet (structurelle / auxiliaire). On peut choisir quels sont les attributs portés par la classe d'objet.</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_018.png" title="Forgerock_018.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_018.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_018.png?itok=T8RYDc5v" width="363" height="480" alt="Forgerock_018.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p>Au final, on a un nouvel attribut et une nouvelle classe d'objet :</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_019.png" title="Forgerock_019.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_019.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_019.png?itok=wOFjqRs7" width="480" height="336" alt="Forgerock_019.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <h2>Références</h2> <p>Guide d'administration OpenDJ / Forgerock : <a href="https://backstage.forgerock.com/#!/docs/opendj/2.6.0/admin-guide#chap-schema">https://backstage.forgerock.com/#!/docs/opendj/2.6.0/admin-guide#chap-s…</a></p> <p> </p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span class="field field--name-created field--type-created field--label-hidden">mar 18/08/2015 - 14:03</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> </section> Tue, 18 Aug 2015 12:03:24 +0000 vincentl 137 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/opendj-personnalisation-du-sch%C3%A9ma#comments OpenDJ : ajout d'un Root Suffix https://www.vincentliefooghe.net/index.php/content/opendj-ajout-dun-root-suffix <span class="field field--name-title field--type-string field--label-hidden">OpenDJ : ajout d&#039;un Root Suffix</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>L'ajout d'un <em>Root Suffix</em> (racine d'un arbre LDAP) peut se faire via la console graphique, mais aussi en ligne de commande.</p> <p>On peut vouloir ajouter un <em>backend</em> spécifique, ce qui permettra de gérer la réplication différemment pour ce suffixe, ou ajouter le suffixe dans un <em>backend</em> existant.</p> <h2>En ligne de commande</h2> <p>On va utiliser la commande <em>dsconfig</em>, qui gère la configuration de l'annuaire.</p> <h3>Avec ajout d'un nouveau backend</h3> <pre>/opt/opendj/bin/dsconfig create-backend --backend-name hebinweb --type local-db --hostName opendj \ --port 4444 --set base-dn:"o=hebinweb" --set enabled:true \ --bindDN "cn=Directory Manager" --bindPassword secret --noPropertiesFile --trustAll --no-prompt </pre><h3>Ajout à un backend existant</h3> <pre>/opt/opendj/bin/dsconfig set-backend-prop --backend-name userRoot --add base-dn:o=hebinweb \ --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword secret \ --trustAll --noPropertiesFile --no-prompt </pre><h2>Via la console graphique</h2> <p>OpenDJ fournit une console graphique (<em>control panel</em>) qui permet de se connecter à différentes instances OpenDJ, locales ou distantes.</p> <p>On peut donc réaliser la même opération via la console. Une fois connecté, on sélectionne "Nouveau DN de base..." :</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_001.png" title="Forgerock_001.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_001.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_001.png?itok=GY0zqzVG" width="480" height="347" alt="Forgerock_001.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p>Dans l'écran suivant, on peut alors choisir l'un des backends existant ou en créer un nouveau :</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_002.png" title="Forgerock_002.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_002.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_002.png?itok=3AvNAjI2" width="480" height="331" alt="Forgerock_002.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_003.png" title="Forgerock_003.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_003.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_003.png?itok=7PLlv0y6" width="480" height="338" alt="Forgerock_003.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p> </p> <p>On arrive ensuite à l'écran de synthèse / confirmation de la création du nouveau DN de base.</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_004.png" title="Forgerock_004.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_004.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_004.png?itok=HY_5cddZ" width="480" height="265" alt="Forgerock_004.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p> </p> <p>Et dans l'écran principal, on peut voir la liste  des DN de base et de leur backend.</p> <p><article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/Forgerock_005.png" title="Forgerock_005.png" data-colorbox-gallery="gallery-all-fH2gXU61UUo" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Forgerock_005.png&quot;}"><img src="/sites/default/files/styles/large/public/Forgerock_005.png?itok=DipUgdjH" width="480" height="468" alt="Forgerock_005.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> </p> <p>On pourra ensuite charger les entrées dans l'annuaire, sur ces différents Root Suffix / Base DN.</p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span class="field field--name-created field--type-created field--label-hidden">ven 26/06/2015 - 17:56</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> </section> Fri, 26 Jun 2015 15:56:25 +0000 vincentl 136 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/opendj-ajout-dun-root-suffix#comments Installation OpenDJ https://www.vincentliefooghe.net/index.php/content/installation-opendj <span class="field field--name-title field--type-string field--label-hidden">Installation OpenDJ</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>L'annuaire LDAP <a href="http://forgerock.com/products/open-identity-stack/opendj/">OpenDJ</a> est développé par <a href="http://forgerock.com/">Forgerock</a>, sur la base de l'annuaire OpenDS, développé en son temps par Sun. On peut le télécharger sur <a hef="https://backstage.forgerock.com/#!/downloads/OpenDJ">le site de Forgerock</a>. Il est disponible sous plusieurs formats :</p> <ul> <li>Paquet .deb pour O.S. type Debian</li> <li>Paquet .rpm pour O.S. type Red Hat</li> <li>Fichier zip pour tous les O.S.</li> </ul> <p>Sur cette page, on trouve également des choses intéressantes :</p> <ul> <li>Une passerelle DSML / LDAP (fichier war à installer dans un serveur d'application Java tel que Tomcat)</li> <li>Une passerelle REST / LDAP (fichier war à installer dans un serveur d'application Java tel que Tomcat)</li> <li>Un <em>Toolkit</em> qui comprend différents outils, tels que des programmes de test de charge (lecture, authentification, etc), utilisables avec les annuaires LDAP</li> <li>Une documentation assez complète sur l'annuaire (guide d'installation, d'administration, etc.)</li> </ul> <h2>Installation en mode ligne de commande</h2> <p>Sur un serveur, il est rare d'avoir accès à une interface graphique. Lorsqu'on lance le setup, le programme détecte la présence d'une IHM, et l'installateur passe en mode texte s'il n'y en a pas de disponible.</p> <p>Après avoir accepté les termes de la licence, il faut saisir le DN du compte d'administration de l'annuaire (<em>cn=Directory Manager</em> par défaut), puis son mot de passe. On peut également créer le DN de base (ou Root Suffix) pour cette instance d'annuaire. L'installation propose également d'alimenter l'annuaire avec des données, soit un fichier LDIF existant, soit des données générées, ce qui peut être intéressant si on veut faire des tests.<br />Notez que si vous faites l'installation dans un compte utilisateur, les ports utilisés normalement en LDAP (389 et 636) sont <em>translatés</em> en 1389 et 1636.</p> <pre>Please read the License Agreement above. You must accept the terms of the agreement before continuing with the installation. Accept the license (Yes/No) [No]:Yes What would you like to use as the initial root user DN for the Directory Server? [cn=Directory Manager]: Please provide the password to use for the initial root user: Please re-enter the password for confirmation: Provide the fully-qualified directory server host name that will be used when generating self-signed certificates for LDAP SSL/StartTLS, the administration connector, and replication [opendj]: opendj.lxc.local On which port would you like the Directory Server to accept connections from LDAP clients? [1389]: 1389 On which port would you like the Administration Connector to accept connections? [4444]: Do you want to create base DNs in the server? (yes / no) [yes]: yes Provide the base DN for the directory data: o=opendj-lxc Options for populating the database: 1) Only create the base entry 2) Leave the database empty 3) Import data from an LDIF file 4) Load automatically-generated sample data Enter choice [1]: 4 Please specify the number of user entries to generate: [2000]: Do you want to enable SSL? (yes / no) [no]: yes On which port would you like the Directory Server to accept connections from LDAPS clients? [1636]: Do you want to enable Start TLS? (yes / no) [no]: yes Certificate server options: 1) Generate self-signed certificate (recommended for testing purposes only) 2) Use an existing certificate located on a Java Key Store (JKS) 3) Use an existing certificate located on a JCEKS key store 4) Use an existing certificate located on a PKCS#12 key store 5) Use an existing certificate on a PKCS#11 token Enter choice [1]: 1 Do you want to start the server when the configuration is completed? (yes / no) [yes]: Setup Summary ============= LDAP Listener Port: 1389 Administration Connector Port: 4444 LDAP Secure Access: Enable StartTLS Enable SSL on LDAP Port 1636 Create a new Self-Signed Certificate Root User DN: cn=Directory Manager Directory Data: Create New Base DN o=opendj-lxc. Base DN Data: Import Automatically-Generated Data (2000 Entries) Start Server when the configuration is completed What would you like to do? 1) Set up the server with the parameters above 2) Provide the setup parameters again 3) Print equivalent non-interactive command-line 4) Cancel and exit Enter choice [1]: 3 Equivalent non-interactive command-line to setup server: /opt/opendj/setup \ --cli \ --baseDN o=opendj-lxc \ --sampleData 2000 \ --ldapPort 1389 \ --adminConnectorPort 4444 \ --rootUserDN cn=Directory\ Manager \ --rootUserPassword ****** \ --enableStartTLS \ --ldapsPort 1636 \ --generateSelfSignedCertificate \ --hostName opendj.lxc.local \ --no-prompt \ --noPropertiesFile What would you like to do? 1) Set up the server with the parameters above 2) Provide the setup parameters again 3) Print equivalent non-interactive command-line 4) Cancel and exit Enter choice [1]: See /tmp/opendj-setup-269943537366412976.log for a detailed log of this operation. Configuring Directory Server ..... Done. Configuring Certificates ..... Done. Importing Automatically-Generated Data (2000 Entries) ................ Done. Starting Directory Server ............ Done. To see basic server configuration status and configuration you can launch /opt/opendj/bin/status </pre><p>On peut faire la création en mode non-interactif. Par exemple en utilisant la sortie de la commande interactive :</p> <pre>/opt/opendj/setup \ --cli \ --baseDN o=opendj-lxc \ --sampleData 2000 \ --ldapPort 1389 \ --adminConnectorPort 4444 \ --rootUserDN cn=Directory\ Manager \ --rootUserPassword ****** \ --enableStartTLS \ --ldapsPort 1636 \ --generateSelfSignedCertificate \ --hostName opendj.lxc.local \ --no-prompt \ --noPropertiesFile </pre><h2>Installation avec un fichier de propriétés</h2> <p>Il est également possible d'utiliser un fichier de <em>properties</em>, qui va contenir les paramètres (sans les --). Par exemple, pour installer OpenDJ avec les mêmes options que précédemment, on va créer un fichier<em> /opt/opendj/moninstall.props</em>, qui contient :</p> <pre>baseDN = o=opendj-lxc sampleData = 2000 ldapPort = 1389 adminConnectorPort = 4444 rootUserDN = cn=Directory\ Manager rootUserPassword = monMotDePasse enableStartTLS = true ldapsPort = 1636 generateSelfSignedCertificate = true hostName = opendj.lxc.local</pre><p>L'installation s'effectue alors avec la commande :</p> <pre>./setup --cli --propertiesFilePath /opt/opendj/moninstall.props --acceptLicense --noprompt</pre><p>Nous verrons par la suite comment personnaliser l'installation en <a href="http://www.vincentliefooghe.net/node/136">ajoutant un RootSuffix</a> supplémentaire, et en modifiant le schéma pour y ajouter des attributs ou classes d'objets spécifiques.</p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span class="field field--name-created field--type-created field--label-hidden">ven 26/06/2015 - 17:28</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> </section> Fri, 26 Jun 2015 15:28:45 +0000 vincentl 135 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/installation-opendj#comments OpenDJ https://www.vincentliefooghe.net/index.php/content/opendj <span class="field field--name-title field--type-string field--label-hidden">OpenDJ</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p><a href="http://www.forgerock.com/en-us/products/directory-services/">OpenDJ</a> est la solution d'annuaire LDAP proposée par Forgerock.</p> <p>Issu de l'ancien OpenDS de Sun Microsystems, il s'agit d'un annuaire LDAP V3, écrit en java, et donc "installable" sur un grand nombre de plates-formes (Linux, Unix, Windows, MacOS).</p> <p>Par rapport à un OpenLDAP, il propose des fonctionnalités intéressantes :</p> <ul> <li>un installateur (graphique, en mode ligne de commande ou via du scripting) qui propose dès le début la création d'un root Suffix</li> <li>une console mutli-instances qui permet de gérer le schéma, les indexes, les entrées de l'annuaire</li> <li>des fonctionnalités de réplication (issues, dans leur approche, du Sun Directory Server, avec par exemple une réplication par backend, de la réplication fractionnée, etc)</li> <li>la possibilité d'utiliser des requêtes REST pour interagir avec l'annuaire (plutôt que du LDAP)</li> <li>des groupes statiques, dynamiques, (basés sur des filtres LDAP) ou statiques virtuels</li> <li>des attributs virtuels et/ou collectifs (basé sur des classes de services)</li> </ul> <p>Nous verrons dans la suite de cette série comment mettre en oeuvre ces différentes fonctionnalités</p> <p>On peut trouver des informations plus techniques sur <a href="https://forgerock.org/opendj/">https://forgerock.org/opendj/</a></p> <p><strong>Attention</strong> : comme tous les produits Forgerock, le déploiement en production nécessite de disposer d'un contrat de support.</p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/index.php/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span class="field field--name-created field--type-created field--label-hidden">jeu 04/06/2015 - 11:26</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/index.php/cat%C3%A9gorie/iam" hreflang="fr">IAM</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/index.php/tags/forgerock" hreflang="fr">forgerock</a></div> <div class="field__item"><a href="/index.php/tags/opendj" hreflang="fr">opendj</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> </section> Thu, 04 Jun 2015 09:26:46 +0000 vincentl 132 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/opendj#comments