Archives de catégorie : Azure Key Vault

Consommer des secrets Azure Key Vault depuis Visual Studio 2015

Parfois, il y a des mises à jour qu’on voit pas passer et qui nous sauvent la vie quand on les découvre. Je dis découvre car c’est tellement petit en taille sur mon écran qu’on se rend pas compte qu’on passe devant tous les jours. La dernière mise à jour de Visual Studio Community Edition 2015 (L’update 2) est de celle-là. Je passe par là tellement souvent que c’est devenu un réflexe.

clip_image001

 

J’allais renseigner mes paramètres sans réfléchir, jusqu’à ce que ce petit icône attire mon attention.

clip_image002

 

Oh magie, une intégration cachée de l’Azure Key Vault. Premier point qui attire mon attention, une indication d’avertissement sur mon Key Vault.

clip_image003

 

C’est que mon instance du service Key Vault n’est pas encore configurée pour être utilisable pendant les déploiements. Recherche rapide, la configuration actuelle ne permet pas d’utiliser le Key Vault lors d’un déploiement de templates.

clip_image004

 

Je me disais que cela allait être une formalité mais on est toujours en Preview. L’aide de la commande New-AzureRmKeyVault nous indique que c’est pas encore possible de le configurer en PowerShell.

clip_image005

 

En attendant le passage en General Availability, je triche, moi propriétaire du précieux coffre-fort numérique va corriger cela en déclarant un secret directement depuis Visual Studio Community 2015.

clip_image006

 

Y a plus qu’à laisser Visual Studio mettre à jour les fonctionnalités de mon coffre-fort numérique.

clip_image007

 

Par ce que je ne suis pas préteur de mes précieux, je ne donne l’accès qu’au précieux secrets dont mon développeur a besoin. Et encore, uniquement le droit de les consommer­. La subtilité, c’est qu’il doit pouvoir accéder aux clés et aux secrets. Pas plus que la permission Get. C’est suffisant.

Set-AzureRmKeyVaultAccessPolicy -VaultName ‘MyKeyVaultHSM’ -UserPrincipalName ‘test@XXXXXXXXXX.onMicrosoft.com’ -PermissionsToKeys ‘Get’ -PermissionsToSecrets ‘Get’

clip_image008

 

Une évolution intéressante serait de pouvoir filtrer précisément la clé concernée. C’est pas encore possible à ce jour.Après, y a plus qu’à shooter comme d’habitude. On remarquera qu’on fait référence à une secret qui vient juste d’être mis au coffre-fort numérique.

clip_image009

 

Pour ceux que cela intéresse, le détail de mes paramètres de déploiement. Cela fait bien référence à la variable nouvellement créée.

clip_image010

 

Conclusion, mes développeurs peuvent provisionner des machines virtuelles sans connaitre le mot de passe Administrateur de la machine virtuelle. On peut même pousser la mécanique pour réaliser la jointure au domaine. Combiné avec un truc comme LAPSI alias ADMPWD, c’est parfait.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Injecter un certificat dans une machine virtuelle avec Azure Key Vault

Après ma première exploration de l’Azure KeyVault avec la preview d’Azure Disk Encryption, j’ai décidé de m’attarder sur un autre usage du coffre-fort numérique. Un sujet récurrent dans la gestion des infrastructures, c’est la mise à disposition de certificats dans les machines virtuelles.

Du point de vue de la sécurité, c’est compliqué car cela implique de mettre à disposition le certificat avec sa clé privée sous forme d’un fichier PFX. La seule sécurité, c’est le mot de passe nécessaire pour pouvoir installer le certificat sur un nouveau système. Certes, on peut masquer ce mot de passe, c’est un sujet que j’avais traité dans ce billet : Cacher les mots de passe dans les scripts PowerShell. C’est une approche, mais on peut faire mieux en stockant le couple PFX et mot de passe dans l’Azure Key Vault. C’est le sujet de ce billet.

Pour la démonstration, j’ai réutilisé le coffre-fort numérique que j’avais mis en œuvre dans le billet Cacher les mots de passe dans les scripts PowerShell, ainsi que la machine virtuelle utilisée dans le billet Découverte d’Azure Disk Encryption (Preview).

Un peu de cuisine

Dans les prérequis, il me faut un certificat qui soit exportable. Je viens de l’exporter tout chaud avec sa clé privée.

clip_image001

 

Azure, on commence à connaitre, ce n’est pas la première fois que j’aborde le module PowerShell qui lui est associé. Donc première étape : Authentification. En toute logique, il serait fort judicieux d’avoir activé Azure Multifactor Authentication (MFA) pour sécuriser l’accès à notre coffre-fort numérique.

clip_image002

 

Puis nous devons sélectionner la souscription que nous allons utiliser.

clip_image003

 

Dans mon dernier billet, j’avais mis en œuvre un KeyVault dans le ressource group ‘AzureDiskEncrypt’, nous allons le réutiliser.

$Vault = Get-AzureRmKeyVault -ResourceGroupName ‘AzureDiskEncrypt’

$Vault.VaultName

clip_image004

 

C’est pour l’exemple. Dans la pratique, je recommanderais de séparer les coffre-fort numériques en fonction des usages. D’un point de vue facturation, il n’y a pas de coût à mettre en place un coffre-numérique, nous ne payons que l’usage, l’accès aux secrets protégés.

 

Le stockage des secrets

C’est maintenant que cela commence à se compliquer. On ne doit pas référencer un secret mais bien deux :

  • Le fichier PFX
  • Le mot de passe nécessaire pour accéder à la clé privée

C’est un couple indissociable que nous devons stocker dans notre coffre-fort numérique. Après quelques recherches, c’est un peu plus compliqué que pour les mots de passe. La solution est venue du White Paper Azure Disk Encryption for Windows and Linux Azure Virtual Machines. Pour faire court, nous allons devoir créer un objet JSON contenant :

  • Le certificat encodé en base 64
  • Le type de certificat (PFX, impliquant donc une clé privée sécurisée par un mot de passe)
  • Le mot de passe en lui-même

 

Cet objet JSON sera lui-même encodé en base 64.

$CertFile = ‘C:\Temp\certificat.PFX’

$CertPassword = « Password123 »

$ResourceGroupName = ‘AzureDiskEncrypt’

$fileContentBytes = get-content $CertFile -Encoding Byte

$fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes)

$jsonObject = @ »

{

« data »: « $filecontentencoded »,

« dataType » : »pfx »,

« password »: « $certPassword »

}

« @

$jsonObjectBytes = [System.Text.Encoding]::UTF8.GetBytes($jsonObject)

$jsonEncoded = [System.Convert]::ToBase64String($jsonObjectBytes)

 

Le secret doit lui aussi faire l’objet d’un encodage mais cette fois, il est tout à fait classique.

$secret = ConvertTo-SecureString -String $jsonEncoded -AsPlainText -Force

clip_image006

 

Maintenant, on a plus qu’à enregistrer notre objet JSON dans le coffre-fort numérique avec la commande suivante.

Set-AzureKeyVaultSecret -VaultName $vault.VaultName -Name ‘SecureCertificate’ -SecretValue $Secret

clip_image008

 

Quelques précisions :

  • Pour raison de sécurité, l’opération nécessitera la confirmation de notre identité
  • La commande permet de spécifier une date interdisant l’usage avant une date donnée
  • La commande permet de spécifier une date interdisant l’usage passé une date donnée

 

Bref, nous, responsable de la sécurité pouvons gérer le cycle de vie de ces secrets en étant assurés qu’ils ne seront utilisables que pendant la période de temps autorisée ou jusqu’à ce qu’ils doivent être annulés.

A ce stade, je conseille d’aller faire un tour dans l’aide de la commande Set-AzureRmKeyVaultAccessPolicy pour comprendre comment nous allons accorder à un utilisateur tiers (le propriétaire de la machine virtuelle par exemple) d’accéder à notre conteneur numérique pour y récupérer le secret positionné. On découvre que bientôt on pourra accorder ce droit à une application référencée dans le portail (soon).

L’injection du secret dans la machine virtuelle

La dernière étape c’est d’injecter ce secret sans avoir accès au secret lui-même. Mieux sans avoir à manipuler ni le fichier PFX et encore moins le mot de passe associé. Pour la suite de ce billet, je pars du principe que le propriétaire de la machine virtuelle s’est vu accordé une permission pour accéder au secret. Ce que nous devons injecter, c’est l’URL de notre secret. Dès lorsqu’on connait le nom du coffre-fort numérique et le nom du secret, la commande ci-dessous va nous retourner l’URL de la dernière version du secret :

$certUrl = (Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name ‘SecureCertificate’).ID

clip_image010

 

Il ne nous reste plus qu’à mettre à jour notre machine virtuelle pour que sa définition fasse référence à ce secret. On va donc commencer par récupérer sa configuration dans une variable pour l’enrichir et mettre à jour la machine virtuelle :

$vm = Get-AzureRmVM -ResourceGroupName ‘AzureDiskEncrypt’ -Name ‘AzureVM01’

$vm = Add-AzureRmVMSecret -VM $vm -SourceVaultId $vault.ResourceId -CertificateStore « My » -CertificateUrl $CertURL

Update-AzureRmVM -VM $vm -ResourceGroupName « AzureDiskEncrypt »

clip_image011

 

Explorons un peu la nouvelle configuration de la machine virtuelle :

$Vm.OSProfile.Secrets | Format-List

$Vm.OSProfile.Secrets.SourceVault

$Vm.OSProfile.Secrets.VaultCertificates

clip_image012

 

On retrouve bien la référence à notre coffre-fort numérique et au secret injecté. Dans la machine virtuelle, je retrouve bien le certificat :

Get-ChildItem Cert:\Localmachine\My

clip_image014

 

Y a même la clé privée qui va avec

clip_image016

Que demander de plus?

En fait pas grand-chose. Si on dispose bien d’une commande pour injecter un certificat dans une machine virtuelle, nous n’avons pas la possibilité de le retirer. Il faudra donc révoquer le certificat.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Découverte d’Azure Disk Encryption (Preview)

Le billet « Cacher les mots de passe en Powershell » ayant eu beaucoup de succès, j’ai décidé de passer un peu plus de temps sur Azure Key Vault. En creusant un peu, on comprend qu’elle permet de stocker un grand nombre de secrets, y compris les clés de chiffrement de Bitlocker, ce qui nous amène au service Azure Disk Encryption, encore en Preview au moment où je rédige cet article. Linux n’étant pas encore ma tasse de thé, ce sera donc à Windows que je vais consacrer mon billet.

Le couplage d’Azure Disk Encryption avec Azure Key Vault est une évidence : Remplacer le TPM que nous avions On- Premises pour y stocker notre secret. Azure Key Vault étant un service Cloud, il est capable de stocker bien plus qu’un secret avec un niveau de sécurité bien plus élevé. Pour information, les instances « Premium » du service Azure Key Vault sont hébergées sur des boitiers HSM Thales certifiés FIPS 140-2 Level 2. Pourquoi s’en priver?  La mise en place s’effectuera selon les étapes suivantes :

  • Mise en place des prérequis
  • Activation pour le disque OS de notre VM IaaS
  • Constats dans la machine virtuelle

 

Mise en place des prérequis

Azure Disk Enryption nécessite la version 1.1.0 du module Powershell Azure Active Directory. Une rapide commande « Get-Module Azure -ListAvailable » nous inique que j’ai bien la version minimale.

clip_image001

 

Ceci vérifié, on peut s’attaquer au grand classique de l’authentification avec Login-AzureRmAccount.

clip_image002

 

Et sélectionner la souscription que nous allons utiliser avec les commandes Get-AzureRMSubscription et Select-AzureRMSubscription.

clip_image003

 

Pour travailler, nous allons avoir besoin d’une machine virtuelle qui a été provisionnée dans le groupe de ressources AzureDiskEncrypt, ce que j’ai bien avec les commandes suivantes :

Get-AzureRMresourceGroup -Name AzureDiskEncrypt

Get-AzureRMVM -Resourcegroupname ‘AzureDiskEncrypt’ | Select ResourcegroupName, Name, Location, ProvisioningState

clip_image004

 

Dans mon dernier billet, j’avais mis en œuvre un Key Vault dans son édition standard. Cette fois, j’utilise l’édition Premium, juste pour bénéficier du stockage sur un HSM certifié FIPS 140-2 Level 2. Comme indiqué plus tôt, à ce tarif, ce serait criminel de ne pas l’utiliser. La commande suivante va nous permettre de créer mon coffre-fort numérique dans le même groupe de ressources pour raisons de simplicité. Donc allons y :

New-AzureRMKeyVault -VaultName ‘MyKeyVaultHSM’ -ResourceGroupName ‘AzureDiskEnrypt’ -Location ‘North Europe’ -SKU ‘Premium’.

clip_image005

 

Remarque: Une limite à connaitre, le Key vault que nous allons utiliser pour la fonctionnalité Azure Disk Encryption doit nécessairement dépendre de la même région Azure que les machines virtuelles sur lesquelles nous allons activer la prise en charge. Dans un sens c’est logique, ou alors on devrait accepter que les secrets sortent d’une région et donc d’un Datacenter.

Notre coffre à secrets est en place et accessible via une URL. Pour l’instant, je suis le seul à avoir tous les privilèges, ce qui est normal en tant que créateur. A ce stade, on peut constater que notre coffre-fort numérique n’est pas éligible aux fonctionnalités qui nous intéresse. Nous allons y remédier avec les commandes Powershell suivantes :

Set-AzureRmKeyVaultAccessPolicy -VaultName ‘MyKeyVaultHSM’ -ResourceGroupName ‘AzureDiskEncrypt’ -EnabledForDiskEncryption -EnabledForDeployment

Get-AzureRMKeyVault -VaultName ‘MyKeyVaultHSM’ -ResourceGroupName ‘AzureDiskEncrypt’

clip_image006

 

Je vois tout de suite qu’il y en a qui se demandent pourquoi l’option ‘-EnabledForTemplateDeployment’ n’a pas été utilisée. La réponse est venue de la documentation de la commande New-AzureRmKeyVault : « Note: This parameter is not currently implemented. ». On est bien en Preview.

 

On arrive bientôt à la fin des prérequis, plus que deux. Pour que nos machines virtuelles puissent utiliser notre coffre-fort numérique, il nous faut deux choses :

  • Une identité que nos machines virtuelles pourront utiliser pour accéder à notre coffre-fort numérique (plus précisément l’extension de machine virtuelle)
  • Une ressource à laquelle nous allons accorder des accès.

Il m’a fallu un peu de temps pour comprendre le modèle mais c’est logique. Pour piloter la mise en place de la fonctionnalité Azure Disk Encryption, nous allons injecter un agent dans la machine virtuelle. Du point de vue de Windows Azure Active Directory, notre machine virtuelle n’a pas d’identité, il faut donc l’aider en lui fournissant une identité, laquelle sera utilisée pour accéder au coffre-fort numérique.

Au moment où je rédige ce billet, Windows Azure Active Directory est encore disponible uniquement depuis l’ancien portail. C’est donc depuis celui-ci que nous allons déclarer une nouvelle application dans notre tenant Windows Azure Active Directory.

clip_image007

 

L’application référencée pointera directement sur l’URL de la ressource de notre coffre-fort numérique.

clip_image008

 

C’est là qu’intervient une subtilité. Pour configurer notre agent, il va avoir besoin de deux informations :

  • Un Client ID
  • Une clé.

clip_image009

 

C’est un peu comme un login & Mot de passe. Nous allons garder ces informations dans un coin. On va commencer par autoriser l’accès au coffre-fort numérique pour cette identité avec la commande Powershell suivante : Set-AzureRmKeyVaultAccessPolicy -VaultName ‘MyKeyVaultHSM’ -ServicePrincipalName ‘<ClientID>’ -PermissionsToKeys All -PermissionsToSecrets All

clip_image010

 

Pour vérifier que cela fonctionne, il suffit s’afficher les caractéristiques de notre coffre-fort numérique avec la commande Get-AzureRMKeyVault -VaultName ‘MyKeyVaultHSM’. On constate que le ClientID que nous avons fourni a été reconnu. Pour simplifier, j’ai volontairement simplifié la mise en œuvre. Dans un véritable déploiement, on limiterait l’accès à certains types de secrets, voire jusqu’à segmenter en plusieurs coffre-fort numériques en fonction des usages. Si ça vous intéresse, l’aide en ligne de la commande PowerShell Set-AzureRmKeyVaultAccessPolicy est un bon point de départ.

Activation pour le disque OS de notre VM IaaS

C’est maintenant que cela commence à devenir intéressant. Pour commencer on va personnaliser le portail pour faire apparaitre une nouvelle colonne. Pour l’instant, le service Azure Disk Encryption est bien désactivé.

clip_image011

 

On peut avoir le même résultat avec la commande Powershell suivante  : Get-AzureRMVMDiskEncryptionStatus -ResourceGroupName ‘AzureDiskEncrypt’ -VMName AzureVM01

clip_image012

 

L’information est ici plus précise puisqu’on sépare le statut du disque OS des éventuels disques de données. Dernière étape, l’activation de l’agent de chiffrement dans notre machine virtuelle. Pour commencer, on va mettre de côté quelques informations sur notre coffre-fort numérique avec la commande Powershell suivante : $Vault = Get-AzureRMKeyVault -Resourcegroupname ‘AzureDiskEncrypt’ -VaultName ‘MyKeyVaultHSM’

clip_image013

 

On a tout ce qu’il nous faut, on passe au tour de magie. L’installation de l’agent va nécessiter le redémarrage de notre machine virtuelle ainsi qu’un peu de temps pour activer Bitlocker. Voilà la formule magique :

Set-AzureRMVMDiskEncryptionExtension -ResourceGroupName ‘AzureDiskEncrypt’ -VMName ‘AZUREVM01’ -AadClientID ‘<Identifiant Client ID de l’application dans le portail>’ -AadClientencryptionKeyVaultURL $vault.VaultUri -DiskEncryptionKeyVaultID $Vault.ResourceId

clip_image014

 

Après quelques minutes et un redémarrage de la machine virtuelle, la commande Powershell rend la main en nous indiquant un succès. Un rapide Get-AzureRMVMDiskEncryptionStatus -ResourceGroupName ‘AzureDiskEncrypt’ -VMName AzureVM0’1 nous confirme que le chiffrement est bien activé, au moins pour le disque OS pour lequel on a maintenant un secret dans le coffre-fort numérique.

Logiquement, si on a activé la fonctionnalité Bitlocker, on devrait avoir des secrets dans notre coffre-fort numérique. Je dis bien des secrets car au minimum, une machine virtuelle est composée de deux disques dur :

  • Le disque OS
  • Le disque temporaire

C’est pour cela que la commande Get-AzureKeyvaultSecret -VaultName ‘MyKeyVaultHSM’ nous indique deux secrets.

clip_image015

 

Constats dans la machine virtuelle

On a passé assez de temps dans les nuages, allons constater que notre système d’exploitation a bien activé Bitlocker. Juste après l’authentification, un joli message nous indique que cela se présente bien :

clip_image016

 

Dans le détail, effectivement, ça se présente même très bien dans le panneau de configuration.

clip_image017

 

Pour finir, comme j’aime de moins en moins des interface graphiques, je repasse en Powershell avec la commande Get-BitlockerVolume :

clip_image018

 

Là, les résultats sont sans appel. On a bien deux volumes pour lesquels Bitlocker est activé (dont un en cours d’activation). Y a juste une subtilité qui m’échappe. Le KeyProtector indique ‘ExternalKey’. Elle est ou cette clé. Pour rappel, n’a pas de TPM. La réponse m’est apparue quelques minutes plus tard en regardant l’explorateur Windows.

clip_image019

 

Ce nom ne m’est pas inconnu, allons revoir les secrets dans notre coffre-fort numérique

Get-AzureKeyVaultSecret -Vaultname ‘MyKeyvaultHSM’ | Select Name

Get-AzureKeyVaultSecret -Vaultname ‘MyKeyvaultHSM’ -name ‘EBCAF0E6-3AAB-4234-9B64-AB84DCC1A0DA’

clip_image020

 

C’est la clé Bitlocker. La VM Extension utilise donc un disque additionnel pour y placer le secret qu’elle a extrait de mon coffre-fort numérique.

 

Conclusion

La fonctionnalité est encore en Preview mais vu que seul l’accès aux secrets est facturé 0,8433€ par secret par mois, ce sera une fonctionnalité obligatoire lorsqu’elle passera en General Availability. 1€ pour stocker des clés de chiffrement dans des boitiers HSM Thales certifiés FIPS 140-2 Level 2, ce serait criminel de s’en passer. Pour rappel dans le Cloud, la responsabilité de vos ressources et contenu de votre tenant est sous votre responsabilité. Microsoft fournit les moyens de sécuriser nos ressources, nous seuls sommes responsables en cas d’incident de sécurité.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)