Archives mensuelles : juillet 2017

Parlons d’identité avec Azure Automation

Azure Automation, est un composant avec lequel je passe beaucoup de temps en ce moment. C’est un composant intéressant qui mérite qu’on y passe un peu de temps, surtout lorsque celui-ci nous parle d’identité. C’est ce qui arrive lors de la création d’une instance de ce service si on ne dispose pas des privilèges nécessaires. C’est le cas illustré ci-dessous. Ce qu’il faut comprendre, c’est que nous ne pouvons pas créer un certain nombre d’objets dans le tenant Azure AD et positionner des permissions.

clip_image001

Pourquoi est-ce important ? Tout simplement parce que c’est sous cette identité que nous allons exécuter nos futurs Runbooks. Dans ma situation, j’ai bien le niveau de privilège « Owner » sur mon groupe de ressources mais absolument aucun privilège dans le tenant Azure AD lié à ma souscription Azure. Du point de vue Azure Automation, il m’indique bien qu’il a un problème avec les « Run As Accounts » ?

clip_image002

 

On notera qu’il existe deux type de « Run As Accounts » :

  • Azure Run As Account
  • Azure Classic Run As Account

Pour faire court, le premier est destiné à gérer les ressources de type ARM et le second les ressources de type ASM, donc l’ancien Azure. Dans mon cas, ça ne sera pas possible puisque je suis sur une souscription Azure CSP. Nous allons donc devoir créer un « Azure Run As Account ». C’est maintenant que cela commence à piquer un peu. Le portail Azure nous donne un indice, ce qui manque, c’est une identité, un Service Principal qui va être associé à une application dans Azure AD. Si nous n’avons pas les privilèges sur le Tenant Azure AD lié à notre souscription Azure, il faudra réaliser la création manuellement. L’opération comprendra plusieurs étapes :

  • La création d’un certificat
  • Créer une application Azure AD
  • Assigner un rôle RBAC
  • Déclaration du Certificat dans Azure Automation
  • Déclaration de la connexion dans Azure Automation
  • Consommer l’identité dans un Runbook

 

La création d’un certificat

L’instance du Service Azure Automation a besoin d’un certificat. Ce certificat sera référencé comme un « Asset » dans Azure Automation., nous y reviendrons. Pour le certificat en lui-même, il peut être auto-signé ou délivré par une autorité de certification. Lorsqu’on laisse faire le portail, il va générer un certificat auto-signé d’une durée de vie d’un an. C’est court. Est-ce qu’on va se souvenir que ce certificat va expirer si le portail a fait tout cela pour nous ? Non. Le portail Azure ne nous préviendra pas. La seule chose qu’il va nous proposer, c’est l’option « Rewnew certificate » comme illustré ci-dessous :

Celui-ci sera lié à notre Application Azure AD. Vu qu’on va avoir besoin du certificat pour créer notre Application Azure AD, on va commencer par lui. Notre première décision sera de définir les caractéristiques principales de ce certificat :

  • Nom
  • Date d’expiration

clip_image003

Par contre, ce qui est bien, c’est qu’on a maintenant sous les yeux tous les ingrédients. Pour notre démonstration, nous allons créer un certificat auto-signé d’une durée de vie de deux ans :

$CertName = « automation.simplebydesignlabs.fr »

$CurrentDate =Get-Date

$EndDate = $currentDate.AddYears(2)

$NotAfter = $endDate.AddYears(2)

$CertStore = “Cert:\LocalMachine\My”

$CertThumbprint =(New-SelfSignedCertificate -DnsName « $certName » -CertStoreLocation $CertStore -KeyExportPolicy Exportable -Provider « Microsoft Enhanced RSA and AES Cryptographic Provider » -NotAfter $notAfter).Thumbprint

$CertThumbprint

clip_image004

Ce n’est pas précisé mais le certificat est exportable et c’est vivement recommandé si on veut plus tard déployer des Hybrid Worker Group. Nous allons exporter ce certificat.

$pfxPassword = ConvertTo-SecureString -String « LeMotDePasseIlAChangé! » -AsPlainText -Force

$pfxFilepath = « C:\Temp\automation.PFX »

Export-PfxCertificate -Cert « $($certStore)\$($certThumbprint) » -FilePath $pfxFilepath -Password $pfxPassword

clip_image005

C’est maintenant que cela se complique. Pour permettre à notre instance Azure Automation de s’authentifier, il faut la référencer sous la forme d’une application Azure AD. Cette application devra présenter le certificat exporté. Ce sera sa méthode d’authentification. Nous devons donc préparer un objet « PSADKeyCredential » dans lequel nous allons référencer le certificat et ses principales caractéristiques :

Import-Module -Name AzureRM.Resources

$Cert =New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate -ArgumentList @($pfxFilepath, $pfxPassword)

$KeyValue =[System.Convert]::ToBase64String($cert.GetRawCertData())

$KeyId =[guid]::NewGuid()

$KeyCredential = New-Object -TypeName Microsoft.Azure.Commands.Resources.Models.ActiveDirectory.PSADKeyCredential

$KeyCredential.StartDate = $currentDate

$KeyCredential.EndDate = $endDate

$KeyCredential.KeyId = $keyId

$KeyCredential.CertValue = $keyValue

$KeyCredential

clip_image006

 

Créer une application Azure AD

Prochaine étape, déclarer notre application dans Azure AD et y associer un Service principal :

$AADAppName = « Automation_APP »

$adAppHomePage = « « 

$adAppIdentifierUri = « « 

$AADApp = New-AzureRmADApplication -DisplayName $AADAppName -HomePage $adAppHomePage -IdentifierUris $adAppIdentifierUri -KeyCredentials $KeyCredential

New-AzureRmADServicePrincipal -ApplicationId $AADApp.ApplicationId -KeyCredential $KeyCredential

clip_image007

 

Assigner un rôle RBAC

Nous avons maintenant une identité. Encore faut-il que celle-ci dispose de privilèges dans la souscription Azure. Dans mon contexte, j’ai fait au plus restreint, à savoir limité à un groupe de ressources nommé Gestion, pour lequel le Service principal dispose du niveau de privilèges « Contributor » (gestion des ressources existantes dans le groupe de ressources).

New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $($AADApp.ApplicationId) -ResourceGroupName Gestion

clip_image008

Au passage, si on laisse faire le portail, c’est le niveau de privilège « Owner » qui est positionné sur la souscription. Votre RSSI appréciera, ou pas.

 

Déclaration du Certificat dans Azure Automation

La première opération qu’un Runbook Azure Automation, c’est de s’authentifier auprès d’Azure. Cette authentification sera faite sous l’identité du Service Principal. Pour que l’authentification fonctionne, encore faut-il qu’Azure Automation dispose du certificat. Azure Automation va mettre à disposition le certificat lors de chaque exécution de Runbook. On va donc référencer cet « Asset » dans notre instance du service Azure Automation sous le nom « AzureRunAsCertificate ». On verra plus tard que le nom a son importance.

$AutomationCertAsset = « AzureRunAsCertificate »

$AutomationAccountName = « Automation »

$AutomationResourceGroupname = « Gestion »

New-AzureRmAutomationCertificate -Name $AutomationCertAsset -Path $pfxFilepath -Password $pfxPassword -AutomationAccountName $AutomationAccountName -ResourceGroupName $AutomationResourceGroupname

clip_image009

On notera que ce certificat est maintenant impossible à exporter. C’est une bonne chose d’un point de vue sécurité.

Déclaration de la connexion dans Azure Automation

C’est maintenant qu’on va créer le « Run As Account ». Dans notre cas, nous allons créer un « Run As Account » pour un Service Principal qui utilise un certificat pour s’authentifier. Nous devons disposer d’un certain nombre de paramètres :

  • L’identifiant unique de l’application Azure AD précédemment créée
  • L’identifiant unique du tenant Azure AD dans lequel l’Application Azure AD a été créée
  • L’empreinte numérique du certificat que nous avons associé à l’Application Azure AD
  • La souscription Azure dans laquelle l’application Azure AD va se connecter

$ConnectionAssetName = « AzureRunAsConnection »

$ConnectionFieldValues = @{« ApplicationId » = $AADApp.ApplicationId; « TenantId » = (Get-AzureRmContext).Tenant.Id; « CertificateThumbprint » = $CertThumbprint; « SubscriptionId » = (Get-AzureRmContext).Subscription.Id}

$ConnectionFieldValues

New-AzureRmAutomationConnection -ResourceGroupName $AutomationResourceGroupname -AutomationAccountName $AutomationAccountName -Name $ConnectionAssetName -ConnectionTypeName AzureServicePrincipal -ConnectionFieldValues $ConnectionFieldValues

clip_image010

 

Si tout se passe bien, voilà ce que vous devriez avoir dans les « Run As Accounts » de votre instance Azure Automation :

clip_image011

 

On retrouve bien toutes les informations que nous avons renseigné.

clip_image012

 

Maintenant le truc sur lequel j’ai passé le plus de temps. Si vous avez scrupuleusement respecté les étapes indiquées, cela fonctionne. Par contre, si vous avez eu le malheur de changer le nom de l' »Asset » du certificat, le portail n’est pas d’accord. Il vous indique que votre configuration est incomplète. Pour le portail, c’est clairement le certificat qui est en cause.

clip_image013

 

C’est un problème lié au portail, ce qui n’empêche pas le fonctionnement des Runbooks. Le problème a été remonté chez Microsoft car si la configuration est considérée comme incomplète, le portail Azure ne nous permet pas de renouveler notre certificat.

 

Consommer l’identité dans un Runbook

Créer une identité, c’est bien, la consommer c’est mieux. J’ai fait au plus court avec un Runbook PowerShell des familles :

[OutputType([String])]

$connectionName = « AzureRunAsConnection »

try

{

# Get the connection « AzureRunAsConnection « 

$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName

« Logging in to Azure… »

Add-AzureRmAccount `

-ServicePrincipal `

-TenantId $servicePrincipalConnection.TenantId `

-ApplicationId $servicePrincipalConnection.ApplicationId `

-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint

« Logged to Azure »

}

catch {

if (!$servicePrincipalConnection)

{

$ErrorMessage = « Connection $connectionName not found. »

throw $ErrorMessage

} else{

Write-Error -Message $_.Exception

throw $_.Exception

}

}

Get-ChildItem cert:\currentuser\my

 

Lors de l’exécution, vous allez découvrir que le certificat utilisé est dans le magasin de l’utilisateur et non de l’ordinateur :

clip_image014

 

Voilà tout ce qui se cache derrière le portail Azure lors de la création d’une instance du service Azure Automation en mode « Click Next Finish ».

 

BenoitS – Simple and Secure by design but Business compliant (with disruptive flag enabled)