Using Gary Grudzinskas ‘Securing Virtual Machines with Azure Key Vault’ training course on Pluralsight
Azure Key Vault helps solve the following problems:
- Secrets Management - Azure Key Vault can be used to Securely store and tightly control access to tokens, passwords, certificates, API keys, and other secrets
- Key Management - Azure Key Vault can also be used as a Key Management solution.
- Certificate Management - Azure Key Vault is also a service that lets you easily provision, manage, and deploy public and private Transport Layer Security/Secure Sockets Layer (TLS/SSL) certificates for use with Azure and your internal connected resources.
- Store secrets backed by Hardware Security Modules - The secrets and keys can be protected either by software or FIPS 140-2 Level 2 validated HSMs
Key Vault PowerShell reference: https://docs.microsoft.com/en-us/powershell/module/azurerm.keyvault/?view=azurermps-6.13.0#key_vault
Requirements for Key Vault:
- Azure AD
- PowerShell for Azure
- Connectivity from VM to Key Vault, VM to Azure AD, VM to Storage account.
Components:
- Azure App
- Key Vault
- VM
You can have multiple key vaults in your account, fit for purpose. You can create them in the UI if needed. Even if you use encryption on your storage account, bitlocker with key vault gives you that assurance that the VM cannot leave Azure. The key is in vault.
In the context of secrets: Azure Key Vault is a secret store: a centralized cloud service for storing application secrets - configuration values like passwords and connection strings that must remain secure at all times. Key Vault helps you control your applications’ secrets by keeping them in a single central location and providing secure access, permissions control, and access logging.
IAM
There are a stack of built in roles, and the ability to customize them or create new ones - but there is also a wizard to show exactly what things a particular principal can do based on their role assignments.
Access to a key vault is controlled through two interfaces: the management plane and the data plane. The management plane is where you manage Key Vault itself. Operations in this plane include creating and deleting key vaults, retrieving Key Vault properties, and updating access policies. The data plane is where you work with the data stored in a key vault. You can add, delete, and modify keys, secrets, and certificates.
To access a key vault in either plane, all callers (users or applications) must have proper authentication and authorization. Authentication establishes the identity of the caller. Authorization determines which operations the caller can execute.
Both planes use Azure Active Directory (Azure AD) for authentication. For authorization, the management plane uses role-based access control (RBAC) and the data plane uses a Key Vault access policy.
Logging
Key vault builds activity logs. Very granular logging with search built in to the console. You can access your logging information 10 minutes (at most) after the key vault operation. In most cases, it will be quicker than this. You can access your logging information 10 minutes (at most) after the key vault operation. In most cases, it will be quicker than this.
Creating a Key Vault
The actual command (you need to do other things first):
PS C:\Users\ChadDuffey> New-AzureRmKeyVault -VaultName $kvName -ResourceGroupName $rgName -Location $location
Vault Name : duffKV
Resource Group Name : duffRG
Location : West US
Resource ID : /subscriptions/a/resourceGroups/duffRG/providers/Microsoft.KeyVault/vaults/duffKV
Vault URI : https://duffkv.vault.azure.net/
Tenant ID :
SKU : Standard
Enabled For Deployment? : False
Enabled For Template Deployment? : False
Enabled For Disk Encryption? : False
Soft Delete Enabled? :
Access Policies :
Tenant ID :
Object ID :
Application ID :
Display Name : Chad Duffey (chad@chadduffey.com)
Permissions to Keys : get, create, delete, list, update, import, backup, restore, recover
Permissions to Secrets : get, list, set, delete, backup, restore, recover
Permissions to Certificates : get, delete, list, create, import, update, deleteissuers, getissuers, listissuers, managecontacts,
manageissuers, setissuers, recover, backup, restore
Permissions to (Key Vault Managed) Storage : delete, deletesas, get, getsas, list, listsas, regeneratekey, set, setsas, update, recover, backup,
restore
Network Rule Set :
Default Action : Allow
Bypass : AzureServices
IP Rules :
Virtual Network Rules :
Tags :
PS C:\Users\ChadDuffey>
A better script to create a Key Vault and Azure App:
$kvName = 'duffKV'
$rgName = 'duffRG'
$location = 'West US'
$aadClientSecret = 'duffClientSecret123'
$appDisplayName = 'duffEncryptApp'
#Connect-AzureRmAccount -Subscription XXXXXXX
New-AzureRmResourceGroup -Name $rgName -Location $location
New-AzureRmKeyVault -VaultName $kvName -ResourceGroupName $rgName -Location $location
Set-AzureRmKeyVaultAccessPolicy -VaultName $kvName -ResourceGroupName $rgName -EnabledForDiskEncryption
$secureaadClientSecret = ConvertTo-SecureString $aadClientSecret -AsPlainText -Force
$aadApp = New-AzureRmADApplication -DisplayName $appDisplayName -HomePage 'http://homepageduffEncryptApp' -IdentifierUris 'http://uriduffEncryptApp' -Password $secureaadClientSecret
$appID = $aadApp.ApplicationId
$aadServicePrincipal = New-AzureRmADServicePrincipal -ApplicationId $appID
Set-AzureRmKeyVaultAccessPolicy -VaultName $kvName -ServicePrincipalName $appID `
-PermissionsToKeys decrypt,encrypt,unwrapKey,wrapKey,verify,sign,get,list,update,create,import,delete,backup,restore,recover,purge `
-PermissionsToSecrets get, list, set, delete, backup, restore, recover, purge
Bitlocker integration
Generation 2 VMs do not yet support some Azure platform features, including Azure Disk Encryption.
When we first build a VM:
To encrypt, we add the following to our script:
$vmName = 'plazVM'
$kv = Get-AzureRmKeyVault -VaultName $kvName -ResourceGroupName $rgName
$kvUri = $kv.VaultUri
$kvRID = $kv.ResourceId
Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $rgName -VMName $vmName -AadClientID $appID -AadClientSecret $aadClientSecret -DiskEncryptionKeyVaultUrl $kvUri -DiskEncryptionKeyVaultId $kvRID
PowerShell will let you know that you have a 10-15 minute wait coming up.
We could also do the data disks:
$kv = Get-AzureRmKeyVault -VaultName $kvName -ResourceGroupName $rgName
$kvUri = $kv.VaultUri
$kvRID = $kv.ResourceId
$aadApp = Get-AzureRmADApplication -DisplayName $appDisplayName
$appID = $aadApp.ApplicationId
Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $rgName -VMName $vmName -AadClientID $appID -AadClientSecret $aadClientSecret -DiskEncryptionKeyVaultUrl $kvUri -DiskEncryptionKeyVaultId $kvRID -VolumeType Data
Get-AzureRmVMDiskEncryptionStatus -VMName $vmName -ResourceGroupName $rgName
Here’s a gotcha! Not all VM types support encryption:
Set-AzureRmVMDiskEncryptionExtension : VM size is Basic_A1. Disk encryption is not supported for Basic Family VM sizes currently.
ErrorCode: NotSupported
ErrorMessage: VM size is Basic_A1. Disk encryption is not supported for Basic Family VM sizes currently.
ErrorTarget:
StatusCode: 409
ReasonPhrase: Conflict
OperationID : 75a81ea3-a426-4c16-981c-ded861fb876b
And a second one, VM and Key Vault need to be in the same region:
Set-AzureRmVMDiskEncryptionExtension : Long running operation failed with status 'Failed'. Additional Info:'The Key Vault
https://duffkv.vault.azure.net/secrets/FCC65FF0-B580-42F5-828A-3B100D905FDE/40f226f47b2a40ff832cb7bc030ec653 is located in location West US, which is different from the location of the
VM, westus2. The VM and Key Vault need to be located within the same region.'
ErrorCode: KeyVaultAndVMInDifferentRegions
ErrorMessage: The Key Vault https://duffkv.vault.azure.net/secrets/FCC65FF0-B580-42F5-828A-3B100D905FDE/40f226f47b2a40ff832cb7bc030ec653 is located in location West US, which is
different from the location of the VM, westus2. The VM and Key Vault need to be located within the same region.
Here’s what it looks like when it goes well:
PS C:\Users\ChadDuffey> Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $rgName -VMName $vmName -AadClientID $appID -AadClientSecret $aadClientSecret -DiskEncryptionKeyVaultUrl $kvUri -DiskEncryptionKeyVaultId $kvRID
RequestId IsSuccessStatusCode StatusCode ReasonPhrase
--------- ------------------- ---------- ------------
True OK OK
Quickstart Templates
Quickstart templates: https://github.com/Azure/azure-quickstart-templates Specifically: https://github.com/Azure/azure-quickstart-templates/tree/master/201-encrypt-create-new-vm-gallery-image Check out the “Deploy to Azure” button. Hot.
Deploying Certificates via Key Vault
(Gary Grudzinskas script for:) Deploying Certificates into Key Vault for distribution:
$secretName = "CertVM"
$certPassword = "CertPW"
$fileName = "CertVM.pfx"
$fileContentBytes = Get-Content $fileName -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)
$secret = ConvertTo-SecureString -String $jsonEncoded -AsPlainText –Force
Set-AzureKeyVaultSecret -VaultName $kvName -Name $secretName -SecretValue $secret
Then: https://github.com/Azure/azure-quickstart-templates/tree/master/201-vm-push-certificate-windows. This will run you through the configuration that will allow a certificate to be pushed right into the personal store inside the image. That is, we can deploy certificates using Azure.
Custom Secrets with Key vault
Say i had to store the setup password for a machine:
az keyvault secret set --name WVD-Machine001 --value 5645342anbt12 --vault-name duffKV
or with PowerShell module:
$Secret = ConvertTo-SecureString -String 'Password123' -AsPlainText -Force
Set-AzureKeyVaultSecret -VaultName 'duffkv' -Name 'WVD-Machine123' -SecretValue $Secret
Output:
{
"attributes": {
"created": "2020-03-22T19:42:22+00:00",
"enabled": true,
"expires": null,
"notBefore": null,
"recoveryLevel": "Purgeable",
"updated": "2020-03-22T19:42:22+00:00"
},
"contentType": null,
"id": "https://duffkv.vault.azure.net/secrets/WVD-Machine001/df3e6bfcb4334d0ab74fa176c98d22ac",
"kid": null,
"managed": null,
"tags": {
"file-encoding": "utf-8"
},
"value": "5645342anbt12"
}
Notice how we can even set expiration on the secrets. Hot.