Ansible : déléguer les droits minimaux sur contrôleurs de domaine et serveurs Exchange (sans Domain Admin)

Accordez à Ansible le strict nécessaire pour déployer, corriger et redémarrer vos contrôleurs de domaine et serveurs Exchange, sans glisser vers des privilèges Domain Admin. Voici une méthode opérationnelle, sécurisée et reproductible.

Sommaire

Vue d’ensemble de la question

Comment attribuer à un compte de service utilisé par Ansible des droits suffisants pour :

  • installer ou mettre à jour des logiciels ;
  • appliquer les correctifs Windows (WSUS/WUfB) ;
  • redémarrer proprement des serveurs,

sur des contrôleurs de domaine (DC) et des serveurs Exchange, sans élargir le périmètre jusqu’aux privilèges complets d’Administrateur du domaine ?

Réponse & solution (résumé des étapes)

ÉtapeDétails essentiels
1. Recenser les droits requisInstallation logicielle (écriture disque, création de service, arrêt/démarrage), Windows Update (configurer + lancer), Redémarrage distant (SeRemoteShutdownPrivilege pour la fermeture à distance, SeShutdownPrivilege pour la fermeture locale).
2. Créer/choisir le compteCompte utilisateur AD dédié (recommandé pour WinRM) ou gMSA si le compte sert à exécuter un service/planificateur sur les hôtes. Durcissement Kerberos (AES), rotation/mot de passe fort si non‑gMSA.
3. Délimiter la zone d’administrationPlacer DC et Exchange dans des OU dédiées (Tier 0). Filtrer GPO par cible (DC vs Exchange).
4. Déléguer côté Active DirectoryLimiter à la lecture de l’annuaire si nécessaire. Éviter toute délégation étendue. Server Operators sur DC est une option encadrée si l’organisation l’accepte ; sinon privilégier des droits de machine ciblés via GPO.
5. Accorder les privilèges locauxSur DC : user rights précis via GPO (WinRM, redémarrage). Sur Exchange : appartenance au groupe Administrators local pour l’installation/MAJ Windows uniquement, pas d’élévation AD.
6. Configurer Exchange (RBAC)Créer un Role Group dédié (ex. View-Only Configuration, Server Management). Éviter Organization Management si non requis. Scripts de maintenance DAG pré/post patch.
7. Sécuriser WinRM / PowerShell RemotingKerberos/TLS, pas de Basic/Négo, « AllowUnencrypted » = false, IP source limitée au nœud Ansible, journaux activés.
8. Tester en pré‑productionPlaybooks de pré‑vérification, patch factice, reboot contrôlé, validation des journaux (Security, System, journal d’audit Exchange).
9. Auditer et surveillerAudit avancé (4768/4769, 4672/4673, 4688), SIEM sur élévations ou accès hors IP autorisées.
10. Documenter et réviserRunbook détaillé (GPO, RBAC, groupes, scripts), revue périodique à chaque nouveau playbook/périmètre.

Principes de moindre privilège appliqués

  • Ségrégation par cible : on distingue DC (Tier 0 absolu) et serveurs Exchange (Tier 0 également, mais gérés localement via RBAC Exchange + Administrators local).
  • Droits composables : on assemble des User Rights ciblés via GPO plutôt que des rôles AD trop larges.
  • Endpoints JEA : on borne les cmdlets réellement disponibles au compte Ansible.
  • Traçabilité : chaque action sensible est journalisée et corrélée.

Cartographie des besoins techniques

Action AnsibleServeurDroits minimaux côté OSCommentaire
Installer MSI/EXEExchangeMembre du groupe local AdministratorsCréation de services, écriture sous Program Files, arrêt/démarrage.
Installer MSI/EXEDCÀ éviter. Si indispensable : droits précis + validation sécurité.Limiter aux agents approuvés ; idéalement recourir à solutions natives (GPO/DSC).
Appliquer Windows UpdateExchangeAdministrators local + accès au service wuauservCompatible WSUS/WUfB.
Appliquer Windows UpdateDCPrivilège d’administration de l’OS ou JEA avec cmdlets limitéesPréférer JEA et win_updates avec redémarrage orchestré.
Redémarrage distantDC & ExchangeSeRemoteShutdownPrivilegeIndispensable pour win_reboot. SeShutdownPrivilege suffit pour local.
Exécuter via WinRMDC & ExchangeSeNetworkLogonRight (Accès depuis le réseau)Nécessaire dans les environnements durcis où ce droit est restreint.

Création du compte de service

Option la plus simple (WinRM/Ansible) : un utilisateur AD dédié (CONTOSO\svc_ansible) avec :

  • chiffrement Kerberos AES128/256 ;
  • mot de passe long, rotation automatisée ;
  • interdiction d’ouverture de session interactive (deny log on locally) ;
  • restriction des heures et postes d’ouverture (Logon Workstations : nœud Ansible uniquement) ;
  • si délégation contrainte nécessaire : KCD (Kerberos Constrained Delegation) vers SMB/RPC.
# Création d’un compte de service utilisateur
New-ADUser `
  -Name "svc_ansible" `
  -SamAccountName "svc_ansible" `
  -Enabled $true `
  -Description "Compte de service Ansible (Tier0, WinRM)" `
  -KerberosEncryptionType AES128,AES256
# Définir un mot de passe fort (saisi à la demande) et forcer la rotation
Set-ADAccountPassword svc_ansible -Reset
Set-ADUser svc_ansible -PasswordNeverExpires $false

Quand envisager un gMSA ? Le Group‑Managed Service Account est idéal pour exécuter des services ou tâches planifiées côté Windows (avec gestion du secret par AD). Attention : un gMSA ne s’utilise pas comme identifiant/mot de passe pour une connexion WinRM depuis Ansible. Il convient si vous orchestrez, par exemple, des tâches planifiées qui s’exécutent localement avec ce gMSA.

# Pré-requis gMSA (à exécuter une seule fois dans la forêt)
Add-KdsRootKey -EffectiveImmediately

# gMSA dont seuls EX01 et DC01 peuvent récupérer le secret
New-ADServiceAccount `
  -Name "gmsa-ansible" `
  -DNSHostName "contoso.local" `
  -PrincipalsAllowedToRetrieveManagedPassword "EX01$","DC01$"

Organisation des OU et périmètre d’administration

  • Créer OU=Tier0,OU=Servers et, sous celle-ci, OU=DomainControllers et OU=Exchange.
  • Appliquer des GPO distinctes : GPO – Tier0 – DC – AnsibleRights et GPO – Tier0 – EX – AnsibleRights.
  • Utiliser un groupe de sécurité unique (ex. GG_Ansible_Tier0Ops) contenant le compte de service ; ce groupe est la cible des GPO et des membership locaux.

Délégations Active Directory

Dans un domaine par défaut, Domain Users ont déjà un read‑only suffisant pour interroger l’annuaire. N’accordez pas d’autorisations d’écriture AD inutiles. Si vos ACLs ont été durcies côté OU, vous pouvez :

  • accorder au groupe GG_Ansible_Tier0Ops le droit Read sur les OU DC/Exchange ;
  • éviter la délégation « Apply Group Policy » (inutile à Ansible) et toute délégation d’administration d’objets sensibles.

Sur DC, deux approches :

  1. Privilèges précis via GPO (recommandé) : on attribue uniquement les User Rights nécessaires (SeRemoteShutdownPrivilege, SeNetworkLogonRight, etc.).
  2. Groupe Server Operators (option encadrée) : confère des droits étendus sur DC (services, partage, arrêt). Cela reste moins que Domain Admin, mais c’est très puissant ; ne l’utiliser que si justifié et fortement surveillé.

Privilèges locaux via GPO

Créer/éditer les GPO :

  • Configuration ordinateur → Paramètres Windows → Paramètres de sécurité → Stratégies locales → Attribution des droits utilisateur

Attribuer au groupe GG_Ansible_Tier0Ops :

  • Accéder à cet ordinateur depuis le réseau (SeNetworkLogonRight) : si restreint dans votre durcissement.
  • Forcer l’arrêt à partir d’un système à distance (SeRemoteShutdownPrivilege) : nécessaire au reboot distant.
  • Ouvrir une session en tant que service (SeServiceLogonRight) : uniquement si vous exécutez un service/tâche planifiée avec ce compte.
  • Refuser l’ouverture de session locale : pour empêcher l’interactif sur DC/Exchange.

Sur les serveurs Exchange (membres), ajoutez le groupe GG_Ansible_Tier0Ops au groupe local Administrators via GPO (Restricted Groups ou Group Policy Preferences → Local Users and Groups), uniquement sur l’OU Exchange.

Exemples Ansible pour appliquer ces droits

# Inventaire minimal (Kerberos recommandé)

[dc]

dc01.contoso.local

[exchange]

ex01.contoso.local

[all:vars]

ansible_connection=winrm ansible_winrm_transport=kerberos ansible_user=CONTOSO\svc_ansible ansible_password= # ou utiliser ansible-vault ansible_winrm_server_cert_validation=validate

# Rôles système : droits utilisateur et appartenances
- name: Durcir les droits Ansible sur DC
  hosts: dc
  gather_facts: no
  tasks:
    - name: Accès depuis le réseau (si restreint)
      ansible.windows.win_user_right:
        name: SeNetworkLogonRight
        users:
          - CONTOSO\\GG_Ansible_Tier0Ops
        action: add

    - name: Autoriser l’arrêt à distance
      ansible.windows.win_user_right:
        name: SeRemoteShutdownPrivilege
        users:
          - CONTOSO\\GG_Ansible_Tier0Ops
        action: add

- name: Appartenances locales sur Exchange
  hosts: exchange
  gather_facts: no
  tasks:
    - name: Ajouter au groupe Administrators local
      ansible.windows.win_group_membership:
        name: Administrators
        members:
          - CONTOSO\\GG_Ansible_Tier0Ops
        state: present

RBAC Exchange minimal

Si Ansible doit piloter des opérations Exchange (maintenance, activation de composants…), créer un Role Group dédié :

# Exemple dans la Console Exchange Management Shell
New-RoleGroup -Name "RG-Ansible-ExchangeOps" `
  -Roles "View-Only Configuration","Server Management" `
  -Members "CONTOSO\\svc_ansible"

Éviter Organization Management qui donne un contrôle très large. Si vous devez importer/exporter des boîtes aux lettres (PST), ajouter explicitement le rôle Mailbox Import Export.

Maintenance DAG (pré/post patch)

# Pré-patch (mise hors service)
Set-ServerComponentState EX01 -Component ServerWideOffline -State Inactive -Requester Maintenance
Suspend-ClusterNode EX01
# Post-patch (remise en service)
Resume-ClusterNode EX01
Set-ServerComponentState EX01 -Component ServerWideOffline -State Active -Requester Maintenance

Intégrez ces cmdlets dans des pre_tasks/post_tasks Ansible conditionnées au rôle du serveur (membre DAG ou non).

WinRM et PowerShell Remoting sécurisés

  • Activer PSRemoting : Enable-PSRemoting -Force.
  • Kerberos/TLS uniquement : winrm set winrm/config/service/auth @{Kerberos="true";Basic="false";Negotiate="false"}.
  • Chiffrement obligatoire : winrm set winrm/config/service @{AllowUnencrypted="false"}.
  • Listener HTTPS avec certificat d’entreprise :
    winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="srv.contoso.local";CertificateThumbprint="<thumb>"}
  • Pare-feu : limiter l’entrée WinRM aux IP du nœud Ansible.
  • Comptes : interdire NTLM sur le compte Ansible, activer AES128/256, considérer KCD si « double‑saut » requis.

JEA pour limiter les cmdlets

Un endpoint JEA (Just‑Enough Administration) borne ce que le compte peut exécuter. Exemple : autoriser Restart-Computer, gestion du service Windows Update et quelques cmdlets d’observation.

# Rôle JEA minimaliste
$modulePath = "$env:ProgramFiles\WindowsPowerShell\Modules\AnsibleJEA\RoleCapabilities"
New-Item -ItemType Directory -Path $modulePath -Force | Out-Null
New-PSRoleCapabilityFile -Path "$modulePath\AnsibleOps.psrc" `
  -VisibleCmdlets @(
    'Restart-Computer',
    @{ Name='Get-Service'; Parameters=@{ Name='Name' } },
    @{ Name='Start-Service'; Parameters=@{ Name='Name' } },
    @{ Name='Stop-Service'; Parameters=@{ Name='Name' } }
  )

# Session configuration

New-PSSessionConfigurationFile -Path 'C:\ProgramData\JEA\AnsibleOps.pssc' `  -RunAsVirtualAccount`
-RoleDefinitions @{ 'CONTOSO\GG_Ansible_Tier0Ops' = @{ 'RoleCapabilities' = 'AnsibleOps' } }

Register-PSSessionConfiguration -Name 'JEA-Ansible' -Path 'C:\ProgramData\JEA\AnsibleOps.pssc' -Force 

Côté Ansible, utilisez le plugin de connexion PSRP afin de cibler ce endpoint :

[all:vars]
ansible_connection=psrp
ansible_psrp_transport=kerberos
ansible_psrp_configuration=JEA-Ansible
ansible_user=CONTOSO\\svc_ansible
ansible_password=&lt;mot_de_passe&gt;

Playbooks de référence

Vérifications préalables

- name: Pré‑checks Ansible sur DC &amp; Exchange
  hosts: dc,exchange
  gather_facts: no
  tasks:
    - name: Ping WinRM
      ansible.windows.win_ping:

```
- name: Vérifier le service Windows Update
  ansible.windows.win_service_info:
    name: wuauserv

- name: Inspecter les privilèges du jeton
  ansible.windows.win_shell: 'whoami /priv'
  register: privs
- debug:
    var: privs.stdout_lines
```

Patch + redémarrage orchestré

- name: Patcher Exchange de façon séquencée (serial=1)
  hosts: exchange
  serial: 1
  pre_tasks:
    - name: Mettre EX en maintenance (si DAG)
      ansible.windows.win_shell: |
        Set-ServerComponentState $env:COMPUTERNAME -Component ServerWideOffline -State Inactive -Requester Maintenance
      args:
        executable: powershell.exe
  tasks:
    - name: Appliquer les mises à jour de sécurité
      ansible.windows.win_updates:
        category_names:
          - SecurityUpdates
          - CriticalUpdates
        reboot: yes
        reboot_timeout: 3600

post_tasks:
- name: Sortie de maintenance
ansible.windows.win_shell: |
Set-ServerComponentState $env:COMPUTERNAME -Component ServerWideOffline -State Active -Requester Maintenance
args:
executable: powershell.exe

* name: Patcher les contrôleurs de domaine (serial=1)
  hosts: dc
  serial: 1
  tasks:

  * name: Mises à jour Windows
    ansible.windows.win_updates:
    category_names:
    - SecurityUpdates
    - CriticalUpdates
    reboot: yes
    reboot_timeout: 3600 

Tests en pré‑production

  • Jeu d’essai : machine sandbox à l’image d’un DC/Exchange (même GPO/durcissement).
  • Déploiement factice : installer un MSI inoffensif, simuler un reboot, vérifier les états de services.
  • Journalisation : Security, System, PowerShell, et Exchange Admin Audit Log.

Audit et détection

Activez l’audit avancé et surveillez :

  • Authentification Kerberos : 4768 (TGT), 4769 (TGS).
  • Utilisation de privilèges sensibles : 4672 (droits spéciaux attribués), 4673 (service sensible appelé).
  • Création de processus : 4688 avec ligne de commande (Include command line in process creation events).
  • Connexions : 4624/4625, 4648 (logon avec informations d’identification explicites).
  • Altérations risquées : 4719 (audit policy), 1102 (log effacé).

Ajoutez des alertes SIEM sur : utilisation de svc_ansible en dehors de l’IP du nœud Ansible, changements d’appartenance aux groupes Administrators/Server Operators, et exécutions de cmdlets Exchange inhabituelles.

Bonnes pratiques et garde‑fous

  • Zéro interactif : refuser l’ouverture de session locale/RDP au compte Ansible.
  • Rotation de secret : mot de passe non réutilisé, vault Ansible, expiration courte.
  • AppLocker/WDAC : liste blanche des binaires autorisés (particulièrement sur DC).
  • Éviter les installations sur DC : si inévitable, justification écrite, revue sécurité, rollback prévu.
  • Pairs de changement : patch par vagues (serial) + fenêtres de maintenance.
  • Revue périodique : droits du groupe GG_Ansible_Tier0Ops et rôles RBAC Exchange revus trimestriellement.

Foire aux pièges

  • Confusion des privilèges d’arrêt : pour redémarrer à distance, c’est SeRemoteShutdownPrivilege qu’il faut (pas seulement SeShutdownPrivilege).
  • gMSA et WinRM : un gMSA n’est pas un identifiant/mot de passe à fournir à Ansible. Il sert à exécuter localement des services/tâches.
  • Server Operators sur DC : puissant et parfois désactivé par politique interne. Préférer des droits GPO ciblés.
  • NTLM résiduel : blocage NTLM sur le compte Ansible pour éviter le downgrade et le pass‑the‑hash.
  • Double‑saut : si vos playbooks accèdent à des partages distants depuis les hôtes, prévoir KCD au lieu de CredSSP.

Modèle de runbook

  1. Périmètre : serveurs visés, fenêtre, version de patch.
  2. Pré‑checks : connectivité Kerberos, espace disque, état DAG/AD.
  3. Entrée en maintenance : Exchange (DAG), mises hors service applicatives.
  4. Patch + reboot : lot par lot (serial), délais configurés.
  5. Sortie maintenance : tests applicatifs, réactivation des composants.
  6. Validation : journaux, versions, conformité CIS/interne.
  7. Retour d’expérience : incidents, améliorations de la délégation.

Conclusion

En combinant un compte de service dédié, des droits locaux finement ciselés (GPO), un RBAC Exchange minimal, des endpoints JEA et un WinRM sécurisé, vous permettez à Ansible d’exécuter exactement ce qui est nécessaire sur DC et Exchange, sans concession excessive sur la sécurité. Le tout reste traçable, réversible et compréhensible pour les équipes d’audit.

Annexe : snippets utiles

Création d’un groupe de sécurité dédié

New-ADGroup -Name "GG_Ansible_Tier0Ops" -GroupScope Global -GroupCategory Security -Path "OU=Groups,DC=contoso,DC=local"
Add-ADGroupMember -Identity "GG_Ansible_Tier0Ops" -Members "svc_ansible"

Forcer Kerberos only + AES

Set-ADUser svc_ansible -Add @{'msDS-SupportedEncryptionTypes'= 24}  # 24 = AES128 + AES256
# Désactiver NTLM côté compte (via politiques internes / Protected Users si applicable)

Vérifier les droits effectifs de redémarrage

whoami /priv | findstr /i "SeRemoteShutdownPrivilege SeShutdownPrivilege"

Redémarrage sécurisé via Ansible

- name: Redémarrage contrôlé
  hosts: dc,exchange
  tasks:
    - name: Redémarrer et attendre le retour
      ansible.windows.win_reboot:
        reboot_timeout: 3600
        post_reboot_delay: 30
        test_command: 'powershell -command "&amp; { (Get-Service wuauserv).Status -eq ''Running'' }"'

Ce que vous gagnez : des opérations quotidiennes fluides (déploiement, patch, reboot) sur des actifs Tier 0, sans basculer vers Domain Admin, avec une surface d’attaque maîtrisée et un excellent niveau de traçabilité.

Sommaire