TL;DR:
Quick-howto sans explications pour effectuer le déploiement d'un environnement AD minimal pour des tests, constitué de VMs: 3 Domain Controllers, une forêt, 3 domaines, une machine windows, une machine Linux.
Concepts:
Active Directory, forêts, domain, join domain.
Outils:
Windows Server, PowerShell, Ubuntu.
On dispose d'un homelab faisant tourner des machines virtuelles KVM/libvirt (QEMU).
Les templates ont été créés selon cette procédure.
Les 5 VM suivantes sont créées par clonage à partir des templates, puis démarrées:
lab_dc1.lab.local: un contrôleur de domaine pour le domaine lab.local.
lab_dc2.amchit.lab.local: un contrôleur de domaine pour le domaine amchit.lab.local.
lab_dc3.jounieh.lab.local: un contrôleur de domaine pour le domaine jounieh.lab.local.
lab_batroun.lab.local: un serveur Windows qui sera membre du domaine lab.local.
lab_cedar.lab.local: un serveur Linux qui sera membre du domaine lab.local.
Par commodité je nomme les VM avec le fqdn qui leur sera attribué, en ajoutant juste le préfixe "lab_" devant pour les regrouper dans la liste car virt-manager a une interface très rudimentaire.
amchit.lab.local et jounieh.lab.local sont deux domaines de la forêt lab.local:
Plan d'adressage:
| serveur | IP |
|---|---|
| dc1.lab.local | 192.168.122.101 |
| dc2.amchit.lab.local | 192.168.122.102 |
| dc3.jounieh.lab.local | 192.168.122.103 |
| batroun.lab.local | 192.168.122.104 |
| cedar.lab.local | 192.168.122.105 |
La procédure qui suit consiste à déployer tout ça.
Ajouter les adresses ip dans /etc/hosts sur l'hôte:
# Lab AD
192.168.122.101 dc1 lab dc1.lab.local
192.168.122.102 dc2 amchit dc2.amchit.lab.local
192.168.122.103 dc3 jounieh dc3.jounieh.lab.local
192.168.122.104 batroun batroun.lab.local
192.168.122.105 cedar cedar.lab.local
Dans une session PowerShell, appliquer la conf IP souhaitée:
PS> New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.122.101 -PrefixLength 24 -DefaultGateway 192.168.122.1
PS> Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 192.168.122.1
PS> Rename-Computer -NewName "dc1" -Restart
Le serveur redémarre et le certificat RDP change.
Après le reboot, configurer le domaine:
PS> Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
PS> Install-ADDSForest -DomainName "lab.local" -DomainNetbiosName "LAB" -InstallDNS:$true -Force
SafeModeAdministratorPassword: *********
Confirm SafeModeAdministratorPassword: *********
Le serveur redémarre et le certificat RDP change une nouvelle fois.
Après le reboot, vérifier:
PS> Get-ADForest
PS> Get-ADDomain
PS> nslookup lab.local
Dans une session PowerShell, appliquer la conf IP souhaitée:
PS> New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.122.102 -PrefixLength 24 -DefaultGateway 192.168.122.1
PS> Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 192.168.122.101
PS> Rename-Computer -NewName "dc2" -Restart
Attention:
Ici on met l'adresse du contrôleur de domaine dc1 comme DNS (le serveur doit pouvoir localiser la forêt existante, et donc utiliser temporairement le DNS du premier DC).
Le serveur redémarre et le certificat RDP change.
Après le reboot, configurer le domaine:
PS> Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
PS> $cred = Get-Credential
PS> Install-ADDSDomain -NewDomainName "amchit" -ParentDomainName "lab.local" -DomainType ChildDomain -InstallDNS:$true -Credential $cred -Force
SafeModeAdministratorPassword: *********
Confirm SafeModeAdministratorPassword: *********
Le serveur redémarre et le certificat RDP change une nouvelle fois.
Vérifications après le reboot:
PS> Get-ADForest
PS> Get-ADDomain
PS> repadmin /replsummary
PS> repadmin /showrepl
PS> dcdiag /test:dns
PS> nslookup lab.local
PS> nslookup amchit.lab.local
Dans une session PowerShell, appliquer la conf IP souhaitée:
PS> New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.122.103 -PrefixLength 24 -DefaultGateway 192.168.122.1
PS> Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 192.168.122.101
PS> Rename-Computer -NewName "dc3" -Restart
Attention:
Ici on met l'adresse du contrôleur de domaine dc1 comme DNS.
Le serveur redémarre et le certificat RDP change.
Après le reboot, configurer le domaine:
PS> Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
PS> $cred = Get-Credential
PS> Install-ADDSDomain -NewDomainName "jounieh" -ParentDomainName "lab.local" -DomainType ChildDomain -InstallDNS:$true -Credential $cred -Force
SafeModeAdministratorPassword: *********
Confirm SafeModeAdministratorPassword: *********
Le serveur redémarre et le certificat RDP change une nouvelle fois.
Vérifications après le reboot:
PS> Get-ADForest
PS> Get-ADDomain
PS> repadmin /replsummary
PS> repadmin /showrepl
PS> dcdiag /test:dns
PS> nslookup lab.local
PS> nslookup jounieh.lab.local
Cette machine Windows Server va être membre du domaine lab.local (dc1).
Ouvrir une session powershell:
PS> Rename-Computer -NewName "batroun" -Restart
PS> New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.122.104 -PrefixLength 24 -DefaultGateway 192.168.122.1
PS> Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 192.168.122.101
PS> $Domain = "lab.local"
PS> $User = "LAB\Administrator"
PS> $Pass = ConvertTo-SecureString "<mot_de_passe>" -AsPlainText -Force
PS> $Cred = New-Object System.Management.Automation.PSCredential($User, $Pass)
PS> Add-Computer -DomainName $Domain -Credential $Cred -Restart
Remplacer <mot_de_passe> par le vrai mot de passe :-)
Cet exemple montre une autre façon de renseigner l'objet $Cred, de manière non-interactive, mais devant en contrepartie faire figurer un mot de passe en clair dans une commande.
Vérification:
Sur la DSA du domain controller: la machine cliente est enregistrée
Sur la machine cliente, se connecter en tant que lab\administrator.
PS C:\Users\Administrator.LAB> whoami
lab\administrator
Cette machine Linux va aussi être membre du domaine lab.local (dc1).
Sur un Linux récent, la méthode recommandée consiste à utiliser sssd (realmd, Kerberos). Winbind est toujours supporté, mais il est plutôt réservé aux besoins Samba avancés (serveur de fichiers, contrôleur de domaine, etc.).
Ouvrir une session SSH:
# resolvectl status
==> Le serveur doit utiliser le(s) serveur(s) DNS du domaine AD à joindre (dans le cadre du homelab = le domain controller dc1). Si ce n'est pas le cas, modifier et appliquer la configuration DNS cliente.
# apt update
# apt install realmd sssd sssd-tools libnss-sss libpam-sss adcli samba-common-bin oddjob oddjob-mkhomedir packagekit krb5-user
Lors de l'installation de krb5-user, une tui demande le nom du realm pour l'authent Kerberos. Je mets le nom de mon domaine AD: lab.local. (Sinon realmd le renseignera plus tard)
Ensuite, la tui demande les serveurs associés au realm. Je mets le nom de mon DC: dc1.
Vérifier que le domaine est détecté:
# realm discover lab.local
lab.local
type: kerberos
realm-name: LAB.LOCAL
domain-name: lab.local
configured: no
server-software: active-directory
client-software: sssd
required-package: sssd-tools
required-package: sssd
required-package: libnss-sss
required-package: libpam-sss
required-package: adcli
required-package: samba-common-bin
Vérifier que le temps est bien synchronisé:
# timedatectl status
Joindre le domaine:
# realm join lab.local -U Administrator
C'est un lab, hein. On est bien d'accord qu'il faut utiliser un autre compte pour ça.
Vérifier sur la DSA du domain controller que la machine cliente est bien enregistrée:
Vérifier depuis la machine Linux:
# realm list
lab.local
type: kerberos
realm-name: LAB.LOCAL
domain-name: lab.local
configured: kerberos-member
server-software: active-directory
client-software: sssd
required-package: sssd-tools
required-package: sssd
required-package: libnss-sss
required-package: libpam-sss
required-package: adcli
required-package: samba-common-bin
login-formats: %U@lab.local
login-policy: allow-realm-logins
Check authent Kerberos:
# klist
# kinit utilisateur@lab.local
# klist
Vérification SSSD:
# id utilisateur
# getent passwd utilisateur
# getent group "Domain Users"
Pour autoriser des utilisateurs à se connecter:
# realm permit --all
# realm permit user1 user2
# realm permit -g LinuxAdmins
Pour activer la création automatique du homedir:
# pam-auth-update --enable mkhomedir
Fichier de conf et logs:
# vi /etc/sssd/sssd.conf
# journalctl -u sssd
Pour quitter le domaine (au cas où):
# realm leave lab.local
Voici une méthode minimale, rapide et sale pour remplir un domaine AD avec des données de test bidon (comptes utilisateurs et groupes).
Import-Module ActiveDirectory
New-ADOrganizationalUnit -Name "Fake" -Path (Get-ADDomain).DistinguishedName
# Récupération du domaine courant
$domain = (Get-ADDomain).DnsRoot
# Listes de noms/prénoms fictifs
$prenoms = @(
"Alice","Bob","Charlie","David","Emma","Frank","Grace","Hugo","Isabelle","Jack",
"Karen","Leo","Mona","Nicolas","Olivia","Paul","Quentin","Rita","Sophie","Thomas",
"Ursula","Victor","Wendy","Xavier","Yasmine","Zoe"
)
$noms = @(
"Martin","Dupont","Durand","Bernard","Petit","Robert","Richard","Moreau","Simon","Laurent",
"Lefebvre","Michel","Garcia","David","Bertrand","Roux","Vincent","Fournier","Morel","Girard",
"Andre","Lefevre","Mercier","Blanc","Guerin","Muller"
)
# Listes de noms/prénoms fictifs internationaux
$prenomsIntl = @(
"John","Michael","Sophia","Daniel","Emily","Carlos","Maria","Hiroshi","Akira","Mei",
"Wei","Ananya","Raj","Aisha","Fatima","Omar","Amir","Elena","Ivan","Svetlana",
"Giulia","Luca","Pablo","Diego","Santiago","Alejandro","Marta","Andreas","Greta","Hans",
"Ingrid","Bjorn","Sofia","Mateusz","Katarzyna","Jakub","Esra","Selim","Leila","Nadia",
"Sergey","Olga","Petra","Zoltan","Marek","Tomas","Jan","Krzysztof","Hanna","Yuki"
)
$nomsIntl = @(
"Smith","Johnson","Williams","Brown","Taylor","Wilson","Lopez","Gonzalez","Martinez","Rodriguez",
"Kumar","Singh","Patel","Gupta","Sharma","Hernandez","Torres","Silva","Costa","Ferreira",
"Müller","Schmidt","Schneider","Fischer","Weber","Novak","Horvat","Ivic","Popov","Ivanov",
"Petrov","Sokolov","Kuznetsov","Volkov","Andersen","Hansen","Nielsen","Olsen","Johansson","Karlsson",
"Svensson","Lindberg","Virtanen","Korhonen","Nieminen","Papadopoulos","Georgiou","Haddad","Khalil","Aziz"
)
$prenoms = $prenoms + $prenomsIntl
$noms = $noms + $nomsIntl
# Génération de 100 couples prénom/nom
$users = @()
for ($i=1; $i -le 100; $i++) {
$prenom = Get-Random $prenoms
$nom = Get-Random $noms
$users += [PSCustomObject]@{
Prenom = $prenom
Nom = $nom
}
}
# Création des utilisateurs
foreach ($u in $users) {
$sam = ($u.Nom + $u.Prenom.Substring(0,1)).ToUpper()
$upn = ($u.Prenom + "." + $u.Nom + "@" + $domain).ToLower()
$pwd = ConvertTo-SecureString "LabPassword123!" -AsPlainText -Force
$name = "$($u.Prenom) $($u.Nom)"
try {
New-ADUser `
-Name $name `
-GivenName $u.Prenom `
-Surname $u.Nom `
-SamAccountName $sam `
-UserPrincipalName $upn `
-AccountPassword $pwd `
-Office "fake" `
-Path "OU=Fake,$((Get-ADDomain).DistinguishedName)" `
-PasswordNeverExpires $true `
-Enabled $true
Write-Host "Created user $name ($sam)"
}
catch {
Write-Warning "Failed to create user $name : $_"
}
}
# Noms de groupes
$groupNames = @(
"App_CRM_Users",
"App_ERP_Administrators",
"App_Intranet_Editors",
"Service_Finance",
"Service_RH",
"Service_IT_Support",
"Service_Production",
"Service_Marketing",
"App_Mail_Distribution",
"App_Tickets_Access",
"App_BI_Analysts",
"Service_Compliance",
"Service_Logistique",
"App_DevOps_Pipeline",
"App_VPN_Users"
)
# Création des groupes
$groupes = @()
foreach ($gname in $groupNames) {
try {
New-ADGroup -Name $gname -GroupScope Global -GroupCategory Security -Path "OU=Fake,$((Get-ADDomain).DistinguishedName)"
$groupes += $gname
Write-Host "Created group $gname"
}
catch {
Write-Warning "Failed to create group $gname : $_"
}
}
# Répartition aléatoire des comptes dans les groupes
foreach ($u in $users) {
$sam = ($u.Nom + $u.Prenom.Substring(0,1)).ToUpper()
$grp = Get-Random $groupes
try {
Add-ADGroupMember -Identity $grp -Members $sam
Write-Host "Added $sam to $grp"
}
catch {
Write-Warning "Failed to add $sam to $grp : $_"
}
}
Et voilà le travail: l'annuaire AD est rempli en 30 secondes avec des données de test basiques.
--
TG - 07/2026