Fiche récapitulative des playbooks Ansible
pour l'intégration Windows-Linux avec Active
Directory
Vue d'ensemble du système
Notre objectif était de créer un environnement mixte Windows-Linux où les utilisateurs d'Active
Directory peuvent accéder automatiquement aux partages réseau correspondant à leurs groupes
d'appartenance. Cette solution utilise:
• Un serveur Windows 2019 (SRV-AD-BARZINI) avec Active Directory
• Une machine gestionnaire Ubuntu (BARZINI-GESTIONNAIRE) avec Ansible
• Des machines clientes Linux (BARZINI-CLIENT) et Windows
Playbooks principaux
1. deploy_fstab_* (deploy_fstab_dev.yml, deploy_fstab_audio.yml, etc.)
Utilité: Ces playbooks constituent notre première approche pour configurer les montages SMB.
Chaque playbook est dédié à un partage spécifique.
Détails:
• Création du fichier d'identifiants (/etc/smb_credentials) pour l'authentification SMB
• Ajout d'entrées dans /etc/fstab pour monter automatiquement les partages au démarrage
• Création des points de montage dans /mnt/
• Montage immédiat des partages
Interaction: Ces playbooks fonctionnent indépendamment les uns des autres, chacun gérant un
partage spécifique. Ils ont constitué notre approche initiale, mais présentaient une limitation
importante: tous les partages étaient montés globalement sous /mnt/, indépendamment des besoins
spécifiques des utilisateurs.
2. deploy_dynamic_mounts.yml
Utilité: Ce playbook représente notre deuxième approche, plus sophistiquée, qui introduit des
montages dynamiques basés sur les groupes d'utilisateurs.
Détails:
• Nettoyage des anciennes entrées dans /etc/fstab (remplace l'approche statique)
• Création d'un script bash (/usr/local/bin/mount_shares_by_group.sh) qui:
• Détecte les groupes de l'utilisateur
• Monte uniquement les partages correspondant à ces groupes
• Place les montages dans le répertoire personnel (~partages/) plutôt que globalement
• Configuration du script pour s'exécuter au login via /etc/profile.d/
• Ajout d'un script de nettoyage pour démonter à la déconnexion
Interaction: Ce playbook représente une évolution par rapport aux deploy_fstab_*, avec une
approche plus personnalisée. Il a remplacé les montages statiques par des montages dynamiques,
mais a rencontré des problèmes de permissions puisque les utilisateurs normaux ne peuvent pas
monter des systèmes de fichiers.
3. deploy_pam_smb_mounts.yml
Utilité: Ce playbook représente notre solution finale et la plus robuste, résolvant le problème de
permissions du script précédent.
Détails:
• Création du fichier d'identifiants comme les précédents
• Création d'un script exécuté par PAM (/etc/pam.d/session-cleanup.sh)
• Configuration de PAM pour exécuter ce script lors de la connexion et déconnexion
• Nettoyage des anciennes entrées fstab et suppression des anciens points de montage
• Ce script s'exécute avec les privilèges root, ce qui résout le problème d'autorisations
Interaction: Ce playbook représente la solution finale qui combine les avantages des approches
précédentes tout en résolvant leurs limitations. Il a effectivement remplacé
deploy_dynamic_mounts.yml.
4. deploy_smb.yml
Utilité: Ce playbook avait pour objectif de déployer un script de montage SMB personnalisé sur les
clients.
Détails:
• Copie d'un script de montage SMB depuis /etc/ansible/files/mount_smb.sh
• Exécution immédiate du script
Interaction: Ce playbook représentait une approche alternative ou complémentaire, mais n'a pas été
intégré dans notre solution finale basée sur PAM.
Playbooks Windows (non listés mais implémentés)
Bien qu'absents de votre liste, nous avons également mis en place une solution pour les clients
Windows via une stratégie de groupe (GPO) et un script PowerShell pour le mappage automatique
des lecteurs réseau.
Processus d'évolution de la solution
Notre démarche a suivi une évolution progressive:
1. Approche initiale (deploy_fstab_*): Montages statiques via /etc/fstab
2. Approche intermédiaire (deploy_dynamic_mounts.yml): Script shell pour montages
dynamiques
3. Solution finale (deploy_pam_smb_mounts.yml): Script PAM pour montage automatique
La solution finale retenue combine:
• L'authentification AD via SSSD
• Le montage dynamique des partages selon les groupes
• L'exécution avec les privilèges appropriés via PAM
Dépannage spécifique
Le cas du partage Asr a nécessité une attention particulière à cause de:
1. La casse du nom (Asr vs ASR)
2. L'appartenance de l'utilisateur ansible au groupe GG_ASR
En résolvant ces deux points, nous avons complété la solution globale qui permet désormais à tous
les utilisateurs d'accéder automatiquement aux partages correspondant à leurs groupes, que ce soit
sur les clients Linux ou Windows.
Playbooks manquants ou non utilisés
Je ne vois pas de playbook crucial manquant dans votre liste. Le playbook deploy_contraste.yml n'a
pas été mentionné dans notre discussion, et deploy_cca.yml n'a pas non plus été utilisé dans notre
solution d'intégration AD.
________________________________________________________________________________
________________________________________________________________________________
Montage automatique des partages réseau
basé sur les groupes d'utilisateurs
Architecture globale de la solution
Notre solution permet à chaque utilisateur d'accéder automatiquement aux partages correspondant à
ses groupes d'appartenance dans Active Directory, comme le montre notre démo d'un utilisateur du
groupe ADMIN accédant au partage ADMIN.
Configuration étape par étape
1. Structure des groupes dans Active Directory
Nous avons d'abord établi une structure AGDLP (Account, Global Group, Domain Local Group,
Permission) dans Active Directory:
• Groupes globaux (GG_DEV, GG_ADMIN, GG_AUDIO, GG_GRAPH, GG_ASR,
GG_TEST)
• Groupes locaux de domaine (LG_SHARED_DEV, LG_SHARED_ADMIN, etc.)
• Chaque utilisateur est membre d'un ou plusieurs groupes globaux
• Chaque groupe global est membre du groupe local correspondant
• Les permissions sur les partages sont accordées aux groupes locaux
2. Configuration côté Linux
A. Configuration initiale d'intégration à Active Directory
1. La machine cliente a été jointe au domaine avec realm join
2. SSSD a été configuré pour l'authentification avec Active Directory
3. La configuration PAM a été ajustée pour supporter l'authentification du domaine
B. Montage automatique des partages (solution finale)
1. Création d'un script PAM de montage automatique (/etc/pam.d/session-
cleanup.sh):
#!/bin/bash
# Script pour gérer les montages SMB en fonction de l'utilisateur connecté
USERNAME=$PAM_USER
USER_HOME=$(getent passwd $USERNAME | cut -d: -f6)
# Si c'est un utilisateur système, ne rien faire
if [ -z "$USER_HOME" ] || [ "$USER_HOME" == "/dev/null" ] || [ $(id -u $USERNAME)
-lt 1000 ]; then
exit 0
fi
# Créer le répertoire de montage
USER_MNT="$USER_HOME/partages"
mkdir -p "$USER_MNT"
chown $USERNAME:$(id -g $USERNAME) "$USER_MNT"
# Obtenir les groupes de l'utilisateur
USER_GROUPS=$(id $USERNAME)
# Démonter les anciens partages
find "$USER_MNT" -mindepth 1 -maxdepth 1 -type d | while read dir; do
if mountpoint -q "$dir"; then
umount "$dir"
fi
done
# Vérifier chaque groupe et monter le partage correspondant
if echo "$USER_GROUPS" | grep -q "gg_dev"; then
SHARE_DIR="$USER_MNT/DEV"
mkdir -p "$SHARE_DIR"
mount -t cifs "//SRV-AD-BARZINI/DEV" "$SHARE_DIR" -o
credentials=/etc/smb_credentials,sec=ntlmssp,vers=3.0,uid=$(id -u $USERNAME),gid=$
(id -g $USERNAME),file_mode=0770,dir_mode=0770,iocharset=utf8,noperm
fi
# [Sections similaires pour ADMIN, AUDIO, GRAPH, ASR et TEST]
2. Configuration de PAM pour exécuter le script à la connexion:
# Ajout dans /etc/pam.d/common-session
session optional pam_exec.so /etc/pam.d/session-cleanup.sh
3. Création du fichier d'identifiants pour l'authentification SMB:
# /etc/smb_credentials
username=ansible
password=Azerty@123456
domain=barzini.corp
4. Déploiement via Ansible sur tous les clients:
ansible-playbook /etc/ansible/deploy_pam_smb_mounts.yml
3. Configuration côté Windows
1. Création d'un script PowerShell de mappage automatique:
# Script pour mapper automatiquement les lecteurs réseau
$GroupShareMapping = @{
"GG_DEV" = "DEV"
"GG_AUDIO" = "AUDIO"
"GG_GRAPH" = "GRAPH"
"GG_ADMIN" = "ADMIN"
"GG_TEST" = "TEST"
"GG_ASR" = "ASR"
}
# Obtenir les groupes de l'utilisateur
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$userGroups = $currentUser.Groups | ForEach-Object {
$_.Translate([System.Security.Principal.NTAccount]).Value
}
# Mapper les lecteurs en fonction des groupes
foreach ($group in $GroupShareMapping.Keys) {
$share = $GroupShareMapping[$group]
foreach ($userGroup in $userGroups) {
if ($userGroup -like "*\$group" -or $userGroup -eq $group) {
# Trouver une lettre de lecteur disponible
$driveLetter = $null
foreach ($letter in [char[]]("ZYXWVUTSRQPONMLKJIHGFEDCBA")) {
if (-not (Test-Path "${letter}:")) {
$driveLetter = "${letter}:"
break
}
}
if ($driveLetter) {
$networkPath = "\\SRV-AD-BARZINI\$share"
New-PSDrive -Name $driveLetter.TrimEnd(':') -PSProvider
FileSystem -Root $networkPath -Persist -Scope Global -ErrorAction Stop
}
break
}
}
}
2. Déploiement via GPO:
• Création d'une GPO "Mappage de lecteurs par groupe"
• Configuration du script PowerShell comme script d'ouverture de session
• Application de la GPO au domaine barzini.corp
Points clés du fonctionnement
1. Montage sélectif: Seuls les partages correspondant aux groupes de l'utilisateur sont montés
2. Montage automatique: Les montages se font automatiquement à la connexion
3. Emplacement personnalisé: Sur Linux, les montages sont dans le répertoire personnel
(~partages/)
4. Exécution privilégiée: Le script PAM s'exécute avec les droits root nécessaires pour le
montage
5. Cohérence Windows-Linux: L'expérience est similaire sur les deux plateformes
Résolution de problèmes spécifiques
1. Casse des noms de partage: Nous avons dû aligner la casse des noms (Asr vs ASR) sur
Linux
2. Appartenances aux groupes: L'utilisateur ansible a dû être ajouté à tous les groupes
(GG_*)
3. Privilèges de montage: Utilisation de PAM pour exécuter le script avec les privilèges root
4. Nettoyage des anciennes configurations: Suppression des entrées statiques dans fstab
Cette solution garantit que lorsqu'un utilisateur se connecte, il voit automatiquement les partages
correspondant à ses groupes, comme le montre votre capture d'écran pour un utilisateur du groupe
ADMIN.
________________________________________________________________________________
________________________________________________________________________________
Analyse du script PowerShell de mappage
automatique de lecteurs réseau
Ce script PowerShell est conçu pour automatiser le mappage des lecteurs réseau en fonction des
groupes auxquels appartient l'utilisateur. Examinons comment il fonctionne et ce que fait chaque
partie.
Structure générale et fonctionnement
Le script suit une logique en trois temps :
1. Définir les correspondances entre groupes et partages réseau
2. Identifier les groupes auxquels appartient l'utilisateur actuel
3. Créer des mappages de lecteurs réseau selon les appartenances aux groupes
Analysons maintenant chaque section en détail.
Analyse détaillée des éléments
1. Table de correspondance entre groupes et partages
$GroupShareMapping = @{
"GG_DEV" = "DEV"
"GG_AUDIO" = "AUDIO"
"GG_GRAPH" = "GRAPH"
"GG_ADMIN" = "ADMIN"
"GG_TEST" = "TEST"
"GG_ASR" = "ASR"
}
Cette section crée une table de hachage (hashtable) qui définit les associations entre les noms des
groupes de sécurité et les noms des partages réseau correspondants. Par exemple :
• Si l'utilisateur appartient au groupe "GG_DEV", il devrait avoir accès au partage "DEV"
• Si l'utilisateur appartient au groupe "GG_AUDIO", il devrait avoir accès au partage
"AUDIO"
• Et ainsi de suite...
Le format @{ "clé" = "valeur" } est la syntaxe PowerShell pour créer ce type de
dictionnaire, où chaque clé (nom de groupe) est associée à une valeur (nom de partage).
2. Récupération des groupes de l'utilisateur
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$userGroups = $currentUser.Groups | ForEach-Object {
$_.Translate([System.Security.Principal.NTAccount]).Value
}
Cette partie récupère les informations sur l'utilisateur actuellement connecté et ses appartenances
aux groupes :
• [System.Security.Principal.WindowsIdentity]::GetCurrent()
obtient l'identité Windows de l'utilisateur actuellement connecté
• .Groups récupère la liste des groupes auxquels appartient cet utilisateur (sous forme
d'identifiants de sécurité ou SID)
• Le ForEach-Object convertit ces identifiants techniques (SID) en noms lisibles (comme
"DOMAIN\GG_DEV")
• La méthode .Translate() effectue cette conversion de SID en nom de compte
• .Value extrait la valeur finale sous forme de chaîne de caractères
À la fin de cette section, $userGroups contient un tableau avec tous les noms des groupes
auxquels l'utilisateur appartient.
3. Mappage des lecteurs en fonction des groupes
foreach ($group in $GroupShareMapping.Keys) {
$share = $GroupShareMapping[$group]
foreach ($userGroup in $userGroups) {
if ($userGroup -like "*\$group" -or $userGroup -eq $group) {
# Trouver une lettre de lecteur disponible
$driveLetter = $null
foreach ($letter in [char[]]("ZYXWVUTSRQPONMLKJIHGFEDCBA")) {
if (-not (Test-Path "${letter}:")) {
$driveLetter = "${letter}:"
break
}
}
if ($driveLetter) {
$networkPath = "\\SRV-AD-BARZINI\$share"
New-PSDrive -Name $driveLetter.TrimEnd(':') -PSProvider
FileSystem -Root $networkPath -Persist -Scope Global -ErrorAction Stop
}
break
}
}
}
Cette boucle principale réalise le mappage en suivant plusieurs étapes :
1. Parcours des groupes définis : Le script itère sur chaque clé de la table de correspondance
($GroupShareMapping.Keys)
2. Récupération du nom de partage : Pour chaque groupe, il obtient le nom du partage
associé
3. Vérification d'appartenance : Le script vérifie si l'utilisateur appartient au groupe actuel
• La condition $userGroup -like "*\$group" gère les cas où le nom du
groupe inclut le domaine (ex: "DOMAINE\GG_DEV")
• La condition $userGroup -eq $group gère les cas où le nom est exact sans
préfixe
4. Recherche d'une lettre de lecteur disponible :
• Le script parcourt les lettres de Z à A (dans l'ordre inverse de l'alphabet)
• Pour chaque lettre, il vérifie si elle est déjà utilisée avec Test-Path
• La première lettre disponible est sélectionnée
5. Création du lecteur réseau :
• Si une lettre disponible est trouvée, le script construit le chemin réseau complet : \
\SRV-AD-BARZINI\SHARE_NAME
• New-PSDrive crée le mappage du lecteur avec les options :
• -Name : Lettre de lecteur (sans le deux-points)
• -PSProvider FileSystem : Type de lecteur (système de fichiers)
• -Root : Chemin réseau
• -Persist : Rend le mappage permanent (persistant entre les redémarrages)
• -Scope Global : Disponible dans toute la session PowerShell
• -ErrorAction Stop : Arrête l'exécution en cas d'erreur
6. Sortie de boucle : Le break arrête la recherche une fois que le groupe est trouvé et le
lecteur mappé
Explication vulgarisée
Imaginons que vous travaillez dans une grande bibliothèque avec différentes sections spécialisées
(Littérature, Sciences, Histoire, etc.) :
1. Liste d'accès : À l'entrée, il y a un tableau qui indique quelles sections sont accessibles
selon le badge que vous portez. C'est exactement ce que fait la table de correspondance
$GroupShareMapping - elle dit "si vous avez le badge GG_DEV, vous pouvez accéder à
la section DEV".
2. Vérification de vos badges : Un employé regarde tous les badges que vous portez pour
déterminer quelles sections vous sont accessibles. C'est ce que fait la partie qui récupère
$userGroups - elle identifie tous les "badges" (groupes) que possède l'utilisateur.
3. Attribution des clés : Pour chaque section à laquelle vous avez droit, l'employé doit vous
donner une clé. Mais il n'a qu'un nombre limité de porte-clés (lettres de lecteur), donc :
• Il commence par vérifier les porte-clés Z, puis Y, puis X... jusqu'à trouver un
disponible
• Une fois un porte-clé libre trouvé, il y attache la clé de la section appropriée et vous
le remet
• Sur chaque clé, il grave l'adresse complète de la section (ex: "Bâtiment SRV-AD-
BARZINI, Section DEV")
À la fin, vous avez automatiquement reçu toutes les clés des sections auxquelles vous avez droit,
sans avoir à les demander individuellement.
Points techniques supplémentaires
1. Ordre des lettres : Le script attribue les lecteurs en commençant par Z et en remontant vers
A, ce qui est une pratique courante pour éviter les conflits avec les lecteurs système (C: pour
le disque dur local, etc.).
2. Détection intelligente des noms de groupes : Le script peut reconnaître votre appartenance
à un groupe que ce soit sous la forme "GG_DEV" ou "DOMAINE\GG_DEV" grâce à
l'opérateur -like avec le motif *\$group.
3. Persistance : L'option -Persist garantit que ces lecteurs réseau seront toujours
disponibles après un redémarrage de l'ordinateur.
Ce script est particulièrement utile dans un environnement d'entreprise comme Barzini Studios, où
différentes équipes (développeurs, graphistes, audio, etc.) ont besoin d'accéder à des ressources
spécifiques sur le réseau en fonction de leur rôle.