Vincent Liefooghe - Logiciels (libres), CMS, IDM & Co https://www.vincentliefooghe.net/index.php/ fr Installer 389ds sur almalinux8 ou Red Hat https://www.vincentliefooghe.net/index.php/content/installer-389ds-sur-almalinux8-ou-red-hat <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Installer 389ds sur almalinux8 ou Red Hat</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Cet article traite en parallèle de 2 problématiques :</p> <ul><li>l'installation de 389DS à partir des dépôts EPEL modular, qui ont été désactivés fin octobre 2022</li> <li>l'installation de 389DS à partir des RPM, pour les machines qui n'ont pas accès aux dépôts externes sur internet</li> </ul><h2>Désactivation du dépot EPEL Modular</h2> <p>L'annuaire 389DS <a href="https://directory.fedoraproject.org/index.html">https://directory.fedoraproject.org/index.html</a> est disponible dans les dépôts Fedora, mais également dans les dépôts EPEL (Extra Packages for Enterprise Linux), en tant que module.</p> <p>Mais depuis fin octobre 2022, le dépôt <strong>epel-modular.repo</strong> a été désactivé (<a href="https://pagure.io/epel/issue/198">https://pagure.io/epel/issue/198</a>), rendant ainsi impossible l'installation.</p> <p>En effet, si on regarde le fichier <em>/etc/yum.repos.d/epel-modular.repo</em>, on se rend compte qu'on a <em>enabled=0</em>.</p> <p>Du coup, si on veut pouvoir utiliser ces dépôts (et la méthode recommandée sur le site de Fedora) on peut faire :</p> <pre> dnf install -y epel-release yum update -y dnf config-manager --set-enabled powertools # activer les repo dans /etc/yum.repos.d/epel-modular.repo sed -i 's/enabled=0/enabled=1/' /etc/yum.repos.d/epel-modular.repo</pre><p>A ce niveau, les dépôts seront réactivés. On peut donc lancer l'installation en mode module :</p> <pre> yum update -y yum module install -y 389-directory-server:stable/default</pre><p> </p> <h2>Installation à partir des RPM</h2> <p>Un autre cas assez fréquent chez les clients est que les serveurs n'ont pas accès aux dépôts tiers, ouverts sur internet, pour des raisons de sécurité.</p> <p>Il est alors possible de faire l'installation en récupérant à l'avance les RPM (à partir d'une autre machine connectée à internet), puis en copiant ces fichiers sur les serveurs cibles, et en faisant une installation locale.</p> <p>Sur la machine connectée à internet, on va donc activer le dépôt <strong>epel-release</strong> et epel-modular (voir ci-dessus).</p> <p>Puis on lance le téléchargement des fichiers</p> <pre> yum update -y yum install -y tar mkdir /root/ds389 yum module install --downloadonly --downloaddir=/root/ds389 389-directory-server:stable/default</pre><p>On peut ensuite créer une archive avec ces RPM :</p> <pre> cd /root tar zcf ds389-rpms.tgz ds389</pre><p>L'étape suivante est de copier cette archive sur le(s) serveur(s) cible(s), puis d'extraire l'archive.</p> <pre> scp ds389-rpms.tgz monservercible.example.com:/tmp</pre><p>Sur chaque serveur cible, on peut alors extraire et lancer l'installation :</p> <pre> cd /tmp tar zxf ds389-rpms.tgz cd ds389 yum localinstall -y *rpm</pre><p>A ce stade, on a un 389ds. On peut vérifier par exemple en listant les instances ::</p> <pre> dsctl -l</pre><p> </p> <p>Espérons que par la suite 389ds soit encore disponible dans les dépôts, en dehors de ceux de Fedora... Après avoir supprimé les packages OpenLDAP de la distribution Red Hat 8, il serait dommage de ne plus pouvoir utiliser un annuaire LDAP libre sur un OS Red Hat / CentOS / AlmaLinux ou autre...</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="2022-11-10T09:41:36+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">jeu 10/11/2022 - 10:41</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/389ds" hreflang="fr">389DS</a></div> <div class="field__item"><a href="/index.php/tags/ldap" hreflang="fr">ldap</a></div> </div> </div> <section class="field field--name-comment-node-blog 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=219&amp;2=comment_node_blog&amp;3=comment_node_blog" token="VCu05VsivR6glr3vrwc9ePvo10Bbcnx94iAI7fQC3s4"></drupal-render-placeholder> </section> Thu, 10 Nov 2022 09:41:36 +0000 vincentl 219 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/installer-389ds-sur-almalinux8-ou-red-hat#comments Synchronisation d'annuaires avec LSC https://www.vincentliefooghe.net/index.php/content/synchronisation-dannuaires-avec-lsc <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Synchronisation d&#039;annuaires avec LSC</span> <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="2022-09-22T16:09:46+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">jeu 22/09/2022 - 18:09</span> Thu, 22 Sep 2022 16:09:46 +0000 vincentl 218 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/synchronisation-dannuaires-avec-lsc#comments Problème de connexion ldapsearch sur un AD LDS https://www.vincentliefooghe.net/index.php/content/probl%C3%A8me-connexion-ldapsearch-sur-un-ad-lds <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Problème de connexion ldapsearch sur un AD LDS</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>J'ai été confronté à un problème curieux d'accès à un serveur AD LDS à partir d'un container de type Forgerock DS. </p> <p>Côté réseau, tout était OK, les ports ouverts d'un côté comme de l'autre.</p> <p>Par contre une commande <em>ldapsearch</em> tombait en erreur :</p> <pre> /opt/opendj/bin/ldapsearch --hostname 10.1.2.3 --port 389 -D "CN=admin,CN=Admin-Users,dc=example,dc=fr" -w admin2003 \ -b "CN=Applications,DC=example,DC=fr" "(objectclass=exApplications)" Unable to connect to the server: 91 (Connect Error) Additional Information: Remote close</pre><p>Pas très parlant.</p> <p>Côté AD LDS, en modifiant le niveau de logs, on a :</p> <pre> Internal event: The LDAP server returned an error. Additional Data Error value: 00000057: LdapErr: DSID-0C0C0095, comment: Error decoding ldap message, data 0, v4563</pre><p>Peu d'éléments complémentaires. Sachant qu'en plus, en local sur la machine AD LDS, la même connexion se fait sans problème.</p> <p>En investiguant un peu plus, je tente une connexion en mode "startSSL", pour voir si j'ai le même comportement :</p> <pre> /opt/opendj/bin/ldapsearch --useStartTls --hostname 10.1.2.3</pre><p>Et là, le message d'erreur côté machine cliente est différent et me met sur la piste :</p> <pre> An error occurred while parsing the command-line arguments: You may not provide both the --useStartTls and the --useSsl arguments See "ldapsearch --help" to get more usage help</pre><p>Comme je n'ai pas précisé les 2 options (useStartTls et useSsl) dans ma ligne de commande, l'option useSsl doit venir d'un paramétrage par défaut.</p> <p>Et en effet, par défaut les commandes ldap utilisent un fichier de propriétés (<em>/opt/opendj/config/tools.properties</em>) qui définit un certain nom de paramètres par défaut.<br /> On y trouvait notamment :</p> <pre> useSsl=true trustAll=true</pre><p>Du coup lorsque je tentais une connexion "en clair" sur le port 389, AD LDS recevait une requête sur un port non chiffré, mais avec une instruction qui disait que la connexion devait être chiffrée... d'où les messages d'erreur.</p> <p>En utilisant l'option "--noPropertiesFile" dans le ldapsearch, on peut du coup accéder en LDAP sur le port 389, et récupérer les données.</p> <p>L'autre option (plus sécurisée), serait d'utiliser du LDAPS entre les deux serveurs.</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="2022-05-13T12:05:59+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">ven 13/05/2022 - 14:05</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/forgerock" hreflang="fr">forgerock</a></div> </div> </div> <section class="field field--name-comment-node-blog 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=216&amp;2=comment_node_blog&amp;3=comment_node_blog" token="93czUIzLBmw8jkXBBdRQU08vkcT1Wk3MoNH84UAYHfA"></drupal-render-placeholder> </section> Fri, 13 May 2022 12:05:59 +0000 vincentl 216 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/probl%C3%A8me-connexion-ldapsearch-sur-un-ad-lds#comments Pass-Through Authentication et migration des mots de passe https://www.vincentliefooghe.net/index.php/content/pass-through-authentication-et-migration-des-mots-passe <span class="field field--name-title field--type-string field--label-hidden">Pass-Through Authentication et migration des mots de passe</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><h2>Contexte</h2> <p>Dans un projet de migration d'un annuaire AD LDS vers un Forgerock DS, le principal problème est de pouvoir récupérer les mots de passe.</p> <p>En effet, AD LDS (et AD DS) ne permettent pas d'exporter le hash du mot de passe en LDIF, et il n'est pas possible non plus <em>simplement</em> de les récupérer, même en passant par des outils tels que <em>creddump</em> , <em>ntdsextract</em> ou autre.</p> <p>Du coup, l'idée peut être intéressante de paramétrer l'annuaire Forgerock DS en mode <em>pass through authentication</em>, d'activer le cache, et ensuite d'utiliser le mot de passe local, une fois la première authentification correcte réalisée sur l'AD LDS (ou n'importe quel annuaire).</p> <h2>Pré-requis : import du certificat</h2> <p>Dans un premier temps, il faut importer le certificat de l'annuaire d'authentification. On peut récupérer le certificat avec une commande <em>openssl</em> :</p> <pre> <code>openssl s_client -connect authserver:2636 </code></pre><p>Une fois le certificat sauvegardé, on va l'intégrer avec <em>keytool</em> :</p> <pre> <code>keytool -importcert -alias authserver -keystore /opt/opendj/config/keystore -file ~/authserver.pem </code></pre><h2>Création d'un "fournisseur de confiance"</h2> <p>Via la commande <em>dsconfig</em>, on va déclarer le serveur d'authentification distant comme "<em>fournisseur de confiance</em>"</p> <pre> <code>dsconfig \ create-trust-manager-provider \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --provider-name AuthServerPKCS12 \ --type file-based \ --set enabled:true \ --set trust-store-type:PKCS12 \ --set trust-store-file:config/keystore \ --set trust-store-pin:"&amp;{file:config/keystore.pin}" \ --usePkcs12TrustStore /opt/opendj/config/keystore \ --trustStorePassword:file /opt/opendj/config/keystore.pin \ --no-prompt </code></pre><h2>Paramétrage du mode PTA</h2> <p>Il faut ensuite créer une politique d'authentification</p> <pre> <code>dsconfig \ create-password-policy \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --policy-name "AuthServer_PTA_Policy" \ --type ldap-pass-through \ --set primary-remote-ldap-server:authserver:636 \ --set mapped-attribute:uid \ --set mapped-search-base-dn:"cn=Users,dc=example,dc=com" \ --set mapped-search-bind-dn:"uid=ad-bind-account,cn=admins,dc=example,dc=com" \ --set mapped-search-bind-password:ZmQ5OWUw-ADpassword \ --set trust-manager-provider:AuthServerPKCS12 \ --set mapping-policy:mapped-search \ --set use-password-caching:true \ --set cached-password-storage-scheme:PBKDF2-HMAC-SHA256 \ --set cache-password-ttl:24h \ --set use-ssl:true \ --usePkcs12TrustStore /opt/opendj/config/keystore \ --trustStorePassword:file /opt/opendj/config/keystore.pin \ --no-prompt </code></pre><p>On précise notamment :</p> <ul><li>le <em>hostname</em> et le port du serveur d'authentification (dans notre exemple, <strong>authserver</strong>, qui écoute sur le port <strong>636</strong>)</li> <li>la base de recherche pour les utilisateurs</li> <li>l'attribut commun entre le compte local et le compte sur le serveur d'authentification, dans l'exemple on utilise <strong>uid</strong> (il faut donc que l'attribut soit bien unique et identique sur les 2 serveurs)</li> <li>le DN du compte sur le serveur distant</li> <li>le mot de passe du compte distant</li> <li>Le trust manager (déclaré ci-avant)</li> </ul><p>En optionnel, on active le "<em>password caching</em>", qui permet, lors d'une première authentification réalisée avec succès, de cacher le mot de passe en local pour éviter les multiples accès sur le serveur d'authentification distant. Pour ceci, il faut également définir le schéma de stockage du mot de passe caché.</p> <p>On positionne la valeur du cache (TTL) à 24 heures.</p> <h2>Assignation de la password policy à un utilisateur</h2> <p>Pour que la politique de type "<em>pass through</em>" soit appliquée à l'utilisateur, il faut l'assigner de manière explicite, par exemple via un fichier ldif :</p> <pre> <code>dn: cn=user1,ou=Externes,ou=People,dc=example,dc=com changetype: modify add: ds-pwp-password-policy-dn ds-pwp-password-policy-dn: cn=AuthServer_PTA_Policy,cn=Password Policies,cn=config </code></pre><p>Si l'utilisateur tente ensuite de se connecter au serveur DS, on peut voir les logs sur le serveur d'authentification (ici il s'agit des logs d'une autre instance Forgerock DS, utilisée pour les tests):</p> <pre> <code>{"eventName":"DJ-LDAP","client":{"ip":"127.0.0.1","port":60984},"server":{"ip":"127.0.0.1","port":2636},"request":{"protocol":"LDAPS","operation":"SEARCH","connId":8,"msgId":9,"dn":"cn=Users,dc=example,dc=com","scope":"sub","filter":"(uid=1189670333702hawl)","attrs":["1.1"]},"transactionId":"0a31b37e-b7f3-4854-9154-5ebad695ff24-488","response":{"status":"SUCCESSFUL","statusCode":"0","elapsedTime":1,"elapsedTimeUnits":"MILLISECONDS","nentries":1},"userId":"uid=ad-bind-account,ou=admins,dc=example,dc=com","timestamp":"2022-04-04T14:15:36.803Z","_id":"0a31b37e-b7f3-4854-9154-5ebad695ff24-490"} {"eventName":"DJ-LDAP","client":{"ip":"127.0.0.1","port":60986},"server":{"ip":"127.0.0.1","port":2636},"request":{"protocol":"LDAPS","operation":"BIND","connId":9,"msgId":8,"version":"3","dn":"cn=user1,cn=Users,dc=example,dc=com","authType":"SIMPLE"},"transactionId":"0a31b37e-b7f3-4854-9154-5ebad695ff24-491","response":{"status":"SUCCESSFUL","statusCode":"0","elapsedTime":1,"elapsedTimeUnits":"MILLISECONDS","additionalItems":{"ssf":"256"}},"userId":"cn=user1,cn=Users,dc=example,dc=com","timestamp":"2022-04-04T14:15:36.805Z","_id":"0a31b37e-b7f3-4854-9154-5ebad695ff24-493"} </code></pre><p>Si on a activé le cache, on peut constater qu'après une première authentification correcte, l'annuaire distant n'est plus sollicité lors des authentifications suivantes, sauf si le mot de passe ne correspond plus à la valeur en cache.</p> <p>Au niveau local, le mot de passe est stocké dans un attribut opérationnel : <em>ds-pta-cached-password</em>. On y trouve également la date de mise en cache du mot de passe.</p> <p>Par exemple :</p> <pre> <code>dn: cn=user1,ou=Externes,ou=People,dc=example,dc=com ds-pta-cached-password: {SSHA512}CpdBFPCD2LrQpDOFK+hjOifS+hwRz79yWYjMFS543iyAmHZIliBgHnoKjY+HhERC61eQMqNmkgEvrlXYtkmhyK9HK+0gqQQBraFUUd2TViM= ds-pta-cached-password-time: 20220404141914Z ds-pwp-password-policy-dn: cn=AuthServer_PTA_Policy,cn=Password Policies,cn=config </code></pre><h2>Migration progressive des mots de passe</h2> <p>En utilisant le mécanisme de cache et l'authentification en mode <em>pass through</em>, on pourra donc envisager de migrer progressivement les mots de passe de la manière suivante :</p> <ul><li>pour tous les utilisateurs qui doivent être migrés, assigner la politique de mot de passe de type "PTA Policy"</li> <li>pour les autres, on peut se reposer sur les politiques de mots de passe par défaut, ou celles définies dans les données (de type <em>subentry</em>)</li> </ul><p>Il faudra ensuite avoir un traitement complémentaire, qui sera lancé à intervalle régulier, et avec une fréquence supérieure à la durée de cache, qui va réaliser le traitement suivant :</p> <ul><li>rechercher les comptes qui ont l'attribut <em>ds_pta-cached-password</em> positionné, avec la politique de mot de passe "PTA"</li> <li>Pour ces comptes :</li> <li>mettre à jour l'attribut <em>userPassword</em> avec la valeur de l'attribut de cache</li> <li>supprimer l'assignation de la politique de mot de passe, pour récupérer celle définie par défaut.</li> </ul><p>Afin d'améliorer les performances, on pourra créer un index sur l'attribut :</p> <pre> <code>create-backend-index --backend-name amIdentityStore --index-name ds-pta-cached-password --type generic --set index-type:presence </code></pre><p>Ceci peut donc permettre d'utiliser les mots de passe actuels, tout en déconnectant au fil de l'eau le lien avec l'ancien annuaire.</p> <p>Au bout d'un certain temps, on pourra considérer que les comptes qui ont encore l'ancienne politique de mots de passe (ou qui n'ont pas encore d'attribut <em>userPassword</em>) ne sont pas utilisés, et on pourra faire un peu de "ménage", ou faire une campagne de renouvellement de mots de passe.</p> <p> </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">lun 04/04/2022 - 17:09</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/ds" hreflang="fr">ds</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"> <h2 class="title comment-form__title">Ajouter un commentaire</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=215&amp;2=comment_node_book&amp;3=comment_node_book" token="5eq-zcWEYJm_Yk06U0kNvELXXhjQF7kEMPtT6Lez1yY"></drupal-render-placeholder> </section> Mon, 04 Apr 2022 15:09:40 +0000 vincentl 215 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/pass-through-authentication-et-migration-des-mots-passe#comments Utilisation d'attributs Json dans Forgerock DS https://www.vincentliefooghe.net/index.php/content/utilisation-dattributs-json-dans-forgerock-ds <span class="field field--name-title field--type-string field--label-hidden">Utilisation d&#039;attributs Json dans Forgerock DS</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><h2>Problématique</h2> <p>Il arrive des cas où l'utilisation des attributs "simples", qu'ils soient mono ou multi-valués, n'est pas satisfaisante par rapport aux besoins des utilisateurs.</p> <p>Prenons le cas suivant : on veut gérer des délégations pour X types de profils et chacun avec des rôles spécifiques.</p> <p>Soit :</p> <ul><li>délégation pour une société S1, avec les rôles RS1, RS2, RS3</li> <li>délégation pour une société S2, avec les rôles RS1, RS3</li> <li>délégation pour un utilisateur U1, avec les rôles RU1, RU2</li> </ul><p>Si on utilise un attribut de type chaîne de caractères, on peut s'en sortir avec des concaténations et des caractères de séparation. Par exemple :</p> <pre> <code>type|identifiant du type|role1-role2-role3 </code></pre><p>Dans ce cas on doit déjà gérer 2 types de séparateurs :le "|" pour les différents éléments, et le "-" pour les rôles.</p> <p>Dans notre exemple, ça donnerait :</p> <ul><li>societe|S1|RS1-RS2-RS3</li> <li>societe|S2|RS1-RS3</li> <li>utilisateur|U1|RU1-RU2</li> </ul><p>Par contre pour les recherches, ça devient plus compliqué, sauf à pré-calculer un filtre, en jouant avec les séparateurs.</p> <h2>Attribut Json</h2> <p>Depuis la version 5.5 (au moins), Forgerock permet d'utiliser une syntaxe Json dans les attributs, ce qui permet de gérer des données structurées à l'intérieur d'un attribut.</p> <h3>Déclaration dans le schéma</h3> <p>L'ajout d'un attribut de type JSON se fait de manière <em>traditionnelle</em>, en utilisant une syntaxe spécifique (<em>1.3.6.1.4.1.36733.2.1.3.1</em>).</p> <p>On ajoute ensuite les attributs dans le schéma :</p> <pre> <code>attributeTypes: ( 1.3.6.1.4.1.18472.2.101 NAME 'delegations' SYNTAX 1.3.6.1.4.1.36733.2.1.3.1 EQUALITY caseIgnoreJsonQueryMatch X-ORIGIN 'Mes tests json' ) attributeTypes: ( 1.3.6.1.4.1.18472.2.102 NAME 'jsonId' SYNTAX 1.3.6.1.4.1.36733.2.1.3.1 EQUALITY caseIgnoreJsonIdMatch SINGLE-VALUE X-ORIGIN 'Mes tests json' ) </code></pre><p>On doit également préciser le type de règle d'égalité qui sera utilisée. Il en existe 4 pré-définies :</p> <ul><li>caseIgnoreJsonQueryMatch : 2 objets sont identiques si tous leurs champs sont les mêmes, à la casse près</li> <li>caseExactJsonQueryMatch : 2 objets sont identiques si tous leurs champs sont les mêmes, avec la même casse de caractères</li> <li>caseIgnoreJsonIdMatch : 2 objets sont identiques si leur champ "_id" est identique, quelle que soit la casse de caractères</li> <li>caseExactJsonIdMatch : 2 objets sont identiques si leur champ "_id" est identique, avec la même casse de caractères.</li> </ul><p>Quelques exemples pour illustrer les cas. En supposant que j'ai 2 entrées dans l'annuaire LDAP, avec :</p> <ol><li>{"_id":"json","type":"user","value":"user123"}</li> <li>{"_id":"Json","type":"User","value":"USER123"}</li> <li>{"_id":"json","type":"user","value":"user345"}</li> <li>{"_id":"Json","type":"User","value":"USER345"}</li> </ol><p>Selon les cas :</p> <ul><li>avec la règle <strong>caseIgnoreJsonQueryMatch</strong>, les objets 1 et 2, et les objets 3 et 4 sont identiques</li> <li>avec la règle <strong>caseExactJsonQueryMatch</strong>, il n'y a pas de correspondance</li> <li>avec la règle <strong>caseIgnoreJsonIdMatch</strong>, les 4 objets sont identiques (ils ont le même _id)</li> <li>avec la règle <strong>caseExactJsonIdMatch</strong>, les objets 1 et 3 sont considérés identiques, ainsi que 2 et 4</li> </ul><h3>Indexation</h3> <p>Lorsqu'on indexe un attribut JSON, le comportement par défaut de Forgerock DS est de maintenir des clés pour chaque champ JSON. De ce fait, si l'attribut JSON contient de nombreux champs différents (et qui ne font pas l'objet de recherches) on peut choisir de n'indexer que ces champs. Dans ce cas, il faudra définir soi-même une règle (de type <em>json-equality-matching-rule</em>).</p> <p>Si on utilise une règle de comparaison basée sur l'ID uniquement, c'est ce champ qui sera indexé, et pas les autres.</p> <h3>Recherche</h3> <p>La syntaxe du filtre de recherche est la même que celle utilisée pour les API REST Forgerock (communément appelées CREST = Common REST).</p> <p>Quelques exemples de filtres, sur la base de nos attributs <em>delegations</em> et <em>jsonId</em> déclarés précédemment :</p> <pre> <code>delegations: {"type":"societe","attributions":[{"id":"societe1","roles":["role-soc1","role-soc2","role-soc3"]},{"id":"societe2","roles":["role-soc4"]}]} delegations: {"type":"utilisateur","attributions":[{"id":"user1","roles":["role-usr1","role-usr2"]},{"id":"user2","roles":["role-usr4"]}]} delegations: {"type":"org","attributions":[{"id":"org1","roles":["role-org1","role-org2","role-org4"]}] } jsonId: {"_id":"json","type":"user","value":"user123"} jsonId: {"_id":"Json","type":"User","value":"USER123"} jsonId: {"_id":"json","type":"user","value":"user345"} jsonId: {"_id":"Json","type":"User","value":"USER345"} </code></pre><ul><li>(delegations=*) : va renvoyer toutes les entrées qui ont un attribut <em>delegations</em></li> <li>(jsonid=_id eq 'json') va renvoyer les entrées qui ont la valeur 'json' dans le champ "_id" de l'attribut</li> <li>(delegations=type eq 'utilisateur' or type eq 'societe') : va renvoyer les objets ayant l'une ou l'autre valeur dans le champ type</li> </ul><p><strong>Limitations sur les filtres de recherche</strong></p> <p>Il n'est pas possible de faire une recherche dans un tableau qui contient plusieurs objets (attributions dans notre exemple).</p> <pre> <code>(delegations=id eq "user2") </code></pre><p>ne ramène rien (on n'y accède pas directement, il faudrait passer par attributions-&gt;id).</p> <p>Par contre, si on a une structure dont l'un des attributs est un tableau, qui ne contient que des valeurs, cela fonctionne.</p> <p>Si on a des attributs comme ceci :</p> <pre> <code>delegations: {"type":"utilisateur","id":"user1","roles":["role-usr1","role-usr2"]} delegations: {"type":"utilisateur","id":"user2","roles":["role-usr4","role-usr2"]} delegations: {"type":"societe","id":"societe1","roles":["role-soc1","role-soc2","role-soc3"]} delegations: {"type":"societe","id":"societe2","roles":["role-soc4"]} delegations: {"type":"org","id":"org2","roles":["role-org1","role-org2","role-org4"]} </code></pre><p>On peut bien faire des recherches de type :</p> <pre> <code>ldapsearch -b ou=people,dc=example,dc=com '(delegations=id eq "user2")' </code></pre><p>Si on veut éviter des collisions entre les différents types, on peut combiner plusieurs recherches. Si elles portent sur plusieurs éléments de l'attribut <em>json</em>, il faut utiliser le filtre adéquat. Par exemple :</p> <pre> <code>(delegations=id eq "2" and type eq "societe") </code></pre><p>La recherche dans un tableau fonctionne également. On peut ainsi rechercher tout les objets LDAP qui ont un role "role-usr4" :</p> <pre> <code>(delegations=roles eq "role-usr4") </code></pre><p>Idem pour les objets avec un type "societe" et un rôle "role-soc1" :</p> <pre> <code>(delegations=type eq "societe" and roles eq "role-soc1") </code></pre></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 04/03/2022 - 14:55</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/ds" hreflang="fr">ds</a></div> <div class="field__item"><a href="/index.php/tags/json" hreflang="fr">json</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=214&amp;2=comment_node_book&amp;3=comment_node_book" token="sYSuQMghlx0xCAUDqXvngNEvgVyPnyCe-RJ6u6n_6dw"></drupal-render-placeholder> </section> Fri, 04 Mar 2022 13:55:34 +0000 vincentl 214 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/utilisation-dattributs-json-dans-forgerock-ds#comments SailPoint IdentityIQ vs SailPoint IdentityNow https://www.vincentliefooghe.net/index.php/content/sailpoint-identityiq-vs-sailpoint-identitynow <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">SailPoint IdentityIQ vs SailPoint IdentityNow</span> <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="2022-01-04T15:17:40+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">mar 04/01/2022 - 16:17</span> Tue, 04 Jan 2022 15:17:40 +0000 vincentl 213 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/sailpoint-identityiq-vs-sailpoint-identitynow#comments Utilisation de SLAMD pour les benchmarks LDAP https://www.vincentliefooghe.net/index.php/content/utilisation-slamd-pour-les-benchmarks-ldap <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Utilisation de SLAMD pour les benchmarks LDAP</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 réalise des études comparatives sur les annuaires LDAP, il est fréquent que le client demande d'établir des tests de performances, pour s'assurer que la solution en place sera capable de répondre à ses exigences.</p> <p>Pour faire cela, j'utilisais souvent les outils <em>authrate</em> ou <em>searchrate</em> présents dans les binaires des annuaires de Forgerock ou Ping.</p> <p>Si ces outils permettent de tester de manière unitaire, et avec un certain nombre de paramètres, ils manquait certaines possibilités / fonctionnalités :</p> <ul><li>pas de possibilité de lancer plusieurs clients en parallèle, de manière synchronisée</li> <li>pas de reporting de base</li> <li>pas de réutilisation des modèles de "tirs"</li> </ul><p>Dans le cadre d'un nouveau projet d'étude, je suis tombé sur l'outil <em>SLAMD</em> disponible sur <a href="https://github.com/dirmgr/slamd">GitHub</a>.</p> <h2>Présentation de SLAMD</h2> <p>Il s'agit d'un outil écrit en Java, par un ancien employé de Sun qui travaillait sur les annuaires OpenDS notamment.</p> <p>On trouve également chez Oracle (qui a racheté Sun il y a plusieurs années), les binaires à télécharger : <a href="https://www.oracle.com/security/identity-management/technologies/slamd-downloads/">Oracle SLAMD Downloads</a></p> <p>L'outil se présente comme "<em>Distributed Load Generation Engine</em>", ce qui donne une idée de son architecture répartie. En effet, <em>SLAMD</em> est articulé autour de plusieurs composants :</p> <ul><li>un serveur, qui tourne dans un serveur Tomcat, qui permet de paramétrer les <em>jobs</em>, et construire les rapports</li> <li>un (ou plusieurs) clients, qui vont communiquer avec le serveur pour récupérer les <em>jobs</em> à traiter, et qui vont effectuer les requêtes demandées (ce sont eux qui vont vraiment faire le travail)</li> <li>un service de monitoring que l'on peut installer sur les serveurs LDAP pour remonter les informations au serveur SLAMD.</li> </ul><p>L'outil a été développé à l'origine pour remplacer / améliorer les <em>authrate</em> et autres, avec une orientation LDAP, mais peut aussi être utilisé pour d'autres protocoles réseau (http, smtp, pop,imap).</p> <h2>Utilisation</h2> <p>Une fois qu'on a récupéré les binaires ou compilé à partir de GitHub et installé les composants sur les serveurs, est de définir les <em>jobs</em> qui seront ensuite activés.</p> <p>Ceci se fait via l'option de menu "Schedule a job", dans laquelle on voit toute la richesse de l'outil.</p> <p>Pour les tests LDAP, on dispose d'une vingtaine de modèle prédéfinis, notamment :</p> <ul><li>Add and Delete : ajout et suppression, utilisé pour les tests d'écriture</li> <li>Basic Bind : connexion simple, sans recherche préalable</li> <li>Basic Search and Bind : connexion après recherche de l'utilisateur ; c'est ce que j'utilise pour tester les mécanismes d'authentification</li> <li>Comprehensive Search : possibilité de mettre plusieurs serveurs, plusieurs filtres et de préciser les attributs retournés</li> <li>Mix load : mélange de Add, Bind, Search, etc</li> </ul><h2>Paramétrage du Search + Bind</h2> <p>Dans la majorité des cas en mode <em>Authentification</em>, celle-ci se passe en 2 étapes :</p> <ul><li>on fait d'abord une recherche de l'utilisateur dans la base, via le RDN (ou un autre attribut)</li> <li>une fois le DN récupéré, on va faire une tentative de connexion avec le mot de passe.</li> </ul><p>Pour tester ceci, on va utiliser différents paramètres (en mode Basic) :</p> <ul><li>Durée du Job</li> <li>Nombre de clients (à savoir que si on n'a pas assez de clients disponibles, le job ne va pas démarrer)</li> <li>Nombre de threads par client</li> <li>Durée de montée en charge / descente de charge</li> <li>Nom et port du serveur LDAP, ainsi que la méthode de sécurité (aucune, StartTLS ou SSL)</li> <li>Bind DN et mot de passe utilisé pour la recherche (généralement, un compte de service)</li> <li>DN de base pour la recherche (par exemple : ou=Users,dc=example,dc=com)</li> <li>Périmètre de recherche (scope = subtree, single-level, base)</li> <li>Search Filter Pattern : le motif de recherche.</li> <li>Mot de passe utilisateur</li> </ul><p>Pour que cela fonctionne, on aura au préalable inséré dans l'annuaire des utilisateurs de tests, avec le même mot de passe, puisque celui-ci est donné dans la configuration.</p> <p>Le motif de recherche LDAP peut être variabilisé. Par exemple, si j'ai généré des utilisateurs avec un uid=userXXXXX (XXXXX = numérique de 1 à 99999), je peux avoir différents motifs pour mon filtre LDAP :</p> <ul><li>(uid=user[1-100000]) : recherche de user1 à user100000 de manière aléatoire</li> <li>(uid=user[1:100000]) : recherche de user1 à user100000 de manière séquentielle</li> </ul><p>Un bouton permet de tester les paramètres (connexion à l'annuaire, existence du Base DN, etc).</p> <p>Une fois le job préparé, on peut l'activer pour qu'il soit traité par les clients. Il passe alors en état "<strong>Running</strong>".</p> <p>Lorsqu'il est terminé, il passe à l'état "<strong>Completed</strong>".</p> <p>On peut dupliquer / cloner un job si on veut le relancer tel quel, ou le modifier pour changer ses paramètres.</p> <h2>Données récupérées</h2> <p>Une fois que le <em>job</em> est terminé, on peut avoir accès aux données recueillies par les clients et centralisées sur le serveur.</p> <p>Les données peuvent être affichées sous forme de graphique, directement sur le serveur, ou être générées sous forme de rapport HTML ou PDF.</p> <p>Le rapport contient pas mal d'informations par défaut :</p> <ul><li>le nom du job, sa description</li> <li>les informations de planification : durée, nombre de clients, nombre de threads</li> <li>paramètres du job</li> <li>les informations d'exécution : date de début et fin, durée, nom des machines clients</li> <li>les résultats des différentes requêtes : nombre, moyenne / seconde, moyenne / intervalle de collecte, ainsi qu'un graphe des données, et la même chose en temps de réponse.</li> <li>répartition des requêtes par statut et temps de réponse.</li> </ul><h2>Autres éléments</h2> <p>Un système de "<em>folders</em>" permet de regrouper ses différents <em>jobs</em> ce qui peut être intéressant pour gérer les séances de tests, soit par type d'annuaire si on en compare plusieurs, soit par type de tests si on fait par exemple changer le nombre de threads.</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="2021-10-13T16:24:59+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">mer 13/10/2021 - 18:24</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/autres" hreflang="fr">Autres</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/benchmark" hreflang="fr">benchmark</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-blog 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=212&amp;2=comment_node_blog&amp;3=comment_node_blog" token="rGeZhG9defyDWatkcDCg4uVhSr1m77C8ZNq7sKOkxhE"></drupal-render-placeholder> </section> Wed, 13 Oct 2021 16:24:59 +0000 vincentl 212 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/utilisation-slamd-pour-les-benchmarks-ldap#comments OpenLDAP - LastBind Overlay https://www.vincentliefooghe.net/index.php/content/openldap-lastbind-overlay <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">OpenLDAP - LastBind Overlay</span> <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="2021-05-31T14:00:20+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">lun 31/05/2021 - 16:00</span> Mon, 31 May 2021 14:00:20 +0000 vincentl 211 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/openldap-lastbind-overlay#comments Gestion du firewall sous CentOS8 / Red Hat 8 https://www.vincentliefooghe.net/index.php/content/gestion-du-firewall-sous-centos8-red-hat-8 <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Gestion du firewall sous CentOS8 / Red Hat 8</span> <span rel="sioc:has_creator" 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 property="dc:date dc:created" content="2021-04-14T11:54:24+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">mer 14/04/2021 - 13:54</span> Wed, 14 Apr 2021 11:54:24 +0000 Vincent 210 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/index.php/content/gestion-du-firewall-sous-centos8-red-hat-8#comments 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 https://www.vincentliefooghe.net/index.php/content/forgerock-opendj-ds-supprimer-les-contr%C3%B4les-syntaxe#comments