Archives de catégorie : storage

Stocker des clés SAS de Storage Account dans un KeyVault

Voilà un peu plus d’un an, j’avais publié ce billet : Valet Key avec Azure Function App. Depuis ce temps, je l’utilise énormément. Ce n’est que très récemment en passant un peu de temps dans le KeyVault que j’ai découvert la commande PowerShell Set-AzureKeyVaultManagedStorageSasDefinition. Ça a un peu changé mon approche initiale. Avant, mon Azure Function retournait un clés SAS prête à consommer. Maintenant, j’utilise le Key-Valet pour stocker les clés SAS mises à disposition. Le KeyVault peut stocker ce type de secret (pas visible dans le portail à ce jour). On peut donc ainsi mettre à disposition des clés SAS pré-générées à des d’applications (limitées dans le temps évidement). Pour ce billet, on va se contenter de mettre en œuvre la fonctionnalité :

  • Etape n°1 : Initialisation de notre environnement
  • Etape n°2 : Génération du token SAS
  • Etape n°3 : Expérience côté consommateur

 

Etape n°1 : Initialisation de notre environnement

Pour initialiser notre environnement, nous allons commencer par définir quelques variables. La variable $KeyVaultConsumer désigne un utilisateur référencé dans notre Azure AD pour lequel nous allons mettre en place des permissions RBAC (pour accéder au KeyVault) ainsi que des Access-Policies pour accéder au secret mis à disposition.

$KeyVaultConsumer = « keyvaultconsumer@xxxxxxxxxx.xxx »

$random = Get-Random -Minimum 0 -Maximum 999

$AzureRegion = « WestEurope »

$vaultname = « keyvaultlab$random »

$ResourceGroupname = « KeyVaultLab$random »

$storageaccountname = « keyvaultlab$random »

$sastokenname = « sas$random »

$saspermission = « racwdlup »

$Sastokendurationinminutes = 15

$StorageSKUName = ‘Standard_LRS’

$StorageKind = ‘StorageV2’

$UserPrincipal = (Get-AzureRmContext).Account.id

clip_image002

 

Avec ces variables, nous allons pouvoir initialiser notre environnement comprenant un groupe de ressources contenant à la fois un Storage Account et une instance de Key Vault. Jusque-là rien de très nouveau.

New-AzureRmResourceGroup -name $ResourceGroupname -Location $AzureRegion

$StorageAccount = New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupname -Name $storageaccountname `

-Location $AzureRegion `

-Kind $StorageKind `

-SkuName $StorageSKUName

$Keyvault = New-AzureRmKeyVault -ResourceGroupName $ResourceGroupname -Name $vaultname -Location $AzureRegion -Sku Standard

clip_image004

A ce jour, le portail Azure ne permet pas encore de gérer les permissions sur le Storage. On va donc commencer par se positionner des permissions pour ce type de secret puis référencer notre Storage Account comme « ManagedStorageAccount » auprès de notre instance KeyVault avec la commande Add-AzureKeyVaultManagedStorageAccount

Set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $ResourceGroupname -VaultName $vaultname `

-PermissionsToStorage get,list,delete,set,update,regeneratekey,getsas,listsas,deletesas,setsas,recover,backup,restore,purge `

-UserPrincipalName $UserPrincipal

$keyVault = Get-AzureRmKeyVault -VaultName $vaultname -ResourceGroupName $ResourceGroupname

$Keyvault.AccessPoliciesText

Add-AzureKeyVaultManagedStorageAccount -VaultName $vaultname -AccountName $storageaccountname `

-AccountResourceId $storageaccount.id `

-ActiveKeyName key1 `

-DisableAutoRegenerateKey

$StorageContext = New-AzureStorageContext -StorageAccountName $storageaccountname -Protocol https -StorageAccountKey Key1

clip_image006

Pour ceux qui ont suivi mon billet « Sécuriser ses Storage Accounts dans Azure« , c’est pour l’instant très proche. On peut donc même cumuler les deux fonctionnalités.

 

Etape n°2 : Génération du token SAS

De là, nous pouvons générer notre clé SAS. Par rapport à une approche Valet-Key, le secret n’est pas retourné au demandeur mais directement stocké dans le KeyVault. Attention, ce n’est pas un secret mais un objet de type « ms-sastoken-storage »

$start = [System.DateTime]::Now.AddMinutes(-1)

$end = [System.DateTime]::Now.AddMinutes($Sastokendurationinminutes)

$AccessToken = New-AzureStorageAccountSasToken -Service blob,file,Table,Queue `

-ResourceType Service,Container,Object `

-Permission $saspermission `

-Protocol HttpsOnly `

-StartTime $start `

-ExpiryTime $end `

-Context $StorageContext

$AccessToken

Set-AzureKeyVaultManagedStorageSasDefinition -AccountName $storageaccountname `

-VaultName $vaultname `

-Name $sastokenname `

-TemplateUri $AccessToken `

-SasType ‘account’ `

-ValidityPeriod ([System.Timespan]::FromDays(30))

$secret = Get-AzureKeyVaultSecret -VaultName $vaultname -Name « $vaultname-$sastokenname »

$secret.SecretValueText

$secret.Attributes.ContentType

clip_image008

Pour qu’un consommateur puisse accéder à ce nouveau type de secret (ms-sastoken-storage), il convient de s’assurer qu’il puisse voir l’objet KeyVault dans notre groupe de ressource puis de lui assigner une Access Policy avec uniquement les permissions nécessaires.

New-AzureRmRoleAssignment -SignInName $KeyVaultConsumer -ResourceGroupName $ResourceGroupname -RoleDefinitionName Reader

set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $ResourceGroupname -VaultName $vaultname `

-PermissionsToSecrets Get, List `

-UserPrincipalName $KeyVaultConsumer

Set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $ResourceGroupname -VaultName $vaultname `

-PermissionsToStorage get, list, getsas, listsas -UserPrincipalName $KeyVaultConsumer

$keyVault = Get-AzureRmKeyVault -VaultName $vaultname -ResourceGroupName $ResourceGroupname

$Keyvault.AccessPoliciesText

clip_image010

Etape n°3 : Expérience côté consommateur

Stocker un nouveau type de secret, c’est bien. Maintenant, il faut pouvoir le consommer. Pour la suite de ce billet, je pars du principe que nous sommes connectés avec son identité ($KeyVaultConsumer).

$keyvault = Get-AzurermKeyVault | Out-GridView -Title « Select KeyVault containing SAS Key. » -PassThru

Get-AzureKeyVaultSecret -VaultName $Keyvault.VaultName | Select-Object Name

$secret = Get-AzureKeyVaultSecret -VaultName $Keyvault.VaultName -Name (Get-AzureKeyVaultSecret -VaultName $Keyvault.VaultName).Name

$secret.ContentType

$secret.SecretValueText

clip_image012

 

Maintenant, on peut imaginer des process qui vont automatiquement renouveler des clés pour des consommateurs. Si en plus on combine avec la rotation automatique des clés de Storage Account vu dans mon précédent article, il n’y a plus de raison d’utiliser les clés Full.

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

Sécuriser ses Storage Accounts dans Azure

Le stockage Azure est certainement le composant d’Azure le plus ancien. Nous avons actuellement un support Preview pour Azure AD en lieu et place des clés primaires / secondaires. Pourtant, aujourd’hui c’est d’elles que nous allons parler. Chaque Storage Account dispose de deux « Access Key » comme illustré ci-dessous. Notre ami le RSI/RSSI (c’est mieux de l’avoir comme ami que comme ennemi) est très sensible sur les sujets de chiffrement et de condition d’accès au stockage.

clip_image001

 

Il y a quelques bonnes pratiques autour de ces clés. La première est de ne pas les divulguer. A la place, on recommande un mécanisme de type Key-Valet comme illustré dans ce billet : Valet Key avec Azure Function App. La seconde est d’opérer une rotation des clés régulièrement. Notre ami le RSSI/ RSSI rêve d’un bouton rouge qui lui permettrait d’opérer une rotation des clés à loisir. Dans les faits, cela déroule de la manière suivante :

  • On identifie les applications consommant la clé primaire d’un Storage Account donné
  • On reconfigure les applications pour utiliser la clé secondaire
  • On opère une régénération de la clé primaire du Storage Account
  • On reconfigure les applications pour utiliser la nouvelle clé primaire

Voilà pour la théorie. Dans la pratique, c’est un peu plus compliqué que cela. Nous sommes capables de configurer nos applications / services Azure pour utiliser un secret dans un KeyVault, mais il manquait encore une rotation des clés pilotée depuis le KeyVault, c’est le sujet de ce billet.

Mise en place de l’environnement

Pour la mise en place de l’environnement, nous commencerons avec un Storage Account tout ce qu’il y a de plus classique. Sa seule réelle particularité est l’activation de la fonctionnalité Managed Service Instance (MSI). Celle-ci va générer une identité Azure AD qui permettra au Storage Account d’accéder à notre Key Vault pour accéder à sa clé de chiffrement. Au passage, on notera qu’à ce stade, les clés de chiffrement sont celles de Microsoft.

$resourcegroupName = ‘KeyVaultLab’

$StorageAccountname = ‘keyvaultlab994’

$Keyvaultname = ‘keyvaultlab994’

$location = ‘WestEurope’

$StorageSKU = ‘Standard_LRS’

$StorageKind = ‘StorageV2’

$StorageAccountKeyName = ‘key1’

$StorageAccountEncryptionKeyname = $StorageAccountname

New-AzureRmResourceGroup -Name $resourcegroupName -Location $location

$storageaccount = New-AzureRmStorageAccount -ResourceGroupName $resourcegroupName -Name $StorageAccountname -Location $location -SkuName $StorageSKU -Kind $StorageKind -AssignIdentity

$Storageaccount.Encryption

$Storageaccount.Encryption.KeySource

clip_image002

 

Pour compléter l’environnement, nous allons mettre en place une instance du service Key Vault. Celle-ci sera utilisée pour deux usages :

  • Le stockage de notre clé de chiffrement du contenu du KeyVault
  • La mise en place de la rotation automatique des clés
New-AzureRmKeyVault -ResourceGroupName $resourcegroupName –Name $Keyvaultname -Location $location -EnableSoftDelete -EnablePurgeProtection

Add-AzureKeyVaultKey -VaultName $Keyvaultname -Name $StorageAccountEncryptionKeyname -Destination ‘Software’

clip_image003

 

Au passage, on notera un type de permission qui à ce jour n’est pas encore visible dans le portail : Key Vault Managed Storage.

Pour ce Key Vault, nous avons créé un premier secret. Celui-ci sera utilisé pour le chiffrement du contenu du Storage Account avec notre clé.

$KeyvaultObject = Get-AzureRmKeyVault -VaultName $Keyvaultname

$KeyObject = Get-AzureKeyVaultKey -VaultName $Keyvaultname -KeyName $StorageAccountEncryptionKeyname

$KeyObject

clip_image004

 

Pour finir, nous allons mettre en place une « Access policy » au niveau de notre instance du service Key Vault. Cette permission va permet à l’identité Azure AD liée à notre Storage Account d’accéder au Key Vault pour récupérer la clé de chiffrement.

Set-AzureRmKeyVaultAccessPolicy -VaultName $Keyvaultname -ObjectId $Storageaccount.Identity.PrincipalId -PermissionsToKeys wrapKey, unwrapKey, get

(Get-AzureRmKeyVault -VaultName $Keyvaultname).AccessPoliciesText

clip_image005

 

Mise en place de « Customer Managed Key »

La mise en place de la fonctionnalité « Customer Managed Key » permet de ne plus utiliser les clés de chiffrement de Microsoft mais la nôtre, mise à disposition dans clé précédemment mise en œuvre. A ce jour des services comme Azure Table et Azure Queue ne permettent pas encore d’utiliser la fonctionnalité « Customer Managed Key ». Maintenant que notre Storage Account est capable d’accéder aux clés de l’instance Key Vault, nous allons utiliser la commande Set-AzureRmStorageAccount pour préciser les références de la clé de chiffrement à utiliser.

Set-AzureRmStorageAccount -ResourceGroupName $resourcegroupName -Name $StorageAccountname -KeyvaultEncryption -Keyname $KeyObject.Name -KeyVersion $KeyObject.Version -KeyVaultUri $KeyvaultObject.VaultUri

$Storageaccount = Get-AzureRmStorageAccount -ResourceGroupName $resourcegroupName -Name $StorageAccountname

$Storageaccount.Encryption

$Storageaccount.Encryption.KeySource

$Storageaccount.Encryption.KeyVaultProperties

clip_image006

 

Une fois la commande exécutée, on peut constater dans les caractéristiques de notre Storage Account que la clé de chiffrement est maintenant issue du Key Vault, donc sous notre responsabilité. Charge à nous d’en opérer la rotation. Dans le portail Azure, on peut maintenant constater que le paramètre « Encryption » référence bien l’utilisation d’un secret du Key Vault pour assurer le chiffrement des données.

clip_image007

 

Mise en place de la rotation automatique Access Key

C’est la partie la plus intéressante. La première « Access Key » sera stockée dans notre instance du service Key Vault. Techniquement, ce n’est pas l’identité de notre instance Key Vault qui réalisera l’opération mais le Resource Provider « Azure Key Vault ». J’ai passé beaucoup de temps avant de comprendre ce point particulier.

$KeyVaultServicePrincipal = Get-AzureRmADServicePrincipal | Where-Object {$_.displayname -like « Azure Key Vault »}

$KeyVaultServicePrincipal.id.Guid

clip_image008

Pour opérer la rotation des clés, le service Key Vault (au sens générique) doit pouvoir manipuler les Access Key de notre Storage Account. Cela tombe bien, il existe un rôle nommé « Storage Account Key Operator Role » qui remplit parfaitement cet usage. Nous allons assigner ce rôle sur le Storage Account pour l’identité de l’application Azure Key Vault.

Get-AzureRmRoleDefinition -Name ‘Storage Account Key Operator Service Role’

New-AzureRmRoleAssignment -ObjectId $KeyVaultServicePrincipal.id.Guid -RoleDefinitionName ‘Storage Account Key Operator Service Role’ -Scope $Storageaccount.Id

clip_image009

 

On peut constater la permission dans le portail Azure pour l’application « Azure Key Vault ».

clip_image010

 

Prochaine étape, nous allons nous attribuer de nouvelles permissions dans le Key Vault concernant le stockage. Au moment de l’écriture de ce billet, le portail ne permettait pas encore de manipuler ce nouveau type de permission. On va donc réaliser l’opération en PowerShell et ajouter une Access Policy à notre instance du service Key Vault.

Set-AzureRmKeyVaultAccessPolicy -VaultName $Keyvaultname -ResourceGroupName $resourcegroupName -UserPrincipalName (Get-AzureRmContext).account.id -PermissionsToStorage set, get, regeneratekey, list, getsas, setsas

clip_image011

 

Les plus attentifs auront noté les permissions « getsas » et « setsas ». C’est pour le prochain billet, une nouvelle approche du Key-Valet, …

Pour finir, nous allons configurer la rotation automatique de la première « Access Key » de notre Storage Account. L’opération sera réalisée tous les trente jours.

(Get-AzureRmKeyVault -VaultName $Keyvaultname).AccessPoliciesText

$RegenerationPeriod = [System.TimeSpan]::FromDays(30)

$parameters = @{

VaultName = $Keyvaultname

AccountResourceId = $StorageAccount.Id

AccountName = $StorageAccountname

ActiveKeyName = $StorageAccountKeyName

RegenerationPeriod = $RegenerationPeriod

}

Add-AzureKeyVaultManagedStorageAccount @Parameters

clip_image012

Afin de vérifier la bonne mise en place, nous allons opérer une première rotation avec les commandes PowerShell suivantes :

Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $storageAccountName

Update-AzureKeyVaultManagedStorageAccountKey -VaultName $keyVaultName -AccountName $storageAccountName -KeyName $StorageAccountKeyName

Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $storageAccountName

clip_image013

 

A noter que la rotation n’a été configurée que pour la première « Access Key », pas pour la seconde. Maintenant, vous connaissez la manœuvre.

Quelques notes

  • A ce jour, la fonctionnalité « Customer-Managed keys » ne concerne que les services Blog et File, pas Table et queue qui continuent à utiliser la clé de chiffrement gérée par Microsoft
  • L’utilisation de la fonctionnalité « Soft delete » sur le keyvault a pour conséquence qu’après avoir supprimé un KeyVault, son nom n’est pas réutilisable avant 90 jours, temps nous permettant de le restaurer. Il est vivement recommandé de l’activer.
  • Pour la rotation des clés, le nom de la clé est nécessairement Key1, Key2. N’essayez pas d’utiliser d’autres noms. Conséquence, on ne peut pas avoir tous les « Access Keys » dans un Key Vault unique. Il faut autant de Key Vault que de Storage Accounts

 

Conclusion

Normalement, avec ces deux opérations le RSI/RSSI de votre entreprise devrait apprécier. Il dispose maintenant d’un bouton rouge pour forcer la régénération des clés d’accès au stockage. Pour ne pas casser vos applications / ressources Azure, la prochaine étape sera de les reconfigurer pour extraire l’information du Key Vault et non continuer à coder l’information en dur dans le code ou dans une variable Application Settings dans Web App.

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

Software-Defined Storage Design Calculator

Avec la génération Windows Server 2012 / 2012 R2, Microsoft a introduit une nouvelle approche du stockage (qui se poursuivra dans Windows Server 2016) basé sur du JBOB et mis en avant avec les fonctionnalités suivantes :

  • Shared Cluster Volume
  • Scale-Out File Server
  • Storage Pool
  • Storage Spaces

Le tout avec une pointe de tiering SSD pour un stockage bien frappé. Cette nouvelle approche du stockage manquait d’information quant à son design. On dispose maintenant d’un Software-Defined Storage Design Calculator, un peu comme le Storage Calculator pour Exchange. Au moment où j’écris ce billet, c’est déjà la version 1.1 qui est disponible. Logiquement, il est très orienté pour les charges applicatives hébergées sous Hyper-V. Pour commencer, nous devons commencer par causer matériel. Cela implique de :

  • Choisir un template (Pour info le 4 nœuds * 4 châssis, c’est l’architecture stockage de CPS qui envoie du poney)
  • Estimer la consommation en pic de la charge applicative que l’on va héberger
  • Estimer la consommation moyenne de la charge applicative que l’on va héberger
  • Fournir les informations concernant le stockage (nombre de disques, capacité brute, nombre de tiroirs, contenu des tiroirs, …)

clip_image001

Note : Attention, avant de commencer, assurez-vous de disposer de la dernière version du fichier disponible à cette adresse.

Vous disposerez d’une première estimation qu’il faudra affiner avec votre fournisseur favori. A un moment, il faudra valider les hypothèses de calcul et se confronter à la réalité. Pour cela, une bonne adresse à conserver : Server and Storage I/O Benchmarking and Performance Resources. Y a tout ce qu’il faut pour casser du disque. Pour finir quelques conseils :

  • Attention à la taille des clusters pour le formatage
  • Attention aux optimisations matérielles réseau
  • Un antivirus sur un Hyper-V ca peut être fatal avec le SCV. Chaque nœud du cluster peut scanner le même fichier

 

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