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).
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
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
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 :
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.
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
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 :
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 :
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.