Scripts de ejemplo de Azure Disk Encryption para máquinas virtuales Linux
Precaución
En este artículo se hace referencia a CentOS, una distribución de Linux con un estado de finalización del servicio (EOL). Tenga en cuenta su uso y planifique en consecuencia. Para obtener más información, consulte la guía de fin de vida de CentOS.
Se aplica a: ✔️ máquinas virtuales Linux ✔️ conjuntos de escalado flexibles
En este artículo se proporcionan scripts de ejemplo tanto para preparar los discos duros virtuales previamente cifrados como para realizar otras tareas.
Nota
Todos los scripts hacen referencia a la versión más reciente de ADE que no sea de AAD, excepto donde se indique lo contrario.
Scripts de ejemplo de PowerShell para Azure Disk Encryption
Enumerar todas las máquinas virtuales cifradas en la suscripción
Puede encontrar todas las VM cifradas con ADE y la versión de la extensión en todos los grupos de recursos presentes en una suscripción, mediante este script de PowerShell.
Como alternativa, estos cmdlets mostrarán todas las VM cifradas con ADE (pero no la versión de la extensión):
$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}
Enumeración de todas las instancias de VMSS cifradas de la suscripción
Puede encontrar todas las instancias de VMSS cifradas con ADE y la versión de la extensión en todos los grupos de recursos presentes en una suscripción, mediante este script de PowerShell.
Enumerar todos los secretos de cifrado de disco usados para cifrar las máquinas virtuales en un almacén de claves
Get-AzKeyVaultSecret -VaultName $KeyVaultName | where {$_.Tags.ContainsKey('DiskEncryptionKeyFileName')} | format-table @{Label="MachineName"; Expression={$_.Tags['MachineName']}}, @{Label="VolumeLetter"; Expression={$_.Tags['VolumeLetter']}}, @{Label="EncryptionKeyURL"; Expression={$_.Id}}
Uso del script de PowerShell de requisitos previos de Azure Disk Encryption
Si ya está familiarizado con los requisitos previos para Azure Disk Encryption, puede usar el script de PowerShell de requisitos previos de Azure Disk Encryption. Para un ejemplo de uso de este script de PowerShell, consulte la guía de inicio rápido para el cifrado de máquinas virtuales. Puede quitar los comentarios de una sección del script, a partir de la línea 211, para cifrar todos los discos de las máquinas virtuales de un grupo de recursos existente.
En la siguiente tabla se muestran los parámetros que se pueden usar en el script de PowerShell:
Parámetro | Descripción | ¿Obligatorio? |
---|---|---|
$resourceGroupName | Nombre del grupo de recursos al que pertenece la instancia de KeyVault. Si no existe, se creará un grupo de recursos con este nombre. | True |
$keyVaultName | Nombre de la instancia de KeyVault en donde se colocarán las claves de cifrado. Si no existe, se creará un almacén con este nombre. | True |
$location | Ubicación de la instancia de KeyVault. Asegúrese de que la instancia de KeyVault y las máquinas virtuales que se van a cifrar están en la misma ubicación. Obtenga una lista de ubicaciones con Get-AzLocation . |
True |
$subscriptionId | Identificador de la suscripción de Azure que se va a utilizar. El identificador de la suscripción se puede obtener con Get-AzSubscription . |
True |
$aadAppName | Nombre de la aplicación de Microsoft Entra que se va a utilizar para escribir secretos en KeyVault. Si no existe, se creará una aplicación con este nombre. Si esta aplicación ya existe, pasará el parámetro aadClientSecret al script. | False |
$aadClientSecret | Secreto de cliente de la aplicación de Microsoft Entra que se creó antes. | False |
$keyEncryptionKeyName | Nombre de la clave de cifrado de clave opcional en KeyVault. Si no existe, se creará una clave con este nombre. | False |
Cifrado o descifrado de máquinas virtuales sin una aplicación de Microsoft Entra
- Habilitar el cifrado de disco en una máquina virtual Linux existente o en ejecución
- Deshabilitar el cifrado en una máquina virtual Linux en ejecución
- La deshabilitación del cifrado solo se permite en volúmenes de datos de máquinas virtuales Linux.
Cifrado o descifrado de máquinas virtuales con una aplicación de Microsoft Entra (versión anterior)
- Habilitar el cifrado de disco en una máquina virtual Linux existente o en ejecución
- Deshabilitar el cifrado en una máquina virtual Linux en ejecución
- La deshabilitación del cifrado solo se permite en volúmenes de datos de máquinas virtuales Linux.
- Crear un disco administrado cifrado a partir de un blob de almacenamiento o disco duro virtual previamente cifrado
- Crea un disco administrado cifrado a partir de un disco duro virtual previamente cifrado y su correspondiente configuración de cifrado.
Cifrado de la unidad del sistema operativo en una máquina virtual con Linux en ejecución
Requisitos previos para el cifrado de disco del sistema operativo
- La máquina virtual debe usar una distribución compatible con el cifrado del disco del sistema operativo, como se muestra en el artículo Sistemas operativos compatibles con Azure Disk Encryption
- La máquina virtual debe crearse a partir de la imagen de Marketplace en Azure Resource Manager.
- La máquina virtual de Azure con al menos 4 GB de RAM (el tamaño recomendado es 7 GB). Consulte Requisitos de memoria para obtener más información.
- (Para RHEL y CentOS) Deshabilite SELinux. Para deshabilitar SELinux, consulte "4.4.2. Disabling SELinux" (Deshabilitar SELinux) en el documento SELinux User's and Administrator's Guide (Guía del administrador y del usuario de SELinux) en la máquina virtual.
- Después de deshabilitar SELinux, reinicie la máquina virtual al menos una vez.
Pasos
Cree una máquina virtual mediante una de las distribuciones especificadas anteriormente.
Configure la máquina virtual según sus necesidades. Si va a cifrar todas las unidades (sistema operativo y datos), las unidades de datos tienen que especificarse y montarse desde /etc/fstab.
Nota
Use UUID=... para especificar unidades de datos en /etc/fstab en lugar de especificar el nombre del dispositivo de bloque (por ejemplo, /dev/sdb1). Durante el cifrado, se cambia el orden de las unidades en la máquina virtual. Si la máquina virtual depende de un orden específico de dispositivos de bloque, se producirá un error de montaje después del cifrado.
Cierre las sesiones de SSH.
Para cifrar el sistema operativo, especifique volumeType como All u OS al habilitar el cifrado.
Nota
Todos los procesos de espacio de usuario que no se ejecutan como servicios
systemd
deben terminarse conSIGKILL
. Reinicie la máquina virtual. Al habilitar el cifrado del disco de sistema operativo en una máquina virtual en ejecución, tenga en cuenta el tiempo de inactividad de la máquina virtual.Supervise periódicamente el progreso del cifrado con las instrucciones de la sección siguiente.
Cuando Get-AzVmDiskEncryptionStatus muestre "VMRestartPending", inicie sesión en la máquina virtual para reiniciarla o hágalo mediante el portal, PowerShell o la CLI.
C:\> Get-AzVmDiskEncryptionStatus -ResourceGroupName $ResourceGroupName -VMName $VMName -ExtensionName $ExtensionName
OsVolumeEncrypted : VMRestartPending DataVolumesEncrypted : NotMounted OsVolumeEncryptionSettings : Microsoft.Azure.Management.Compute.Models.DiskEncryptionSettings ProgressMessage : OS disk successfully encrypted, reboot the VM
Antes de reiniciar, se recomienda que guarde los diagnósticos de arranque de la máquina virtual.
Supervisión del progreso de cifrado del sistema operativo
Hay tres maneras de supervisar el progreso de cifrado del sistema operativo:
Use el cmdlet
Get-AzVmDiskEncryptionStatus
e inspeccione el campo ProgressMessage:Get-AzVMDiskEncryptionStatus -ResourceGroupName $_.ResourceGroupName -VMName $_.Name
OsVolumeEncrypted : EncryptionInProgress DataVolumesEncrypted : NotMounted OsVolumeEncryptionSettings : Microsoft.Azure.Management.Compute.Models.DiskEncryptionSettings ProgressMessage : OS disk encryption started
Una vez que la máquina virtual llega al mensaje de inicio del cifrado de disco del sistema operativo, el proceso tarda aproximadamente entre 40 y 50 minutos en una máquina virtual de almacenamiento Premium.
Debido al problema 388 de WALinuxAgent,
OsVolumeEncrypted
yDataVolumesEncrypted
se muestran comoUnknown
en algunas distribuciones. En WALinuxAgent versión 2.1.5 y versiones posteriores, este problema se ha corregido automáticamente. En caso de que se veaUnknown
en la salida, puede comprobar el estado de cifrado del disco mediante el Explorador de recursos de Azure.Vaya al Explorador de recursos de Azure y expanda esta jerarquía en el panel de selección a la izquierda:
|-- subscriptions |-- [Your subscription] |-- resourceGroups |-- [Your resource group] |-- providers |-- Microsoft.Compute |-- virtualMachines |-- [Your virtual machine] |-- InstanceView
En el objeto InstanceView, desplácese hacia abajo para ver el estado de cifrado de las unidades de disco.
Fíjese en los diagnósticos de arranque. Los mensajes de la extensión ADE deben llevar el prefijo
[AzureDiskEncryption]
.Inicie sesión en la máquina virtual a través de SSH y obtenga el registro de la extensión de:
/var/log/azure/Microsoft.Azure.Security.AzureDiskEncryptionForLinux
Se recomienda que no inicie sesión en la máquina virtual con el cifrado del sistema operativo en curso. Copie los registros solo cuando los otros dos métodos no den resultado.
Preparación de un VHD con Linux precifrado
La preparación de disco duros virtuales previamente cifrados puede variar dependiendo de la distribución. Se pueden encontrar ejemplos sobre cómo preparar Ubuntu, openSUSE y CentOS 7.
Configure el cifrado durante la instalación de la distribución; para ello, siga estos pasos:
Seleccione Configure encrypted volumes (Configurar volúmenes cifrados) al realizar la partición de los discos.
Cree una unidad de arranque independiente, que no debe estar cifrada. Cifre la unidad raíz.
Proporcione una frase de contraseña. Se trata de la frase de contraseña que se carga en el almacén de claves.
Finalice la partición.
Cuando arranque la máquina virtual y se le pida una frase de contraseña, utilice la frase de contraseña que especificó en el paso 3.
Prepare la máquina virtual para su carga en Azure con estas instrucciones. No ejecute todavía el último paso (desaprovisionamiento de la máquina virtual).
Configure el cifrado para que funcione con Azure de esta manera:
Cree un archivo en
/usr/local/sbin/azure_crypt_key.sh
, con el contenido del siguiente script. Preste atención a KeyFileName, porque es el nombre que Azure ha asignado al archivo de frase de contraseña.#!/bin/sh MountPoint=/tmp-keydisk-mount KeyFileName=LinuxPassPhraseFileName echo "Trying to get the key from disks ..." >&2 mkdir -p $MountPoint modprobe vfat >/dev/null 2>&1 modprobe ntfs >/dev/null 2>&1 sleep 2 OPENED=0 cd /sys/block for DEV in sd*; do echo "> Trying device: $DEV ..." >&2 mount -t vfat -r /dev/${DEV}1 $MountPoint >/dev/null|| mount -t ntfs -r /dev/${DEV}1 $MountPoint >/dev/null if [ -f $MountPoint/$KeyFileName ]; then cat $MountPoint/$KeyFileName umount $MountPoint 2>/dev/null OPENED=1 break fi umount $MountPoint 2>/dev/null done if [ $OPENED -eq 0 ]; then echo "FAILED to find suitable passphrase file ..." >&2 echo -n "Try to enter your password: " >&2 read -s -r A </dev/console echo -n "$A" else echo "Success loading keyfile!" >&2 fi
Cambie la configuración de cifrado en /etc/crypttab. Debería ser parecido a este:
xxx_crypt uuid=xxxxxxxxxxxxxxxxxxxxx none luks,discard,keyscript=/usr/local/sbin/azure_crypt_key.sh
Agregue permisos de ejecución al script:
sudo chmod +x /usr/local/sbin/azure_crypt_key.sh
Edite
/etc/initramfs-tools/modules
anexando líneas:vfat ntfs nls_cp437 nls_utf8 nls_iso8859-1
Ejecute
update-initramfs -u -k all
para actualizar initramfs a fin de quekeyscript
surta efecto.Ahora puede desaprovisionar la máquina virtual.
Continúe con el paso siguiente y cargue el disco duro virtual en Azure.
Carga de un VHD cifrado a una cuenta de almacenamiento de Azure
Una vez que se cifre DM-Crypt, el disco duro virtual cifrado local debe cargarse en la cuenta de almacenamiento.
Add-AzVhd [-Destination] <Uri> [-LocalFilePath] <FileInfo> [[-NumberOfUploaderThreads] <Int32> ] [[-BaseImageUriToPatch] <Uri> ] [[-OverWrite]] [ <CommonParameters>]
Carga del secreto de la máquina virtual previamente cifrada en el almacén de claves
Al cifrar mediante una aplicación de Microsoft Entra (versión anterior), el secreto de cifrado del disco que obtuvo con anterioridad se debe cargar como secreto en el almacén de claves. El almacén de claves debe tener habilitados el cifrado de discos y los permisos para el cliente de Microsoft Entra.
$AadClientId = "My-AAD-Client-Id"
$AadClientSecret = "My-AAD-Client-Secret"
$key vault = New-AzKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -Location $Location
Set-AzKeyVaultAccessPolicy -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -ServicePrincipalName $AadClientId -PermissionsToKeys all -PermissionsToSecrets all
Set-AzKeyVaultAccessPolicy -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -EnabledForDiskEncryption
Secreto del cifrado de disco no cifrado con una KEK
Para configurar el secreto en el almacén de claves, use Set-AzKeyVaultSecret. La frase de contraseña se codifica en forma de cadena base64 y, después, se carga en el almacén de claves. Además, asegúrese de que se establecen las siguientes etiquetas al crear el secreto en el almacén de claves.
# 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
Use $secretUrl
en el paso siguiente para conectar el disco del sistema operativo sin usar KEK.
Secreto del cifrado de disco cifrado con una KEK
Antes de cargar el secreto en el almacén de claves, puede cifrarlo si lo desea mediante una clave de cifrado de claves. Utilice la API de encapsulamiento para cifrar por primera vez el secreto mediante la clave de cifrado de claves. El resultado de esta operación de encapsulamiento es una cadena codificada en URL como base64 que luego se carga como secreto con el cmdlet 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
Use $KeyEncryptionKey
y $secretUrl
en el paso siguiente para conectar el disco del sistema operativo usando KEK.
Especificación de una dirección URL de secreto al adjuntar un disco del sistema operativo
Sin utilizar una KEK
Mientras esté adjuntando el disco del sistema operativo, tiene que pasar $secretUrl
. La dirección URL se generó en la sección "Secreto de cifrado de disco no cifrado con una KEK".
Set-AzVMOSDisk `
-VM $VirtualMachine `
-Name $OSDiskName `
-SourceImageUri $VhdUri `
-VhdUri $OSDiskUri `
-Linux `
-CreateOption FromImage `
-DiskEncryptionKeyVaultId $KeyVault.ResourceId `
-DiskEncryptionKeyUrl $SecretUrl
Uso de una KEK
Cuando conecte un disco del sistema operativo, pase $KeyEncryptionKey
y $secretUrl
. La dirección URL se generó en la sección "Secreto del cifrado de disco cifrado con KEK".
Set-AzVMOSDisk `
-VM $VirtualMachine `
-Name $OSDiskName `
-SourceImageUri $CopiedTemplateBlobUri `
-VhdUri $OSDiskUri `
-Linux `
-CreateOption FromImage `
-DiskEncryptionKeyVaultId $KeyVault.ResourceId `
-DiskEncryptionKeyUrl $SecretUrl `
-KeyEncryptionKeyVaultId $KeyVault.ResourceId `
-KeyEncryptionKeyURL $KeyEncryptionKey.Id