使用 PowerShell 为Azure托管磁盘启用客户管理的密钥

适用于: ✔️ Windows VM ✔️ 灵活规模集 ✔️ 统一规模集

Azure 磁盘存储支持使用托管磁盘的客户管理的密钥进行服务器端加密(SSE)。 有关客户管理的密钥和其他托管磁盘加密类型的概念性信息,请参阅 客户管理的密钥。

限制

目前,客户托管密钥具有以下限制:

  • 如果为具有增量快照的磁盘启用了此功能,则不能在该磁盘或其快照上禁用此功能。 要解决此问题,请将所有数据复制到完全不同的、不使用客户管理的密钥的托管磁盘。 可以使用 Azure CLI 或 Azure PowerShell 模块执行此操作。
  • 磁盘及其关联的所有增量快照都必须具有相同的磁盘加密设置。
  • 仅支持大小为 2,048 位、3,072 位和 4,096 位的软件密钥和 HSM RSA 密钥,不支持其他密钥或其他大小。
    • HSM 密钥需要 Azure 密钥保管库的“高级”层。
  • 仅适用于超级磁盘和高级 SSD v2 磁盘:
    • (预览版)用户分配的托管标识适用于使用客户管理的密钥加密的超级磁盘和高级 SSD v2 磁盘。
  • 与客户管理的密钥相关的大部分资源(磁盘加密集、虚拟机、磁盘和快照)都必须位于同一订阅和区域中。
    • Azure 密钥保管库可以在不同的订阅中使用,但必须与磁盘加密集位于同一区域中。
  • 使用客户管理的密钥加密的磁盘只能在附加到的 VM 解除分配时移动到另一个资源组。
  • 无法在不同订阅间移动使用客户管理的密钥加密的磁盘、快照和映像。
  • 当前或以前使用 Azure 磁盘加密加密的托管磁盘不能使用客户管理的密钥进行加密。
  • 每个区域、每个订阅最多只能创建 5000 个磁盘加密集。
  • 有关将客户托管密钥与共享映像库结合使用的信息,请参阅预览版:使用客户托管密钥加密映像。

设置 Azure 密钥保管库 和磁盘加密集,并启用自动密钥轮换

若要将客户管理密钥用于服务器端加密,请设置一个 Azure 密钥保管库 和一个磁盘加密集。

  1. 安装最新的Azure PowerShell版本,并使用 Azure 帐户Connect-AzAccount登录。

  2. 创建 Azure 密钥保管库 和加密密钥的实例。

    创建 密钥保管库 实例时,必须启用清除保护。 清除保护可确保在保留期结束之前,无法永久删除已删除的密钥。 这些设置可防止由于意外删除而丢失数据。 使用 密钥保管库 加密托管磁盘时,这些设置是必需的。

    $ResourceGroupName="yourResourceGroupName"
    $LocationName="chinaeast2"
    $keyVaultName="yourKeyVaultName"
    $keyName="yourKeyName"
    $keyDestination="Software"
    $diskEncryptionSetName="yourDiskEncryptionSetName"
    
    $keyVault = New-AzKeyVault -Name $keyVaultName `
    -ResourceGroupName $ResourceGroupName `
    -Location $LocationName `
    -EnablePurgeProtection
    
    $key = Add-AzKeyVaultKey -VaultName $keyVaultName `
          -Name $keyName `
          -Destination $keyDestination
    
    Set-AzKeyVaultKeyRotationPolicy -VaultName $keyVaultName -KeyName $keyName -ExpiresIn P2Y -KeyRotationLifetimeAction @{Action="Rotate";TimeBeforeExpiry = "P18M"}
    
  3. 创建磁盘加密集。 此脚本将 RotationToLatestKeyVersionEnabled 设置为等于 $true 以启用密钥的自动轮换。 启用自动轮换后,系统将自动更新引用该磁盘加密集的所有托管磁盘、快照和映像,以便在一小时内使用新版本密钥。

    $desConfig=New-AzDiskEncryptionSetConfig -Location $LocationName `
        -SourceVaultId $keyVault.ResourceId `
        -KeyUrl $key.Key.Kid `
        -IdentityType SystemAssigned `
        -RotationToLatestKeyVersionEnabled $true
    
    $des=New-AzDiskEncryptionSet -Name $diskEncryptionSetName `
           -ResourceGroupName $ResourceGroupName `
           -InputObject $desConfig
    
  4. 授予磁盘加密集对密钥保管库的访问权限。

    注意

    Azure 可能需要几分钟时间才能在 Microsoft Entra ID 中创建磁盘加密集的标识。 如果在运行以下命令时收到类似于“找不到 Active Directory 对象”的错误,请等待几分钟,然后重试。

    Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $des.Identity.PrincipalId -PermissionsToKeys wrapkey,unwrapkey,get
    

在不同的订阅中使用密钥保管库

或者,可以从单个订阅集中管理 Azure 密钥保管库,并使用 密钥保管库 中存储的密钥来加密组织的其他订阅中的托管磁盘和快照。 这样,安全团队就可以对单个订阅强制实施和轻松管理可靠的安全策略。

重要

对于此配置,密钥保管库 和磁盘加密集必须位于同一区域并使用同一租户。

下面的脚本是一个示例,说明如何配置磁盘加密集以使用来自不同订阅但相同区域的 密钥保管库 的密钥:

$sourceSubscriptionId="<sourceSubID>"
$sourceKeyVaultName="<sourceKVName>"
$sourceKeyName="<sourceKeyName>"

$targetSubscriptionId="<targetSubID>"
$targetResourceGroupName="<targetRGName>"
$targetDiskEncryptionSetName="<targetDiskEncSetName>"
$location="<targetRegion>"

Set-AzContext -Subscription $sourceSubscriptionId

$key = Get-AzKeyVaultKey -VaultName $sourceKeyVaultName -Name $sourceKeyName

Set-AzContext -Subscription $targetSubscriptionId

$desConfig=New-AzDiskEncryptionSetConfig -Location $location `
-KeyUrl $key.Key.Kid `
-IdentityType SystemAssigned `
-RotationToLatestKeyVersionEnabled $true

$des=New-AzDiskEncryptionSet -Name $targetDiskEncryptionSetName `
-ResourceGroupName $targetResourceGroupName `
-InputObject $desConfig

使用 PowerShell 管理Azure托管磁盘的客户管理的密钥

创建和配置所需的资源后,请使用以下示例Azure PowerShell脚本创建加密的 VM 和磁盘、加密现有托管磁盘和规模集、轮换磁盘加密密钥以及检查磁盘的服务器端加密状态。

使用市场映像创建 VM,并使用客户托管密钥加密 OS 和数据磁盘

在运行脚本之前,请指定现有的资源组和磁盘加密集,以及虚拟机管理员凭据、区域、虚拟机大小和虚拟网络的值。 该脚本从Windows Server市场映像创建虚拟网络、网络接口和 VM。 它使用 Get-AzDiskEncryptionSet 来获取磁盘加密集,并使用 New-AzVM 来创建具有加密 OS 磁盘和 128 GiB 加密数据磁盘的 VM。 将示例值替换为自己的参数,然后运行脚本。

$VMLocalAdminUser = "yourVMLocalAdminUserName"
$VMLocalAdminSecurePassword = ConvertTo-SecureString <password> -AsPlainText -Force
$LocationName = "yourRegion"
$ResourceGroupName = "yourResourceGroupName"
$ComputerName = "yourComputerName"
$VMName = "yourVMName"
$VMSize = "yourVMSize"
$diskEncryptionSetName="yourdiskEncryptionSetName"

$NetworkName = "yourNetworkName"
$NICName = "yourNICName"
$SubnetName = "yourSubnetName"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"

$SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet
$NIC = New-AzNetworkInterface -Name $NICName -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[0].Id

$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);

$VirtualMachine = New-AzVMConfig -VMName $VMName -VMSize $VMSize
$VirtualMachine = Set-AzVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $ComputerName -Credential $Credential -ProvisionVMAgent -EnableAutoUpdate
$VirtualMachine = Add-AzVMNetworkInterface -VM $VirtualMachine -Id $NIC.Id
$VirtualMachine = Set-AzVMSourceImage -VM $VirtualMachine -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' -Skus '2012-R2-Datacenter' -Version latest

$diskEncryptionSet=Get-AzDiskEncryptionSet -ResourceGroupName $ResourceGroupName -Name $diskEncryptionSetName

$VirtualMachine = Set-AzVMOSDisk -VM $VirtualMachine -Name $($VMName +"_OSDisk") -DiskEncryptionSetId $diskEncryptionSet.Id -CreateOption FromImage

$VirtualMachine = Add-AzVMDataDisk -VM $VirtualMachine -Name $($VMName +"DataDisk1") -DiskSizeInGB 128 -StorageAccountType Premium_LRS -CreateOption Empty -Lun 0 -DiskEncryptionSetId $diskEncryptionSet.Id 

New-AzVM -ResourceGroupName $ResourceGroupName -Location $LocationName -VM $VirtualMachine -Verbose

创建一个使用客户托管密钥的服务器端加密的空磁盘,并将其附加到 VM

该脚本使用 Add-AzVMDataDisk 将加密数据磁盘添加到 VM 配置中,并使用 Update-AzVM 应用该配置。 将示例值替换为自己的参数,然后运行脚本。

$vmName = "yourVMName"
$LocationName = "chinaeast2"
$ResourceGroupName = "yourResourceGroupName"
$diskName = "yourDiskName"
$diskSKU = "Premium_LRS"
$diskSizeinGiB = 30
$diskLUN = 1
$diskEncryptionSetName="yourDiskEncryptionSetName"


$vm = Get-AzVM -Name $vmName -ResourceGroupName $ResourceGroupName 

$diskEncryptionSet=Get-AzDiskEncryptionSet -ResourceGroupName $ResourceGroupName -Name $diskEncryptionSetName

$vm = Add-AzVMDataDisk -VM $vm -Name $diskName -CreateOption Empty -DiskSizeInGB $diskSizeinGiB -StorageAccountType $diskSKU -Lun $diskLUN -DiskEncryptionSetId $diskEncryptionSet.Id 

Update-AzVM -ResourceGroupName $ResourceGroupName -VM $vm

加密现有托管磁盘

现有磁盘不得附加到正在运行的 VM。 该脚本使用 New-AzDiskUpdateConfig 和 Update-AzDisk 配置磁盘的客户管理的密钥。

$rgName = "yourResourceGroupName"
$diskName = "yourDiskName"
$diskEncryptionSetName = "yourDiskEncryptionSetName"

$diskEncryptionSet = Get-AzDiskEncryptionSet -ResourceGroupName $rgName -Name $diskEncryptionSetName

New-AzDiskUpdateConfig -EncryptionType "EncryptionAtRestWithCustomerKey" -DiskEncryptionSetId $diskEncryptionSet.Id | Update-AzDisk -ResourceGroupName $rgName -DiskName $diskName

使用服务器端加密和客户管理的密钥加密现有虚拟机规模集(统一业务流程模式)

此脚本只在统一业务流程模式下对规模集有效。 对于在灵活编排模式下的规模集,请遵循“加密每个 VM 的现有托管磁盘”的步骤进行操作。

该脚本使用 Get-AzVmss 检索虚拟机规模集,并使用 Update-AzVmss 应用磁盘加密集设置。 将示例值替换为自己的参数,然后运行脚本。

#set variables 
$vmssname = "name of the vmss that is already created"
$diskencryptionsetname = "name of the diskencryptionset already created"
$vmssrgname = "vmss resourcegroup name"
$diskencryptionsetrgname = "diskencryptionset resourcegroup name"

#get vmss object and create diskencryptionset object attach to vmss os disk
$ssevmss = get-azvmss -ResourceGroupName $vmssrgname -VMScaleSetName $vmssname
$ssevmss.VirtualMachineProfile.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet = New-Object -TypeName Microsoft.Azure.Management.Compute.Models.DiskEncryptionSetParameters

#get diskencryption object and retrieve the resource id
$des = Get-AzDiskEncryptionSet -ResourceGroupName $diskencryptionsetrgname -Name $diskencryptionsetname
write-host "the diskencryptionset resource id is:" $des.Id

#associate DES resource id to os disk and update vmss 
$ssevmss.VirtualMachineProfile.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet.id = $des.Id
$ssevmss | update-azvmss

使用 Marketplace 映像创建虚拟机规模集,使用客户托管密钥加密操作系统和数据磁盘

在运行脚本之前,请提供现有的资源组和磁盘加密集,以及管理员凭据、区域、虚拟机大小和虚拟网络的相关值。 该脚本创建虚拟网络,并使用New-AzVmss从 Windows Server Marketplace 映像创建包含两个实例的统一虚拟机规模集。 规模集的操作系统磁盘和 128 GiB 的数据磁盘使用磁盘加密集。 将示例值替换为自己的参数,然后运行脚本。

重要

从 2023 年 11 月开始,使用 PowerShell 和 Azure CLI 创建的 VM 规模集将默认为灵活业务流程模式(如果未指定业务流程模式)。 若要详细了解此更改以及你应采取哪些操作,请访问针对 VMSS PowerShell/CLI 客户的重大变更 - Microsoft 社区中心

$VMLocalAdminUser = "yourLocalAdminUser"
$VMLocalAdminSecurePassword = ConvertTo-SecureString Password@123 -AsPlainText -Force
$LocationName = "chinaeast2"
$ResourceGroupName = "yourResourceGroupName"
$ComputerNamePrefix = "yourComputerNamePrefix"
$VMScaleSetName = "yourVMSSName"
$VMSize = "Standard_DS3_v2"
$diskEncryptionSetName="yourDiskEncryptionSetName"

$NetworkName = "yourVNETName"
$SubnetName = "yourSubnetName"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"

$SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix

$Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet

$ipConfig = New-AzVmssIpConfig -Name "myIPConfig" -SubnetId $Vnet.Subnets[0].Id 

$VMSS = New-AzVmssConfig -Location $LocationName -SkuCapacity 2 -SkuName $VMSize -UpgradePolicyMode 'Automatic' -OrchestrationMode 'Uniform'

$VMSS = Add-AzVmssNetworkInterfaceConfiguration -Name "myVMSSNetworkConfig" -VirtualMachineScaleSet $VMSS -Primary $true -IpConfiguration $ipConfig

$diskEncryptionSet=Get-AzDiskEncryptionSet -ResourceGroupName $ResourceGroupName -Name $diskEncryptionSetName

# Enable encryption at rest with customer managed keys for OS disk by setting DiskEncryptionSetId property 

$VMSS = Set-AzVmssStorageProfile $VMSS -OsDiskCreateOption "FromImage" -DiskEncryptionSetId $diskEncryptionSet.Id -ImageReferenceOffer 'WindowsServer' -ImageReferenceSku '2012-R2-Datacenter' -ImageReferenceVersion latest -ImageReferencePublisher 'MicrosoftWindowsServer'

$VMSS = Set-AzVmssOsProfile $VMSS -ComputerNamePrefix $ComputerNamePrefix -AdminUsername $VMLocalAdminUser -AdminPassword $VMLocalAdminSecurePassword

# Add a data disk encrypted at rest with customer managed keys by setting DiskEncryptionSetId property 

$VMSS = Add-AzVmssDataDisk -VirtualMachineScaleSet $VMSS -CreateOption Empty -Lun 1 -DiskSizeGB 128 -StorageAccountType Premium_LRS -DiskEncryptionSetId $diskEncryptionSet.Id

$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);

New-AzVmss -VirtualMachineScaleSet $VMSS -ResourceGroupName $ResourceGroupName -VMScaleSetName $VMScaleSetName

更改磁盘加密集的密钥,以轮换其所引用资源的密钥

该脚本使用 Update-AzDiskEncryptionSet 来更改磁盘加密集所引用的密钥。 将示例值替换为自己的参数,然后运行脚本。

$ResourceGroupName="yourResourceGroupName"
$keyVaultName="yourKeyVaultName"
$keyName="yourKeyName"
$diskEncryptionSetName="yourDiskEncryptionSetName"

$keyVault = Get-AzKeyVault -VaultName $keyVaultName -ResourceGroupName $ResourceGroupName

$keyVaultKey = Get-AzKeyVaultKey -VaultName $keyVaultName -Name $keyName

Update-AzDiskEncryptionSet -Name $diskEncryptionSetName -ResourceGroupName $ResourceGroupName -SourceVaultId $keyVault.ResourceId -KeyUrl $keyVaultKey.Id

查找磁盘的服务器端加密状态

该脚本用于 Get-AzDisk 检索磁盘的服务器端加密类型。

$ResourceGroupName="yourResourceGroupName"
$DiskName="yourDiskName"

$disk=Get-AzDisk -ResourceGroupName $ResourceGroupName -DiskName $DiskName
$disk.Encryption.Type

对于上述示例配置的磁盘, EncryptionAtRestWithCustomerKey 指示使用客户管理的密钥进行服务器端加密。 EncryptionAtRestWithPlatformAndCustomerKeys 指示使用客户管理的密钥和平台管理的密钥进行双重加密。

重要

客户管理的密钥依赖于 Azure 资源的托管标识,后者是 Microsoft Entra ID 的一项功能。 配置客户托管密钥时,默认情况下会自动将托管身份分配给你的资源。 如果随后在两个 Microsoft Entra 目录之间移动订阅、资源组或托管磁盘,则与托管磁盘关联的托管标识不会转移到新租户,因此客户管理的密钥可能不再有效。 有关详细信息,请参阅在 Microsoft Entra 目录之间转移订阅。

后续步骤