Contexte
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.
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 simplement de les récupérer, même en passant par des outils tels que creddump , ntdsextract ou autre.
Du coup, l'idée peut être intéressante de paramétrer l'annuaire Forgerock DS en mode pass through authentication, 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).
Pré-requis : import du certificat
Dans un premier temps, il faut importer le certificat de l'annuaire d'authentification. On peut récupérer le certificat avec une commande openssl :
openssl s_client -connect authserver:2636
Une fois le certificat sauvegardé, on va l'intégrer avec keytool :
keytool -importcert -alias authserver -keystore /opt/opendj/config/keystore -file ~/authserver.pem
Création d'un "fournisseur de confiance"
Via la commande dsconfig, on va déclarer le serveur d'authentification distant comme "fournisseur de confiance"
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:"&{file:config/keystore.pin}" \
--usePkcs12TrustStore /opt/opendj/config/keystore \
--trustStorePassword:file /opt/opendj/config/keystore.pin \
--no-prompt
Paramétrage du mode PTA
Il faut ensuite créer une politique d'authentification
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
On précise notamment :
- le hostname et le port du serveur d'authentification (dans notre exemple, authserver, qui écoute sur le port 636)
- la base de recherche pour les utilisateurs
- l'attribut commun entre le compte local et le compte sur le serveur d'authentification, dans l'exemple on utilise uid (il faut donc que l'attribut soit bien unique et identique sur les 2 serveurs)
- le DN du compte sur le serveur distant
- le mot de passe du compte distant
- Le trust manager (déclaré ci-avant)
En optionnel, on active le "password caching", 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é.
On positionne la valeur du cache (TTL) à 24 heures.
Assignation de la password policy à un utilisateur
Pour que la politique de type "pass through" soit appliquée à l'utilisateur, il faut l'assigner de manière explicite, par exemple via un fichier ldif :
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
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):
{"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"}
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.
Au niveau local, le mot de passe est stocké dans un attribut opérationnel : ds-pta-cached-password. On y trouve également la date de mise en cache du mot de passe.
Par exemple :
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
Migration progressive des mots de passe
En utilisant le mécanisme de cache et l'authentification en mode pass through, on pourra donc envisager de migrer progressivement les mots de passe de la manière suivante :
- pour tous les utilisateurs qui doivent être migrés, assigner la politique de mot de passe de type "PTA Policy"
- 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 subentry)
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 :
- rechercher les comptes qui ont l'attribut ds_pta-cached-password positionné, avec la politique de mot de passe "PTA"
- Pour ces comptes :
- mettre à jour l'attribut userPassword avec la valeur de l'attribut de cache
- supprimer l'assignation de la politique de mot de passe, pour récupérer celle définie par défaut.
Afin d'améliorer les performances, on pourra créer un index sur l'attribut :
create-backend-index --backend-name amIdentityStore --index-name ds-pta-cached-password --type generic --set index-type:presence
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.
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 userPassword) ne sont pas utilisés, et on pourra faire un peu de "ménage", ou faire une campagne de renouvellement de mots de passe.
Ajouter un commentaire