Crittografia dischi di Azure script di esempio per le macchine virtuali Linux

Attenzione

Questo articolo fa riferimento a CentOS, una distribuzione Linux prossima allo stato EOL (End of Life, fine del ciclo di vita). Prendere in considerazione l'uso e il piano di conseguenza. Per altre informazioni, vedere le linee guida per la fine della vita di CentOS.

Si applica a: ✔️ macchine virtuali di Linux ✔️ set di scalabilità flessibili

Questo articolo fornisce script di esempio per la preparazione di dischi rigidi virtuali pre-crittografati e altre attività.

Nota

Tutti gli script fanno riferimento alla versione più recente, non AAD di ADE, tranne dove indicato.

Esempi di script di PowerShell per Crittografia dischi di Azure

  • Elencare tutte le macchine virtuali crittografate nella sottoscrizione

    È possibile trovare tutte le macchine virtuali con crittografia ADE e la versione dell'estensione, in tutti i gruppi di risorse presenti in una sottoscrizione, usando questo script di PowerShell.

    In alternativa, questi cmdlet visualizzeranno tutte le macchine virtuali con crittografia ADE (ma non la versione dell'estensione):

    $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}
    
  • Elencare tutte le istanze del set di scalabilità di macchine virtuali crittografate nella sottoscrizione

    È possibile trovare tutte le istanze del set di scalabilità di macchine virtuali crittografate da ADE e la versione dell'estensione, in tutti i gruppi di risorse presenti in una sottoscrizione, usando questo script di PowerShell.

  • Elencare tutti i segreti di crittografia dischi usati per crittografare le macchine virtuali in un insieme di credenziali delle chiavi

    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 dello script di PowerShell Crittografia dischi di Azure

Se si ha già familiarità con i prerequisiti per Crittografia dischi di Azure, è possibile usare lo script di PowerShell per i prerequisiti di Crittografia dischi di Azure. Per un esempio d'uso di questo script di PowerShell, vedere Guida introduttiva alla crittografia di una macchina virtuale. È possibile rimuovere i commenti da una sezione dello script, a partire dalla riga 211, per crittografare tutti i dischi per le macchine virtuali esistenti in un gruppo di risorse esistente.

La tabella seguente illustra i parametri che possono essere usati nello script di PowerShell:

Parametro Descrizione Obbligatorio?
$resourceGroupName Nome del gruppo di risorse a cui appartiene l'insieme di credenziali delle chiavi. Verrà creato un nuovo gruppo di risorse con questo nome, se non esiste già. Vero
$keyVaultName Nome dell'insieme di credenziali delle chiavi in cui inserire le chiavi di crittografia. Verrà creato un nuovo insieme con questo nome, se non esiste già. Vero
$location Percorso dell'insieme di credenziali delle chiavi. Assicurarsi che l'insieme di credenziali delle chiavi e le macchine virtuali da crittografare si trovino nello stesso percorso. Ottenere un elenco di percorsi con Get-AzLocation. Vero
$subscriptionId Identificatore della sottoscrizione di Azure da usare. È possibile ottenere l'ID della sottoscrizione con Get-AzSubscription. Vero
$aadAppName Nome dell'applicazione Microsoft Entra che verrà usata per scrivere segreti in KeyVault. Viene creata una nuova applicazione con questo nome, se non esiste già. Se l'app esiste già, passare il parametro aadClientSecret allo script. Falso
$aadClientSecret Segreto client dell'applicazione Microsoft Entra creata in precedenza. Falso
$keyEncryptionKeyName Nome della chiave di crittografia della chiave facoltativa nell'insieme di credenziali delle chiavi. Verrà creata una nuova chiave con questo nome, se non esiste già. Falso

Crittografare o decrittografare le macchine virtuali senza un'app Microsoft Entra

Crittografare o decrittografare le macchine virtuali con un'app Microsoft Entra (versione precedente)

Crittografia di un'unità del sistema operativo in una VM Linux in esecuzione

Prerequisiti per la crittografia del disco del sistema operativo

Passaggi

  1. Creare una macchina virtuale usando una delle distribuzioni specificate in precedenza.

  2. Configurare la VM in base alle esigenze. Se si intende crittografare tutte le unità (sistema operativo e dati), le unità dati dovranno essere specificate e montabili da /etc/fstab.

    Nota

    Usare UUID=... per specificare le unità di dati in /etc/fstab anziché specificare il nome del dispositivo a blocchi, ad esempio /dev/sdb1. L'ordine delle unità viene modificato nella macchina virtuale durante la crittografia. Se la VM si basa su un ordine specifico di dispositivi a blocchi, questi dispositivi non potranno essere montati dopo la crittografia.

  3. Disconnettersi dalle sessioni SSH.

  4. Per crittografare il sistema operativo, specificare il parametro volumeType come Tutto oppure OS quando si abilita la crittografia.

    Nota

    Tutti i processi dello spazio dell'utente non in esecuzione come servizi systemd devono essere terminati con SIGKILL. Riavviare la macchina virtuale. Quando si abilita la crittografia del disco del sistema operativo in una macchina virtuale in esecuzione, pianificare i tempi di inattività della VM.

  5. Monitorare periodicamente lo stato della crittografia tramite le istruzioni indicate nella sezione successiva.

  6. Dopo che Get-AzVmDiskEncryptionStatus mostra "VMRestartPending", riavviare la macchina virtuale eseguendo l'accesso o usando il portale, PowerShell o l'interfaccia della riga di comando.

    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
    

    Prima di riavviare, è consigliabile salvare i dati di diagnostica di avvio della macchina virtuale.

Monitoraggio dello stato della crittografia del sistema operativo

Esistono tre modi per monitorare lo stato della crittografia del sistema operativo:

  • Usare il cmdlet Get-AzVmDiskEncryptionStatus ed esaminare il campo ProgressMessage:

    Get-AzVMDiskEncryptionStatus -ResourceGroupName $_.ResourceGroupName -VMName $_.Name
    
    OsVolumeEncrypted          : EncryptionInProgress
    DataVolumesEncrypted       : NotMounted
    OsVolumeEncryptionSettings : Microsoft.Azure.Management.Compute.Models.DiskEncryptionSettings
    ProgressMessage            : OS disk encryption started
    

    Quando la macchina virtuale raggiunge lo stato "OS disk encryption started", sono necessari circa 40 o 50 minuti in una macchina virtuale con archiviazione Premium.

    A causa dell'errore #388 in WALinuxAgent, OsVolumeEncrypted e DataVolumesEncryptedvengono visualizzati come Unknown in alcune distribuzioni. Con WALinuxAgent 2.1.5 e versioni successive questo errore viene risolto automaticamente. Se viene visualizzato Unknown nell'output, è possibile verificare lo stato della crittografia del disco usando Esplora risorse di Azure.

    Passare a Esplora risorse di Azure, quindi espandere questa gerarchia nel pannello di selezione a sinistra:

    |-- subscriptions
       |-- [Your subscription]
            |-- resourceGroups
                 |-- [Your resource group]
                      |-- providers
                           |-- Microsoft.Compute
                                |-- virtualMachines
                                     |-- [Your virtual machine]
                                          |-- InstanceView
    

    In InstanceView scorrere verso il basso per visualizzare lo stato della crittografia delle unità.

    Visualizzazione dell'istanza della VM

  • Esaminare la diagnostica di avvio. I messaggi provenienti dall'estensione ADE hanno il prefisso [AzureDiskEncryption].

  • Accedere alla VM tramite SSH e ottenere il log di estensione da:

    /var/log/azure/Microsoft.Azure.Security.AzureDiskEncryptionForLinux

    È consigliabile non accedere alla macchina virtuale mentre è in corso la crittografia del sistema operativo. Copiare i log solo in caso di errore degli altri due metodi.

Preparare un disco rigido virtuale Linux pre-crittografato

La preparazione di dischi rigidi virtuali pre-crittografati può variare a seconda della distribuzione. Sono disponibili esempi sulla preparazione di Ubuntu, openSU edizione Standard e CentOS 7.

Configurare la crittografia durante l'installazione della distribuzione seguendo questa procedura:

  1. Selezionare Configure encrypted volumes (Configura volumi crittografati) durante il partizionamento dei dischi.

    Configurazione di Ubuntu 16.04 - Configurare i volumi crittografati

  2. Creare un'unità di avvio separata che non deve essere crittografata. Crittografare l'unità radice.

    Configurazione di Ubuntu 16.04 - Selezionare i dispositivi da crittografare

  3. Specificare una passphrase. Si tratta della passphrase caricata nell'insieme di credenziali delle chiavi.

    Configurazione di Ubuntu 16.04 - Specificare la passphrase

  4. Terminare il partizionamento.

    Configurazione di Ubuntu 16.04 - Terminare il partizionamento

  5. Quando si avvia la macchina virtuale e viene richiesta una passphrase, usare la passphrase specificata nel passaggio 3.

    Configurazione di Ubuntu 16.04 - Specificare la passphrase all'avvio

  6. Preparare la macchina virtuale per il caricamento in Azure seguendo queste istruzioni. Non eseguire ancora l'ultimo passaggio, ovvero il deprovisioning della VM.

Configurare la crittografia per l'uso in Azure eseguendo i passaggi seguenti:

  1. Creare un file in /usr/local/sbin/azure_crypt_key.sh, con il contenuto nello script seguente. Prestare attenzione a KeyFileName perché è il nome file della passphrase usato da Azure.

    #!/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
    
  2. Modificare la configurazione di crittografia in /etc/crypttab. La cartella dovrebbe avere un aspetto simile a questo:

     xxx_crypt uuid=xxxxxxxxxxxxxxxxxxxxx none luks,discard,keyscript=/usr/local/sbin/azure_crypt_key.sh
    
  3. Aggiungere autorizzazioni di esecuzione allo script:

     sudo chmod +x /usr/local/sbin/azure_crypt_key.sh
    
  4. Modificare /etc/initramfs-tools/modules aggiungendo righe:

     vfat
     ntfs
     nls_cp437
     nls_utf8
     nls_iso8859-1
    
  5. Eseguire update-initramfs -u -k all per aggiornare initramfs e rendere operativo il keyscript.

  6. È ora possibile effettuare il deprovisioning della VM.

    Configurazione di Ubuntu 16.04 - update-initramfs

  7. Continuare con il passaggio successivo e caricare il disco rigido virtuale in Azure.

Caricare il VHD crittografato in un account di archiviazione di Azure

Dopo aver abilitato la crittografia DM-Crypt, è necessario caricare il disco rigido virtuale crittografato locale nell'account di archiviazione.

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

Caricare il segreto per la macchina virtuale pre-crittografata nell'insieme di credenziali delle chiavi

Quando si esegue la crittografia con un'app Microsoft Entra (versione precedente), il segreto di crittografia del disco ottenuto in precedenza deve essere caricato come segreto nell'insieme di credenziali delle chiavi. L'insieme di credenziali delle chiavi deve disporre della crittografia del disco e delle autorizzazioni abilitate per il client 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

Segreto di crittografia del disco non crittografato con una chiave di crittografia della chiave

Per configurare il segreto nell'insieme di credenziali delle chiavi, usare Set-AzKeyVaultSecret. La passphrase viene codificata come stringa base64 e quindi caricata nell'insieme di credenziali delle chiavi. Assicurarsi anche che i tag seguenti siano impostati quando si crea il segreto nell'insieme di credenziali delle chiavi.


 # 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

Usare $secretUrl nel passaggio successivo per collegare il disco del sistema operativo senza usare una chiave di crittografia della chiave.

Segreto di crittografia del disco crittografato con una chiave di crittografia della chiave

Prima di caricare il segreto nell'insieme di credenziali delle chiavi, è possibile crittografarlo usando una chiave di crittografia della chiave. Usare l'API WRAP per crittografare prima di tutto il segreto con la chiave di crittografia della chiave. L'output di questa operazione WRAP si basa su una stringa con codifica Base 64 dell'URL che può essere quindi caricata come segreto con il 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

Usare $KeyEncryptionKey e $secretUrl nel passaggio successivo per collegare il disco del sistema operativo usando una chiave di crittografia della chiave.

Specificare un URL del segreto quando si collega un disco del sistema operativo

Senza l'uso di una chiave di crittografia della chiave (KEK)

Quando si collega il disco del sistema operativo è necessario passare $secretUrl. L'URL è stato generato nella sezione "Segreto di crittografia del disco non crittografato con una chiave di crittografia della chiave".

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

Con l'uso di una chiave di crittografia della chiave (KEK)

Quando si collega il disco del sistema operativo, vedere $KeyEncryptionKey e $secretUrl. L'URL è stato generato nella sezione "Segreto di crittografia del disco crittografato con una chiave di crittografia della chiave".

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