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

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

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

Примечание.

Если не указано иное, все скрипты используют последнюю версию Шифрования дисков Azure (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}
    
  • Получение списка всех зашифрованных экземпляров Масштабируемых наборов виртуальных машин в подписке

    Все зашифрованные 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 предварительных требований. Пример использования этого сценария PowerShell см. в статье Краткое руководство. Шифрование виртуальной машины IaaS под управлением Windows с помощью Azure PowerShell. Вы можете удалить комментарии из раздела сценария, начиная со строки 211, чтобы шифровать все диски имеющихся виртуальных машин в имеющейся группе ресурсов.

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

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

Шаблоны Resource Manager

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

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

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

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

Передача зашифрованного виртуального жесткого диска в учетную запись хранения 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

Перед передачей секрета в хранилище ключей его можно дополнительно зашифровать с помощью ключа шифрования ключей. Используйте 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, чтобы подключить диск ОС, применив ключ шифрования ключей.

Указание URL-адреса секрета при подключении диска ОС

Без использования ключа шифрования ключа

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

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

С использованием ключа шифрования ключа

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

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