Поделиться через


Примеры скриптов шифрования дисков Azure

Это важно

Шифрование дисков Azure будет выведено из эксплуатации 15 сентября 2028 г. До этой даты вы можете продолжать использовать шифрование дисков Azure без нарушений. 15 сентября 2028 г. рабочие нагрузки с поддержкой ADE будут выполняться, но зашифрованные диски не смогут разблокироваться после перезагрузки виртуальной машины, что приведет к нарушению работы службы.

Используйте шифрование на узле для новых виртуальных машин. Все виртуальные машины с поддержкой ADE (включая резервные копии) должны перенестися в шифрование на узле до даты выхода на пенсию, чтобы избежать прерывания работы службы. Дополнительные сведения см. в статье "Миграция из шифрования дисков Azure в шифрование на узле ".

Область применения: ✔️ Виртуальные машины Windows

В этой статье приводятся примеры сценариев для подготовки предварительно зашифрованных виртуальных жестких дисков и других задач.

Примечание.

Если не указано иное, все скрипты относятся к последней версии Azure Disk Encryption (ADE) без AAD.

Примеры сценариев PowerShell для шифрования дисков Azure

  • Перечислите все зашифрованные виртуальные машины в вашей подписке

    Все виртуальные машины, зашифрованные с помощью ADE, и версию расширения во всех группах ресурсов в подписке можно найти с помощью этого скрипта PowerShell.

    Кроме того, эти командлеты отобразят все виртуальные машины, зашифрованные с помощью ADE (без версии расширения):

    $osVolEncrypted = {(Get-AzVMDiskEncryptionStatus -ResourceGroupName $_.ResourceGroupName -VMName $_.Name).OsVolumeEncrypted}
    $dataVolEncrypted= {(Get-AzVMDiskEncryptionStatus -ResourceGroupName $_.ResourceGroupName -VMName $_.Name).DataVolumesEncrypted}
    Get-AzVm | Format-Table @{Label="MachineName"; Expression={$_.Name}}, @{Label="OsVolumeEncrypted"; Expression=$osVolEncrypted}, @{Label="DataVolumesEncrypted"; Expression=$dataVolEncrypted}
    
  • Список всех зашифрованных экземпляров VMSS в вашей подписке

    Все экземпляры масштабируемых наборов виртуальных машин, зашифрованных с помощью ADE, и версия расширения могут быть найдены во всех группах ресурсов, присутствующих в подписке, с помощью этого скрипта PowerShell.

  • Перечисление секретов шифрования дисков для виртуальных машин в хранилище ключей

Get-AzKeyVaultSecret -VaultName $KeyVaultName | where {$_.Tags.ContainsKey('DiskEncryptionKeyFileName')} | format-table @{Label="MachineName"; Expression={$_.Tags['MachineName']}}, @{Label="VolumeLetter"; Expression={$_.Tags['VolumeLetter']}}, @{Label="EncryptionKeyURL"; Expression={$_.Id}}

Использование скрипта PowerShell для предварительных требований шифрования дисков Azure

Если вы уже знакомы с предварительными требованиями для шифрования дисков Azure, можно использовать сценарий PowerShell предварительных требований для шифрования дисков Azure. Пример использования этого сценария PowerShell см. в разделе Краткое руководство по шифрованию виртуальной машины. Вы можете удалить комментарии из раздела сценария, начиная со строки 211, чтобы шифровать все диски имеющихся виртуальных машин в имеющейся группе ресурсов.

В следующей таблице показано, какие параметры могут использоваться в сценарии PowerShell:

Параметр Описание Обязательный?
$resourceGroupName Имя группы ресурсов, к которой принадлежит KeyVault. При отсутствии группы ресурсов с таким именем — она будет создана. Истина
$keyVaultName Имя хранилища ключей, в котором будут размещаться ключи шифрования. Если хранилище с таким именем не существует, оно будет создано. Истина
$location Расположение хранилища ключей. Убедитесь, что хранилище ключей и виртуальные машины, которые предстоит зашифровать, находятся в одном расположении. Получите список локаций с помощью Get-AzLocation. Истина
$subscriptionId Идентификатор подписки Azure, который будет использоваться. Вы можете получить идентификатор подписки с помощью команды Get-AzSubscription. Истина
$aadAppName Имя приложения Microsoft Entra, которое будет использоваться для записи секретов в KeyVault. Будет создано приложение с таким именем (если оно еще не создано). Если это приложение уже есть, передайте параметр aadClientSecret в сценарий. Ложно
$aadClientSecret Секрет клиента приложения Microsoft Entra, созданного ранее. Ложно
$keyEncryptionKeyName Имя дополнительного ключа шифрования ключа в хранилище ключей. Если ключ с таким именем отсутствует, он будет создан. Ложно

Шаблоны Resource Manager

Шифрование или расшифровка виртуальных машин без приложения Microsoft Entra

Шифрование или расшифровка виртуальных машин с помощью приложения Microsoft Entra (предыдущий выпуск)

Подготовка предварительно зашифрованного виртуального жесткого диска Windows

В следующем разделе приведены инструкции по подготовке предварительно зашифрованного виртуального жесткого диска Windows к развертыванию в качестве зашифрованного виртуального жесткого диска в IaaS Azure. Используйте эти сведения, чтобы подготовить и загрузить новую виртуальную машину Windows (VHD) в Azure Site Recovery или Azure. Дополнительные сведения о подготовке и отправке виртуального жесткого диска см. в статье Отправка универсального диска VHD и создание виртуальных машин с его помощью в Azure.

Обновление групповой политики с целью разрешить защиту ОС без TPM

Настройте параметр групповой политики BitLocker, который называется Шифрование дисков BitLocker. Для этого выберите Политика локального компьютера>Конфигурация компьютера>Административные шаблоны>Компоненты Windows. Задайте для этого параметра такое значение: Диски операционной системы>Обязательная дополнительная проверка подлинности при запуске>Разрешить использование BitLocker без совместимого TPM, как показано на рисунке ниже.

Антивредоносное ПО Майкрософт в Azure

Установка компонентов BitLocker

Для Windows Server 2012 или более поздней версии используйте следующую команду.

dism /online /Enable-Feature /all /FeatureName:BitLocker /quiet /norestart

Для Windows Server 2008 R2 используйте следующую команду.

ServerManagerCmd -install BitLockers

Подготовьте том операционной системы для BitLocker с помощью bdehdcfg

Чтобы сжать раздел операционной системы и подготовить компьютер к использованию BitLocker, запустите компонент bdehdcfg.

bdehdcfg -target c: shrink -quiet

Защита тома операционной системы с помощью BitLocker

Используйте команду manage-bde, чтобы включить шифрование загрузочного тома с использованием внешнего ключевого защитника. Можно также на этот внешний диск или том поместить внешний ключ (BEK-файл). Шифрование будет включено для системного или загрузочного тома после перезагрузки.

manage-bde -on %systemdrive% -sk [ExternalDriveOrVolume]
reboot

Примечание.

Чтобы получить внешний ключ с использованием BitLocker, подготовьте виртуальную машину с отдельным виртуальным жестким диском для данных и ресурсов.

Загрузите зашифрованный виртуальный жесткий диск (VHD) в учетную запись хранения Azure

После включения шифрования BitLocker локальный зашифрованный виртуальный жесткий диск нужно загрузить в учетную запись для хранения.

    Add-AzVhd [-Destination] <Uri> [-LocalFilePath] <FileInfo> [[-NumberOfUploaderThreads] <Int32> ] [[-BaseImageUriToPatch] <Uri> ] [[-OverWrite]] [ <CommonParameters>]

Отправка секрета для предварительно зашифрованной виртуальной машины в хранилище ключей

Секрет шифрования дисков, полученный ранее, нужно отправить в хранилище ключей в качестве секрета. Для этого необходимо предоставить разрешение на набор секретов и разрешение на оболочку учетной записи, которая будет отправлять секреты.

# Typically, account Id is the user principal name (in user@domain.com format)
$upn = (Get-AzureRmContext).Account.Id
Set-AzKeyVaultAccessPolicy -VaultName $kvname -UserPrincipalName $acctid -PermissionsToKeys wrapKey -PermissionsToSecrets set

# In cloud shell, the account ID is a managed service identity, so specify the username directly
# $upn = "user@domain.com"
# Set-AzKeyVaultAccessPolicy -VaultName $kvname -UserPrincipalName $acctid -PermissionsToKeys wrapKey -PermissionsToSecrets set

# When running as a service principal, retrieve the service principal ID from the account ID, and set access policy to that
# $acctid = (Get-AzureRmContext).Account.Id
# $spoid = (Get-AzureRmADServicePrincipal -ServicePrincipalName $acctid).Id
# Set-AzKeyVaultAccessPolicy -VaultName $kvname -ObjectId $spoid -BypassObjectIdValidation -PermissionsToKeys wrapKey -PermissionsToSecrets set

Секрет дискового шифрования не шифруется с помощью KEK

Выполните командлет Set-AzKeyVaultSecret, чтобы установить секрет в вашем хранилище ключей. Парольную фразу можно закодировать в формате Base64, а затем отправить в хранилище ключей. Убедитесь также, что при создании секрета в хранилище ключей были установлены следующие теги.


 # This is the passphrase that was provided for encryption during the distribution installation
 $passphrase = "contoso-password"

 $tags = @{"DiskEncryptionKeyEncryptionAlgorithm" = "RSA-OAEP"; "DiskEncryptionKeyFileName" = "LinuxPassPhraseFileName"}
 $secretName = [guid]::NewGuid().ToString()
 $secretValue = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($passphrase))
 $secureSecretValue = ConvertTo-SecureString $secretValue -AsPlainText -Force

 $secret = Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $secretName -SecretValue $secureSecretValue -tags $tags
 $secretUrl = $secret.Id

На следующем шаге используйте $secretUrl, чтобы подключить диск ОС без использования KEK.

Секрет дискового шифрования, зашифрованный с помощью KEK

Перед передачей секрета в хранилище ключей его можно дополнительно зашифровать с помощью ключа шифрования ключей. Используйте API обертки для того, чтобы сначала зашифровать секрет с помощью ключа шифрования ключей. Выходное значение этой операции обертывания представляет собой строку URL, закодированную в формате base64, которую вы можете затем загрузить как секрет, используя командлет Set-AzKeyVaultSecret.

    # This is the passphrase that was provided for encryption during the distribution installation
    $passphrase = "contoso-password"

    Add-AzKeyVaultKey -VaultName $KeyVaultName -Name "keyencryptionkey" -Destination Software
    $KeyEncryptionKey = Get-AzKeyVaultKey -VaultName $KeyVault.OriginalVault.Name -Name "keyencryptionkey"

    $apiversion = "2015-06-01"

    ##############################
    # Get Auth URI
    ##############################

    $uri = $KeyVault.VaultUri + "/keys"
    $headers = @{}

    $response = try { Invoke-RestMethod -Method GET -Uri $uri -Headers $headers } catch { $_.Exception.Response }

    $authHeader = $response.Headers["www-authenticate"]
    $authUri = [regex]::match($authHeader, 'authorization="(.*?)"').Groups[1].Value

    Write-Host "Got Auth URI successfully"

    ##############################
    # Get Auth Token
    ##############################

    $uri = $authUri + "/oauth2/token"
    $body = "grant_type=client_credentials"
    $body += "&client_id=" + $AadClientId
    $body += "&client_secret=" + [Uri]::EscapeDataString($AadClientSecret)
    $body += "&resource=" + [Uri]::EscapeDataString("https://vault.azure.net")
    $headers = @{}

    $response = Invoke-RestMethod -Method POST -Uri $uri -Headers $headers -Body $body

    $access_token = $response.access_token

    Write-Host "Got Auth Token successfully"

    ##############################
    # Get KEK info
    ##############################

    $uri = $KeyEncryptionKey.Id + "?api-version=" + $apiversion
    $headers = @{"Authorization" = "Bearer " + $access_token}

    $response = Invoke-RestMethod -Method GET -Uri $uri -Headers $headers

    $keyid = $response.key.kid

    Write-Host "Got KEK info successfully"

    ##############################
    # Encrypt passphrase using KEK
    ##############################

    $passphraseB64 = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Passphrase))
    $uri = $keyid + "/encrypt?api-version=" + $apiversion
    $headers = @{"Authorization" = "Bearer " + $access_token; "Content-Type" = "application/json"}
    $bodyObj = @{"alg" = "RSA-OAEP"; "value" = $passphraseB64}
    $body = $bodyObj | ConvertTo-Json

    $response = Invoke-RestMethod -Method POST -Uri $uri -Headers $headers -Body $body

    $wrappedSecret = $response.value

    Write-Host "Encrypted passphrase successfully"

    ##############################
    # Store secret
    ##############################

    $secretName = [guid]::NewGuid().ToString()
    $uri = $KeyVault.VaultUri + "/secrets/" + $secretName + "?api-version=" + $apiversion
    $secretAttributes = @{"enabled" = $true}
    $secretTags = @{"DiskEncryptionKeyEncryptionAlgorithm" = "RSA-OAEP"; "DiskEncryptionKeyFileName" = "LinuxPassPhraseFileName"}
    $headers = @{"Authorization" = "Bearer " + $access_token; "Content-Type" = "application/json"}
    $bodyObj = @{"value" = $wrappedSecret; "attributes" = $secretAttributes; "tags" = $secretTags}
    $body = $bodyObj | ConvertTo-Json

    $response = Invoke-RestMethod -Method PUT -Uri $uri -Headers $headers -Body $body

    Write-Host "Stored secret successfully"

    $secretUrl = $response.id

Следующим шагом используйте $KeyEncryptionKey и $secretUrl, чтобы подключить диск ОС с использованием KEK.

Укажите секретный URL-адрес, когда вы подключаете диск ОС

Без использования KEK

При подключении диска ОС вам необходимо передать $secretUrl. Этот URL-адрес был создан в разделе "Секрет шифрования дисков, не зашифрованный с помощью ключа шифрования ключей".

    Set-AzVMOSDisk `
            -VM $VirtualMachine `
            -Name $OSDiskName `
            -SourceImageUri $VhdUri `
            -VhdUri $OSDiskUri `
            -Windows `
            -CreateOption FromImage `
            -DiskEncryptionKeyVaultId $KeyVault.ResourceId `
            -DiskEncryptionKeyUrl $SecretUrl

Использование KEK

При подключении диска ОС передайте $KeyEncryptionKey и $secretUrl. Этот URL-адрес был сгенерирован в разделе "Секрет шифрования дисков, зашифрованный с помощью KEK".

    Set-AzVMOSDisk `
            -VM $VirtualMachine `
            -Name $OSDiskName `
            -SourceImageUri $CopiedTemplateBlobUri `
            -VhdUri $OSDiskUri `
            -Windows `
            -CreateOption FromImage `
            -DiskEncryptionKeyVaultId $KeyVault.ResourceId `
            -DiskEncryptionKeyUrl $SecretUrl `
            -KeyEncryptionKeyVaultId $KeyVault.ResourceId `
            -KeyEncryptionKeyURL $KeyEncryptionKey.Id