How to encrypt & Disable virtual disks on a Windows VM using Power Shell
Azure Disk Encryption (ADE) leverages the industry standard BitLocker feature of Windows and the DM-Crypt feature of Linux to provide OS and data disk encryption to help protect and safeguard your data and help meet your organizational security and compliance commitments in customer Azure key vault.
|
When you need encryption to be enabled on a running virtual machine in Azure,
Azure Disk Encryption generates and writes the BitLocker encryption keys to an Azure key vault.
And we can execute this entire process in two fairly simple high level steps.
Managing those encryption keys in your key vault requires Azure AD authentication.
And for that purpose,
we have to create an Azure AD application,
and for authentication purposes
we can either use client secret based authentication or client certificate based Azure AD authentication.
For enhanced virtual machine (VM) security and compliance, virtual disks in Azure can be encrypted.
Disks are encrypted using cryptographic keys that are secured in an Azure Key Vault.
You control these cryptographic keys and can audit their use.
This article details how to encrypt virtual disks on a Windows VM using Azure PowerShell. You can also encrypt a Linux VM using the Azure CLI 2.0.
Overview of disk encryption
==========================
Virtual disks on Windows VMs are encrypted at rest using Bitlocker.
Secure Azure virtual machines and disks
Again, In Azure we have the ability to secure
our virtual machines and the disk. When we encrypt our Azure Virtual
Machines, we encrypt both the OS and data disk at rest. Our Windows
Virtual Machines are encrypted using BitLocker and the Linux Virtual
Machines are encrypted using dm-crypt. And this process uses the Azure Key
Vault.
But before you start
encrypting all your virtual machines, there are few things you need to be
aware of. First, we can only encrypt our standard virtual
machines. Our basic virtual machines cannot be encrypted.
And only virtual machines that
have been created in the Azure Resource Manager or ARM portal can be
encrypted. Your server has to be at least a Server 2008 R2 and above
to be encrypted. And for those of you who are running desktop clients
in Azure, only Windows 8 and Windows 10 clients can also be encrypted.
You must make sure your
Key Vault and your virtual machines are in the same region and in the same
subscription.
Let's take a look at the Encryption
Workflow.
We as the administrator send
the PowerShell cmdlet to encrypt our virtual machine. Within Azure
storage, the OS and the data disk are also encrypted. And the
encryption keys are kept in the key vault. And these keys are written to
the key vault by an application.
There is no charge for encrypting virtual disks in Azure.
1.Cryptographic keys are stored in Azure Key Vault using software-protection, or you can import or generate your keys in Hardware Security Modules (HSMs) certified to FIPS 140-2 level 2 standards. These cryptographic keys are used to encrypt and decrypt virtual disks attached to your VM.
2.You retain control of these cryptographic keys and can audit their use.
An Azure Active Directory service principal provides a secure mechanism for issuing these cryptographic keys as VMs are powered on and off.
The process for encrypting a VM is as follows:-
----------------------------------------------------------- Create a cryptographic key in an Azure Key Vault.
- Configure the cryptographic key to be usable for encrypting disks.
- To read the cryptographic key from the Azure Key Vault, create an Azure Active Directory service principal with the appropriate permissions.
- Issue the command to encrypt your virtual disks, specifying the Azure Active Directory service principal and appropriate cryptographic key to be used.
- The Azure Active Directory service principal requests the required cryptographic key from Azure Key Vault.
- The virtual disks are encrypted using the provided cryptographic key.
The OS disk is not encrypted initially as shown in the figure below..
you can refer below blog to understand the logic.
https://docs.microsoft.com/en-us/azure/virtual-machines/windows/encrypt-disks
Disk encryption relies on the following additional components:
1. Azure Key Vault - used to safeguard cryptographic keys and secrets used for the disk encryption/decryption process.
If one exists, you can use an existing Azure Key Vault. You do not have to dedicate a Key Vault to encrypting disks.
To separate administrative boundaries and key visibility, you can create a dedicated Key Vault.
2.Azure Active Directory - handles the secure exchanging of required cryptographic keys and authentication for requested actions.
You can typically use an existing Azure Active Directory instance for housing your application.
The service principal provides a secure mechanism to request and be issued the appropriate cryptographic keys. You are not developing an actual application that integrates with Azure Active Directory.
if working on existing VM, ensure that VM is up and working fine.
Param(
[Parameter(Mandatory = $true,
HelpMessage="Name of the resource group to which the KeyVault belongs to. A new resource group with this name will be created if one doesn't exist")]
[ValidateNotNullOrEmpty()]
[string]$resourceGroupName,
[Parameter(Mandatory = $true,
HelpMessage="Name of the KeyVault in which encryption keys are to be placed. A new vault with this name will be created if one doesn't exist")]
[ValidateNotNullOrEmpty()]
[string]$keyVaultName,
[Parameter(Mandatory = $true,
HelpMessage="Location of the KeyVault. Important note: Make sure the KeyVault and VMs to be encrypted are in the same region / location.")]
[ValidateNotNullOrEmpty()]
[string]$location,
[Parameter(Mandatory = $true,
HelpMessage="Name of the AAD application that will be used to write secrets to KeyVault. A new application with this name will be created if one doesn't exist. If this app already exists, pass aadClientSecret parameter to the script")]
[ValidateNotNullOrEmpty()]
[string]$aadAppName,
[Parameter(Mandatory = $false,
HelpMessage="Client secret of the AAD application that was created earlier")]
[ValidateNotNullOrEmpty()]
[string]$aadClientSecret,
[Parameter(Mandatory = $false,
HelpMessage="Identifier of the Azure subscription to be used. Default subscription will be used if not specified.")]
[ValidateNotNullOrEmpty()]
[string]$subscriptionId,
[Parameter(Mandatory = $false,
HelpMessage="Name of optional key encryption key in KeyVault. A new key with this name will be created if one doesn't exist")]
[ValidateNotNullOrEmpty()]
[string]$keyEncryptionKeyName
)
########################################################################################################################
# Section1: Log-in to Azure and select appropriate subscription.
########################################################################################################################
Write-Host 'Please log into Azure now' -foregroundcolor Green;
Login-AzureRmAccount -ErrorAction "Stop" 1> $null;
if($subscriptionId)
{
Select-AzureRmSubscription -SubscriptionId $subscriptionId;
}
########################################################################################################################
# Section2: Create AAD app . Fill in $aadClientSecret variable if AAD app was already created
########################################################################################################################
# Check if AAD app with $aadAppName was already created
$SvcPrincipals = (Get-AzureRmADServicePrincipal -SearchString $aadAppName);
if(-not $SvcPrincipals)
{
# Create a new AD application if not created before
$identifierUri = [string]::Format("http://localhost:8080/{0}",[Guid]::NewGuid().ToString("N"));
$defaultHomePage = 'http://contoso.com';
$now = [System.DateTime]::Now;
$oneYearFromNow = $now.AddYears(1);
$aadClientSecret = [Guid]::NewGuid();
Write-Host "Creating new AAD application ($aadAppName)";
$ADApp = New-AzureRmADApplication -DisplayName $aadAppName -HomePage $defaultHomePage -IdentifierUris $identifierUri -StartDate $now -EndDate $oneYearFromNow -Password $aadClientSecret;
$servicePrincipal = New-AzureRmADServicePrincipal -ApplicationId $ADApp.ApplicationId;
$SvcPrincipals = (Get-AzureRmADServicePrincipal -SearchString $aadAppName);
if(-not $SvcPrincipals)
{
# AAD app wasn't created
Write-Error "Failed to create AAD app $aadAppName. Please log-in to Azure using Login-AzureRmAccount and try again";
return;
}
$aadClientID = $servicePrincipal.ApplicationId;
Write-Host "Created a new AAD Application ($aadAppName) with ID: $aadClientID ";
}
else
{
if(-not $aadClientSecret)
{
$aadClientSecret = Read-Host -Prompt "Aad application ($aadAppName) was alerady created, input corresponding aadClientSecret and hit ENTER. It can be retrieved from https://manage.windowsazure.com portal" ;
}
if(-not $aadClientSecret)
{
Write-Error "Aad application ($aadAppName) was alerady created. Re-run the script by supplying aadClientSecret parameter with corresponding secret from https://manage.windowsazure.com portal";
return;
}
$aadClientID = $SvcPrincipals[0].ApplicationId;
}
# Before proceeding to Section3, make sure $aadClientID and $aadClientSecret have valid values
########################################################################################################################
# Section3: Create KeyVault or setup existing keyVault
########################################################################################################################
Try
{
$resGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue;
}
Catch [System.ArgumentException]
{
Write-Host "Couldn't find resource group: ($resourceGroupName)";
$resGroup = $null;
}
#Create a new resource group if it doesn't exist
if (-not $resGroup)
{
Write-Host "Creating new resource group: ($resourceGroupName)";
$resGroup = New-AzureRmResourceGroup -Name $resourceGroupName -Location $location;
Write-Host "Created a new resource group named $resourceGroupName to place keyVault";
}
Try
{
$keyVault = Get-AzureRmKeyVault -VaultName $keyVaultName -ErrorAction SilentlyContinue;
}
Catch [System.ArgumentException]
{
Write-Host "Couldn't find Key Vault: $keyVaultName";
$keyVault = $null;
}
#Create a new vault if vault doesn't exist
if (-not $keyVault)
{
Write-Host "Creating new key vault: ($keyVaultName)";
$keyVault = New-AzureRmKeyVault -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -Sku Standard -Location $location;
Write-Host "Created a new KeyVault named $keyVaultName to store encryption keys";
}
# Specify privileges to the vault for the AAD application - https://msdn.microsoft.com/en-us/library/mt603625.aspx
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -ServicePrincipalName $aadClientID -PermissionsToKeys wrapKey -PermissionsToSecrets set;
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -EnabledForDiskEncryption;
$diskEncryptionKeyVaultUrl = $keyVault.VaultUri;
$keyVaultResourceId = $keyVault.ResourceId;
if($keyEncryptionKeyName)
{
Try
{
$kek = Get-AzureKeyVaultKey -VaultName $keyVaultName -Name $keyEncryptionKeyName -ErrorAction SilentlyContinue;
}
Catch [Microsoft.Azure.KeyVault.KeyVaultClientException]
{
Write-Host "Couldn't find key encryption key named : $keyEncryptionKeyName in Key Vault: $keyVaultName";
$kek = $null;
}
if(-not $kek)
{
Write-Host "Creating new key encryption key named:$keyEncryptionKeyName in Key Vault: $keyVaultName";
$kek = Add-AzureKeyVaultKey -VaultName $keyVaultName -Name $keyEncryptionKeyName -Destination Software -ErrorAction SilentlyContinue;
Write-Host "Created key encryption key named:$keyEncryptionKeyName in Key Vault: $keyVaultName";
}
$keyEncryptionKeyUrl = $kek.Key.Kid;
}
########################################################################################################################
# Section3: Displays values that should be used while enabling encryption. Please note these down
########################################################################################################################
Write-Host "Please note down below aadClientID, aadClientSecret, diskEncryptionKeyVaultUrl, keyVaultResourceId values that will be needed to enable encryption on your VMs " -foregroundcolor Green;
Write-Host "`t aadClientID: $aadClientID" -foregroundcolor Green;
Write-Host "`t aadClientSecret: $aadClientSecret" -foregroundcolor Green;
Write-Host "`t diskEncryptionKeyVaultUrl: $diskEncryptionKeyVaultUrl" -foregroundcolor Green;
Write-Host "`t keyVaultResourceId: $keyVaultResourceId" -foregroundcolor Green;
if($keyEncryptionKeyName)
{
Write-Host "`t keyEncryptionKeyURL: $keyEncryptionKeyUrl" -foregroundcolor Green;
}
Write-Host "Please Press [Enter] after saving values displayed above. They are needed to enable encryption using Set-AzureRmVmDiskEncryptionExtension cmdlet" -foregroundcolor Green;
Read-Host;
########################################################################################################################
# For each VM you want to encrypt, run the below cmdlet
$vmName = 'rakvmnode1';
Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $resourceGroupName -VMName $vmName -AadClientID $aadClientID -AadClientSecret $aadClientSecret -DiskEncryptionKeyVaultUrl $diskEncryptionKeyVaultUrl -DiskEncryptionKeyVaultId $keyVaultResourceId;
########################################################################################################################
Verify the disks are encrypted:-
Get-AzureRmVmDiskEncryptionStatus -ResourceGroupName $resourceGroupName -VMName $vmName
This indicates OS disk is encrypted.
Connect to the Virtual Machine and you will find the Machine C:\ drive is getting encrypted.
Encryption of the disk will take time.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
How to Disables encryption on an IaaS virtual machine.
$ResourceGroup = "datascienceRs"; -- Your Existing Resource group name where that machine resides
$VMName = "rakvmnode1";
Disable-AzureRMVMDiskEncryption -ResourceGroupName $ResourceGroup -VMName $vmName
This command will take some time and then you will get below Message.
RequestId IsSuccessStatusCode StatusCode ReasonPhrase
--------- ------------------- ---------- ------------
True OK OK
You will observed your disks started Decrypting..
Enable Azure Disk Encryption for Linux IaaS VMs:-
Thanks for Reading.