Après une migration vers Windows Server 2022, vos scripts refusent soudain d’exécuter sc \\monserveur start/stop
? Cette analyse détaillée explique la cause exacte (contrôle SCM post‑1709) et présente plusieurs stratégies — dont la plus sûre via RemoteAccessCheckExemptionList
— pour rétablir la délégation tout en conservant le principe du moindre privilège.
Impossible de lancer ou arrêter un service à distance : symptôme et contexte
Dans de nombreuses entreprises, les équipes d’exploitation ou d’application utilisent un compte de service restreint pour piloter le cycle de vie d’un service Windows hébergé sur un autre serveur. Historiquement, il suffisait de :
sc \\srv-app-01 stop MonService
sc \\srv-app-01 start MonService
À partir de Windows 10 1709 / Windows Server 2016 1709, puis nativement dans Windows Server 2022, la même commande renvoie désormais :
OpenService FAILED 5: Access is denied.
Pourtant :
- L’ACL (SDDL) du service octroie toujours SERVICE_START et SERVICE_STOP au groupe délégué.
- La requête
sc \\srv-app-01 query MonService
fonctionne — la lecture n’est pas bloquée. - Un administrateur local, lui, peut toujours démarrer/arrêter le service à distance.
Pourquoi cela fonctionne-t-il en local mais pas à distance ?
Depuis la build 1709, le gestionnaire de contrôle de services (SCM) applique un double contrôle pour toute opération démarrer/arrêter/pause/continue/change config venant d’un ordinateur distant :
- Vérification classique des droits : l’ACL SDDL du service doit contenir les bits SERVICE_START, SERVICE_STOP, SERVICE_PAUSE_CONTINUE, etc.
- Vérification additionnelle “Remote Admin” : l’appelant doit appartenir au groupe Administrateurs locaux du serveur cible, sauf s’il figure dans une liste d’exemptions.
Autrement dit, même si le SID de votre compte service possède déjà RPWP
(ReadProperties / WriteProperties) et les droits spéciaux, le SCM refuse l’appel distant si le second contrôle échoue. Les méthodes locales — session RDP, console ou script exécuté sur le serveur — ne déclenchent pas la vérification, car elles ne sont pas considérées comme “distant call”.
Objectif de Microsoft
Cette mesure vise à réduire la surface d’attaque : sans elle, un attaquant parvenant à modifier l’ACL d’un service (ou à deviner qu’un compte y est déjà autorisé) peut arrêter ou remplacer le binaire d’un service critique à travers le réseau, puis le relancer et exécuter du code avec des privilèges SYSTEM. L’exigence “Administrateur local” force l’attaquant à disposer d’un second niveau d’accès plus élevé, rendant l’exploitation beaucoup plus complexe.
Log d’audit et diagnostic rapide
Source | Événement | Signification |
---|---|---|
Security.evtx | 4656 / 4663 | Ouverture d’un descripteur et accès refusé |
System.evtx | 7045 | Création ou modification de service (lors du redémarrage) |
Operational → Service Control Manager | 1 à 13 | Détails sur les requêtes SCM, souvent “Caller is not a local admin” |
Vérifiez que l’ID d’utilisateur dans ces journaux correspond bien au compte non‑admin utilisé par vos scripts. Le couple Status 5 (Access denied)
+ SC_STATUS_REMOTE_ACCESS_NOT_PERMITTED
confirme le scénario.
Quatre méthodes pour contourner ou neutraliser ce contrôle
La matrice ci‑dessous résume les options. Choisissez la plus adaptée à votre modèle de menace :
Option | Principe | Impact sécurité | Redémarrage requis ? |
---|---|---|---|
1. Ajouter le groupe aux Administrateurs locaux | Aucune modification du registre. On se contente d’inscrire le groupe délégué dans Administrators ou dans GPO “Restricted Groups”. | Très permissif : donne tous les droits locaux, pas seulement le contrôle des services. | Non |
2. Exempter chaque service concerné (clé RemoteAccessCheckExemptionList ) | Liste blanche : le SCM ignore la double vérification pour les services explicitement nommés. | Granulaire et recommandé : seuls les services listés sont pilotables. | Oui (ou redémarrage du service lanmanserver ) |
3. Désactiver globalement le contrôle (DWORD RemoteAccessExemption = 1 ) | Revient au comportement pré‑1709, pour tous les services. | Augmentation de surface d’attaque. À réserver aux environnements contrôlés (lab). | Oui |
4. Tout exécuter localement via RDP, WinRM ou tâches planifiées | Le compte non‑admin continue d’utiliser ses droits SDDL, mais sans passer par l’accès RPC/SCM distant. | Protection inchangée, mais perte d’automatisation centralisée. | Non |
Méthode conseillée : RemoteAccessCheckExemptionList
Cette approche offre le meilleur compromis « principe du moindre privilège / simplicité ». Vous inscrivez uniquement les services nécessaires, et rien d’autre. Exemple complet :
1. Créer la clé par défaut
reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM /f
2. Définir la valeur multi‑chaîne
Chaque service est indiqué par son nom court (celui renvoyé par sc qc
).
reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurePipeServers\SCM ^
/v RemoteAccessCheckExemptionList /t REG_MULTI_SZ ^
/d "MonService\0NomCourt2\0NomCourt3" /f
Le séparateur est le caractère \0
(Null). Vous pouvez également éditer grâce à regedit.exe
: saisissez chaque service sur une ligne distincte dans la zone de texte.
3. Redémarrer le serveur ou le service “Serveur”
La modification est lue au démarrage du service lanmanserver
, d’où la nécessité d’un redémarrage ou d’un simple :
net stop lanmanserver && net start lanmanserver
Attention, stopper lanmanserver
provoque la coupure temporaire des partages SMB — planifiez l’opération.
4. Tester et auditer
sc \\srv-app-01 stop MonService
sc \\srv-app-01 start MonService
Résultat attendu : zéro erreur. Surveillez toutefois les logs Security pour confirmer que l’accès est autorisé et qu’aucune autre alerte 4663 n’apparaît.
Maintenir des ACL SDDL strictes
L’exemption n’enlève pas la nécessité de configurer correctement le descripteur de sécurité du service. Le langage SDDL permet de définir quatre parties (Owner + Group + DACL + SACL). Exemple minimaliste :
D:A;(<abbr title="Type ACE: Allow">A;;CCLCSWRPWPDTLOCRRC;;;SID_AppGroup)
Signification :
A
: ACE de type Allow- Masque d’accès :
CC LC SW RP WP DT LO CR RC
(gère le service mais pas sa configuration) SID_AppGroup
: SID du groupe délégué
Modifiez ces droits via sc sdset
, GPO « System Services » ou l’onglet “Sécurité” de Process Explorer. Conservez toujours :
- Une SACL pour auditer les tentatives d’accès.
- Le groupe
SYSTEM
etAdministrators
avec droits complets (F
).
Automatiser avec PowerShell + JEA
Si l’on veut éviter l’ouverture de ports RPC/SCM ou la gestion de clés registre, la Just Enough Administration est une excellente alternative :
- Créer un endpoint PowerShell restreint (
Register-PSSessionConfiguration
). - Autoriser uniquement les cmdlets
Restart-Service
,Start-Service
,Stop-Service
. - Associer un rôle basé sur le groupe AD de vos opérateurs.
L’appel se fait ensuite en PowerShell :
Invoke-Command -ComputerName srv-app-01 -ConfigurationName ServiceOps `
-ScriptBlock { Restart-Service MonService }
Le compte d’appel reste non‑admin, le transport est chiffré (WinRM+Kerberos) et chaque action est tracée dans les journaux PowerShell.
Configurer le pare‑feu pour limiter la surface réseau
Par défaut, ouvrir le contrôle de service à distance requiert :
- TCP 135 (Endpoint Mapper)
- Plage RPC dynamique TCP 49152‑65535
Si vous utilisez la méthode “exemption” ou un accès complet, appliquez une règle de pare‑feu Inbound qui :
- N’autorise que les serveurs d’orchestration (Runbooks, outils de déploiement, etc.).
- N’autorise que le protocole RPC (programme n° 135) plutôt que Any.
- Est journalisée pour détecter les balayages non autorisés.
Comparatif rapide : Server 2016 vs 2022
Fonction | Server 2016 RTM | Server 2016/2019 1709+ | Server 2022 |
---|---|---|---|
Exemption par service | Absent | Présent après correctif KB4039384 | Présent |
DWORD RemoteAccessExemption | Absent | Présent | Présent (valeur 0 par défaut) |
Audit explicite “Caller not local admin” | Non | Oui (event 18 / Service Control Manager) | Oui |
Procédure de secours en cas de panne de production
- Basculer le service sous surveillance HA ou load‑balancer pour éviter l’interruption.
- Activer
RemoteAccessExemption = 1
temporairement si une automatisation critique dépend du démarrage à distance. - Adapter les scripts pour utiliser PowerShell Remoting local et désactiver
RemoteAccessExemption
dès que l’exemption ciblée est en place. - Documenter le changement dans la CMDB et planifier une revue sécurité.
Questions fréquentes (FAQ)
Mon service n’apparaît pas dans l’événement 4663. Pourquoi ?
La SACL de votre service n’inclut peut‑être pas le Success Audit ni Failure Audit. Ajoutez une ACE SACL : S:(AU;SAFA;;;WD)
par exemple.
Puis-je forcer l’ancienne méthode à l’aide d’une GPO ?
Oui. GPO → Configuration Ordinateur → Préférences → Paramètres Registre. Déployez RemoteAccessExemption = 1
. N’oubliez pas le risque associé.
Les services gérés par le cluster Windows Failover (WFC) sont‑ils affectés ?
Non. Le moteur de cluster utilise des canaux RPC authentifiés en tant que compte NT AUTHORITY\SYSTEM
, déjà administrateur local. Le contrôle n’interfère pas.
Que se passe‑t‑il si je supprime la valeur RemoteAccessCheckExemptionList
?
Le SCM la recrée automatiquement lors d’un update majeur, mais vide. Les comptes non‑admins perdront donc à nouveau l’accès distant.
Bonnes pratiques de durcissement complémentaires
- Activer Credential Guard ou LSA Protection pour réduire les risques de pass‑the‑hash sur le serveur hébergeant le service.
- Mettre en place des alertes SIEM sur la chaîne d’événements 4656/4663/7045 pour détecter les tentatives d’arrêt non autorisées.
- Utiliser des comptes de service gMSA plutôt que des mots de passe statiques.
- Automatiser les tests unitaires post‑patch : chaque Patch Tuesday, un pipeline CI exécute
sc
ouRestart-Service
pour valider la délégation.
Conclusion
Le blocage “Access is denied” rencontré après une montée de version vers Windows Server 2022 n’est pas un bug mais le résultat d’un durcissement volontaire du gestionnaire de services. Plutôt que de céder à la solution radicale consistant à promouvoir vos opérateurs en administrateurs locaux, préférez l’exemption fine offerte par la clé RemoteAccessCheckExemptionList
ou migrez vos scripts vers PowerShell + JEA. Vous conserverez un contrôle granulaire, limiterez l’exposition réseau et répondrez aux standards de conformité (ISO 27001, CIS Benchmark) sans compromettre l’automatisation de vos processus DevOps.