23/11/2024

PowerShell

Comment configurer PowerShell Just Enough Administration ?

I. Présentation

La fonctionnalité PowerShell Just Enough Administration (JEA) est disponible depuis la version 5.0 de PowerShell. Dans ce tutoriel, je vous propose de découvrir comment mettre en œuvre la fonctionnalité JEA pour déléguer l'accès à certaines tâches d'administration à des utilisateurs qui ne sont pas administrateurs.

🎥 Tutoriel disponible au format vidéo :

Grâce à PowerShell Just Enough Administration, nous allons gagner en flexibilité dans la gestion des sessions PowerShell. Avec JEA, vous pouvez autoriser un utilisateur à effectuer une tâche spécifique sur un serveur, au travers de PowerShell et d'une session distante, sans qu'il soit administrateur du serveur ou du service cible.

Concrètement, on peut définir précisément quelles sont les commandes qu'un utilisateur peut exécuter ou non sur une machine au travers d'une session distante. Indépendamment du fait qu'il soit administrateur ou non de cette même machine. Par exemple, vous pouvez autoriser un utilisateur à redémarrer uniquement le service "DHCP" de votre serveur (ou votre serveur web "IIS"), mais aucun autre service (DNS, NTDS, etc...).

En bref, avec PowerShell JEA, on peut :

  • Réduire le nombre de personnes qui sont réellement "administrateur" d'un serveur
  • Limiter les actions réalisables par les utilisateurs sur un serveur grâce à des règles
  • Tracer les actions des utilisateurs par l'intermédiaire de la transcription (chaque commande exécutée sera consignée dans un fichier)

II. Comment implémenter PowerShell JEA ?

PowerShell Just Enough Administration est intégré à Windows 10 et à Windows Server 2016 (et versions supérieures), car il est inclus dans PowerShell 5.0. Cette version de PowerShell est native sur ces OS.

Pour les versions plus anciennes de Windows Server, à savoir Windows Server 2008 R2, Windows Server 2012 et Windows Server 2012 R2, il faudra passer sur PowerShell 5.0. Pour cela, l'installation de Windows Management Framework 5.0 (au minimum) est obligatoire.

Sur la machine à administrer, vous devez autoriser la gestion à distance (WinRM) pour permettre la connexion à distance avec PowerShell (Enter-PSSession).

Ensuite, PowerShell JEA ne demande qu'une chose : être utilisé, alors à vous de jouer !

III. Créer un fichier de configuration de session (PSSC)

Au fait qu'allons-nous mettre en place comme configuration PowerShel JEA ?

L'idée, c'est de créer une configuration sur notre serveur SRV-ADDS-01 pour permettre aux membres du groupe Active Directory "Support-IT" d'exécuter quelques commandes pour gérer le service DHCP. En effet, ce serveur est un contrôleur de domaine, mais c'est également un serveur DHCP. Les membres du groupe "Support-IT" doivent pouvoir redémarrer le service DHCP, redémarrer le serveur (sait-on jamais... en dernier recours), lister les services actifs sur le serveur et réaliser un ping à partir de ce serveur.

À la fin, nous allons tester la configuration depuis machine distante sous Windows 10 nommée "PC-W10-01".

Bon, le décor est planté, on va attaquer la configuration... Ouvrez une console Powershell en tant qu'administrateur sur votre serveur.

La première étape consiste à créer un fichier pour la configuration de notre session.

Ce fichier sera nommé "SRV-ADDS-01-Manage.pssc". L'extension PSSC correspond à PowerShell Session Configuration. On utilise le cmdlet prévu à cet effet : New-PSSessionConfigurationFile.

New-PSSessionConfigurationFile -Path 'C:\Program Files\WindowsPowerShell\SRV-ADDS-01-Manage.pssc'

Sans quitter la console PowerShell, on va éditer le fichier que l'on vient de créer.

notepad.exe 'C:\Program Files\WindowsPowerShell\SRV-ADDS-01-Manage.pssc'

On se rend compte qu'il n'est pas vide ! C'est un template que nous allons modifier à notre sauce.

PowerShell JEA - Exemple de fichier PSSC (PowerShell Session Configuration File)
PowerShell JEA - Exemple de fichier PSSC (PowerShell Session Configuration File)

Il y a quatre paramètres qui m'intéressent particulièrement :

- SessionType

Nous allons remplacer la valeur "Default" par "RestrictedRemoteServer". C'est recommandé par Microsoft (et moi aussi !), car cela va restreindre directement les commandes accessibles.

SessionType = 'RestrictedRemoteServer'

Avec ce mode, l'utilisateur peut utiliser seulement les commandes suivantes :

  • Clear-Host
  • Exit-PSSession
  • Get-Command
  • Get-FormatData
  • Get-Help
  • Measure-Object
  • Out-Default
  • Select-Object

Des commandes pratiques, non dangereuses, tout va bien !

- TranscriptDirectory

Chaque session distante aura son propre journal de transcription. Ces fichiers de transcription doivent être stockés dans un dossier : précisez le chemin de ce dossier et pensez à le créer.

TranscriptDirectory = 'C:\Scripting\Transcripts\'

- RunAsVirtualAccount

Lorsque cette option est à $true (vrai), l'utilisateur bénéficie d'un compte virtuel qui est administrateur local du serveur. Autrement dit, les actions que l'utilisateur va exécuter seront effectuées avec des droits "admin" sur le serveur même si lui n'est pas administrateur du serveur.

RunAsVirtualAccount = $true

Si votre utilisateur va exécuter des actions sur le serveur distant qui ne nécessite pas des droits d'administration complets, il y a une option complémentaire à définir : RunAsVirtualAccountGroups. Elle sert à spécifier un ou plusieurs groupes locaux (et seulement locaux) auxquels doit appartenir l'utilisateur. Un état intermédiaire pour être administrateur d'un service spécifique. Par exemple :

RunAsVirtualAccount = $true 
RunAsVirtualAccountGroups = 'NetworkOperator', 'NetworkAuditor'

Pour accéder à des ressources situées sur le réseau, il faut utiliser une autre directive et spécifier un gMSA : GroupManagedServiceAccount. Néanmoins, c'est à utiliser seulement lorsque c'est indispensable, car la traçabilité devient plus complexe étant donné que le compte peut avoir accès à des ressources du réseau. Par exemple :

GroupManagedServiceAccount = 'IT-Connect\GMSA-JEA'

Dans cet exemple, nous resterons sur l'utilisation standard avec "RunAsVirtualAccount = $true".

- RoleDefinitions

Nous allons préciser le groupe de sécurité Active Directory qui est autorisé à utiliser cette session, puis le nom du rôle associé. En fait, nous verrons que le rôle contient la liste des actions autorisées, notamment les commandes PowerShell que peut exécuter l'utilisateur.

Pour ma part, je déclare le groupe "it-connect.local\Support-IT" et je l'associe au rôle "Support-IT_Manage". Puisque ce groupe doit pouvoir gérer le service DHCP, j'aurais pu choisir un nom un peu plus parlant comme "DHCP_Admins". Mais bon, restons sur "Support-IT_Manage".

RoleDefinitions = @{ 'it-connect.local\Support-IT' = @{ RoleCapabilities = 'Support-IT_Manage' }}

En complément, dans la configuration vous pouvez modifier le champ "Author" pour indiquer votre nom.

Note : lorsque cela est nécessaire, pensez à décommenter les lignes à activer, c'est-à-dire supprimer le "#" en début de ligne. Sinon, la ligne sera ignorée.

L'édition du fichier de configuration est terminée. Sauvegardez puis exécutez la commande ci-dessous. Cette commande va permettre de vérifier la syntaxe de notre fichier : s'il y a une erreur, autant le savoir maintenant.

Test-PSSessionConfigurationFile 'C:\Program Files\WindowsPowerShell\SRV-ADDS-01-Manage.pssc'

Si la commande retourne "True", c'est tout bon !

Ressource complémentaire : Doc Microsoft

IV. Créer un fichier pour la configuration du rôle (PSRC)

Dans notre fichier de configuration de la session, nous avons déclaré le rôle "Support-IT_Manage", mais elle n'a pas encore de configuration. Pas de panique, on s'en occupe maintenant.

Commencez par créer un dossier "RoleCapabilities" sur votre serveur pour stocker l'ensemble des fichiers de configuration de vos rôles.

New-Item -Path 'C:\Program Files\WindowsPowerShell\Modules\JEA\RoleCapabilities' -ItemType Directory

Le dossier étant créé, on va créer notre fichier "Support-IT_Manage.psrc" tout en sachant que l'extension PSRC correspond à PowerShell Session Role Capabilities. Ce fichier doit être nommé de la même façon que le rôle, c'est impératif.

Là encore, on utilise un cmdlet spécifique pour créer ce fichier dans le but d'obtenir un template : New-PSRoleCapabilityFile.

New-PSRoleCapabilityFile -Path 'C:\Program Files\WindowsPowerShell\Modules\JEA\RoleCapabilities\Support-IT_Manage.psrc'

On le modifie avec notepad :

notepad.exe 'C:\Program Files\WindowsPowerShell\Modules\JEA\RoleCapabilities\Support-IT_Manage.psrc'

Dans ce fichier, nous pouvons déclarer différents types d'éléments pour les autoriser : commandes PowerShell, outils externes (exécutables), fonctions, alias, modules, etc.

Pour déclarer les commandes PowerShell autorisées, nous allons devoir configurer l'option "VisibleCmdlets". Il y a plusieurs façons de renseigner cette option :

  • Préciser le nom d'une commande, par exemple "Get-Service", sans rien d'autre, l'utilisateur peut exécuter cette commande sans restriction, c'est-à-dire en utilisant tous les paramètres de cette commande
  • Préciser le nom d'une commande ainsi que les valeurs autorisées pour un ou plusieurs paramètres de cette commande

Pour rappel, nous souhaitons que les membres du groupe "Support-IT" soient autorisés à exécuter les actions ci-dessous (avec en prime la commande correspondante) :

  • Redémarrer le service DHCP
Restart-Service -Name DHCPServer
  • Redémarrer le serveur
Restart-Computer
  • Lister les services actifs sur le serveur
Get-Service
  • Réaliser un ping à partir de ce serveur.
ping

Il faut donc que l'on autorise les cmdlets "Restart-Computer" et "Get-Service", sans réelle restriction. Ensuite, il faut que l'on permette à l'utilisateur de redémarrer le service "DHCPServer" et seulement celui-ci !

Du coup, la commande PowerShell à autoriser est :

Restart-Service -Name DHCPServer

Au sein de la configuration, voici comment nous allons transposer cette commande :

@{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'DHCPServer' }}

On précise que l'on accepte seulement "DHCPServer" comme valeur pour le paramètre "-Name". Si l'on veut autoriser plusieurs valeurs, voici la syntaxe (pour autoriser aussi la valeur "NTDS") :

@{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'DHCPServer', 'NTDS'}}

Au final, voici la ligne complète pour autoriser les trois cmdlets :

VisibleCmdlets = 'Restart-Computer', @{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'DHCPServer' }}, Get-Service

Pour autoriser le "ping" (car oui il est bloqué lui aussi même si c'est une commande basique !), il faut configurer l'option "VisibleExternalCommands". On précise tout simplement le chemin complet vers "ping.exe", ce qui donne :

VisibleExternalCommands = 'C:\Windows\System32\ping.exe'

Notre fichier de configuration du rôle est prêt ! Sauvegardez et fermez le fichier.

PowerShell JEA - Exemple de fichier PSRC (PowerShell Session Role Capabilities)
PowerShell JEA - Exemple de fichier PSRC (PowerShell Session Role Capabilities)

V. Enregistrer la nouvelle configuration de session

Nous devons enregistrer cette session PowerShell pour qu'elle soit utilisable. Le cmdlet Register-PSSessionConfiguration doit être utilisé. On va spécifier le nom de la configuration "Support-IT" et le chemin vers le fichier PSSC : SRV-ADDS-01-Manage.pssc.

Register-PSSessionConfiguration –Name Support-IT -Path 'C:\Program Files\WindowsPowerShell\SRV-ADDS-01-Manage.pssc'

Lorsque la session est enregistrée, s'il n'y a pas d'erreurs (en rouge), redémarrez le service WinRM :

Restart-Service WinRM
Register-PSSessionConfiguration - Exemple
Register-PSSessionConfiguration - Exemple

À tout moment, vous pouvez supprimer cette configuration grâce à la commande Unregister-PSSessionConfiguration.

Unregister-PSSessionConfiguration –Name Support-IT

Ce qui est intéressant, c'est de lister les configurations de sessions disponibles sur votre machine. La commande Get-PSSessionConfiguration est notre amie pour cela :

Get-PSSessionConfiguration | Format-Table Name, Permission

On voit bien notre configuration "Support-IT" et que l'accès est autorisé au groupe "IT-Connect\Support-IT".

Get-PSSessionConfiguration - Lister les configurations de sessions
Get-PSSessionConfiguration - Lister les configurations de sessions

C'est l'heure de tester notre configuration...

VI. Tester la session restreinte via PowerShell JEA

Je bascule sur mon poste client Windows 10.... J'ouvre une session avec l'utilisateur "Florian". Il s'agit d'un utilisateur du domaine membre du groupe "Support-IT".

À l'aide d'une console PowerShell, je vais essayer de me connecter sur mon serveur SRV-ADDS-01. Chose habituelle, j'utilise Enter-PSSession. Voici la commande :

Enter-PSSession -ComputerName SRV-ADDS-01

Et là, ça ne fonctionne pas : Accès refusé.

C'est normal, car nous devons spécifier le nom de la configuration à utiliser pour que le serveur autorise notre connexion à partir d'un utilisateur lambda. Reprenons la commande précédente en précisant "-ConfigurationName Support-IT" :

Enter-PSSession -ComputerName SRV-ADDS-01 -ConfigurationName Support-IT

Là, ça fonctionne : parfait ! On peut essayer quelques commandes... Des commandes que l'on a autorisées et d'autres non pour voir ce qui se passe...

Quand la commande n'est pas autorisée, la console nous dit que le terme n'est pas reconnu, comme si la commande n'existait pas (idem pour un programme non autorisé). Quand la commande est autorisée, mais que la valeur d'un paramètre n'est pas correcte, on obtient une erreur qui fait référence à l'attribut ValidateSet (défini dans le fichier de configuration du rôle).

Note : sur la copie d'écran ci-dessous, "Get-Service" ne fonctionne pas, mais c'est normal, car il n'était pas dans ma configuration au moment du test.

Démonstration d'une session restreinte avec PowerShell JEA
Démonstration d'une session restreinte avec PowerShell JEA

Cela fonctionne vraiment bien ! Pour quitter la session, on précisera :

exit

Si vous modifiez votre fichier de rôle (PSRC) pour ajouter une commande par exemple, il n'est pas nécessaire de réinscrire votre session sur le serveur (Register-PSSessionConfiguration). Ce sera pris en compte directement. Par contre, si la session PowerShell distante est en cours, il faudra la fermer et la rouvrir pour que le changement soit pris en compte.

VII. La transcription de PowerShell JEA

Suite aux différents essais et à l'utilisation de la session PowerShell "Support-IT", il y a eu quelques fichiers de transcriptions créés sur notre serveur : un fichier par session.

Au début de chaque fichier, nous avons :

  • L'heure du début de la session
  • L'utilisateur qui a ouvert cette session distante
  • Le nom de la configuration
  • L'ordinateur cible

Ensuite, le fichier contient une trace de toutes les commandes exécutées, y compris lorsque l'utilisateur tente d'exécuter une commande non autorisée. Par exemple, voici la ligne générée lorsque j'ai exécuté "Restart-Service DHCPServer" :

PS>CommandInvocation (Restart-Service) : « Restart-Service »
>> Liaison de paramètre (Restart-Service) : nom = « Name » ; valeur = « DHCPServer »

À la fin du fichier, nous pouvons retrouver l'heure de fin, c'est-à-dire l'heure à laquelle notre session s'est terminée.

**********************
Fin de la transcription Windows PowerShell
Heure de fin : 20210526161044
**********************

VIII. Conclusion

PowerShell JEA est très pratique pour attribuer de façon précise des droits aux utilisateurs non administrateurs, que ce soit pour exécuter un cmdlet, un programme ou un script.

En tout cas, Powershell JEA n'est pas spécialement utile pour les utilisateurs "Admins du domaine" ou "Administrateurs" d'un serveur. En effet, un administrateur pourrait facilement contourner les restrictions de Powershell JEA en se connectant directement sur le serveur en RDP, par exemple.

Définir un rôle au sein de PowerShell Just Enough Configuration n'est pas toujours simple ! Il faut penser à toutes les commandes que pourraient avoir besoin la personne qui va intervenir, en fonction de ce qu'elle a besoin de faire. Par contre, ce qui est génial, c'est que l'utilisateur sera limité à ces quelques actions. D'un point de vue de la sécurité, c'est top !

Pour aller plus loin, je vous recommande de prendre connaissance de ce fichier du GitHub officiel de Microsoft. Il représente une base intéressante pour créer un fichier de rôle sur le support de niveau 1 d'un serveur : PowerShell JEA - Exemple

Dans le même esprit, pour le support niveau 1 d'un serveur IIS : PowerShell JEA - Exemple IIS

Utilisez-vous déjà PowerShell JEA ou souhaitez-vous le mettre en place suite à la lecture de cet article ?

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

1 commentaire sur “Comment configurer PowerShell Just Enough Administration ?

  • Bonjour Florian,

    PTI, tu peux aussi remplacer le « RoleCapabilities » par le « RoleCapabilityFiles » dans le PSSC afin de pouvoir pointer sur un fichier PSRC directement.

    Exemple:
    – RoleDefinitions = @{ ‘CONTOSO\USER’ = @{ RoleCapabilityFiles = ‘C:\Program Files\WindowsPowerShell\Modules\MyFirstJEARole\RoleCapabilities\MyFirstJEARole.psrc’ }; }

    Par contre, ça ne semble marcher que sur 2019 (2008/2012/2016 ne semblent pas gérer ce « hardcoding »). Je pouvais également choisir un path qui allait ailleurs que dans la racine par défaut, toujours sur 2019.

    Ça devrait être pourtant l’inverse (i.e. la façon de faire par défaut!), car avec la méthode « RoleCapabilities », si tu as deux fichiers PSRC JEA qui ont le même noms dans deux sous-répertoires à partir de la racine « C:\Program Files\WindowsPowerShell\Modules\MyFirstJEARole\RoleCapabilities\ », rien ne peut garantir lequel va primer (ou alors l’ordre alphabétique du répertoire parent) vu qu’il fait en réalité une genre de recherche d’un fichier se nommant « Support-IT_Manage.psrc » dans ton exemple avec le « Support-IT_Manage ».

    On a également testé et certifié JEA de « toutes pièces » de notre côté dans les précédents mois. C’est aussi la raison pour laquelle que plutôt que de directement donner accès à des commandes Powershell et commandes exe, on donne accès à une fonction custom (cmdlet « maison ») dans le PSRC qui fait automatiquement le lien avec un fichier module *.psm1 du même nom, qui lui contient toutes les commandes et process qui sont approuvées.

    Ainsi, un utilisateur concerné par le besoin ne peut pas réutiliser les commandes approuvées pour d’autres besoins que celui expressément demandé, en étant client d’un script clairement encadré par nos soins.

    Également, l’utilisateur concerné ne peut pas non plus jouer avec les commandes en cherchant la « faille », car de nombreuses commandes Powershell peuvent être détournées. En effet, un simple Get-Service possède des sous-méthodes et fonctions stop/start de service (testé et approuvé, voir « Get-Service | Get-Member » pour l’ensemble des détails). Pour finir, une même commande peut aussi se voir bonifier de sous-méthodes et fonctions suite à une future mise à jour de Powershell, alors on se charge aussi de protéger les fonctions avec des ValidateSet!

    Super doc en passant, car celle de Microsoft n’est pas la plus claire de toutes (j’en ai également monté une dans notre wiki d’entreprise).

    J’ai envie de croire qu’on est +/- à un niveau de compréhension similaire en ce qui concerne la mise en place de cette solution.

    Je suis tombé sur ta page par hasard, étant plus habitué à chercher et voir du contenu en anglais (Canada/Québec)… 🙂

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.