Skrip sampel Azure Disk Encryption untuk komputer virtual Linux

Perhatian

Artikel ini mereferensikan CentOS, distribusi Linux yang mendekati status End Of Life (EOL). Harap pertimbangkan penggunaan dan rencanakan yang sesuai. Untuk informasi selengkapnya, lihat panduan Akhir Masa Pakai CentOS.

Berlaku untuk: ✔️ Mesin Virtual Linux ✔️ Set skala fleksibel

Artikel ini menyediakan skrip sampel untuk menyiapkan VHD pra-enkripsi dan tugas lainnya.

Catatan

Semua skrip mengacu pada ADE versi non-AAD terbaru, kecuali jika disebutkan.

Sampel skrip PowerShell untuk Azure Disk Encryption

  • Mencantumkan semua komputer virtual terenkripsi di langganan Anda

    Anda dapat menemukan semua komputer virtual terenkripsi ADE dan versi ekstensi, di semua grup sumber daya yang ada dalam langganan, menggunakan skrip PowerShell ini.

    Atau, cmdlet ini akan menampilkan semua komputer virtual terenkripsi ADE (tetapi bukan versi ekstensi):

    $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}
    
  • Mencantumkan semua instans VMSS terenskripsi di langganan Anda

    Anda bisa menemukan instans VMSS terenkripsi ADE dan versi ekstensi, di semua grup sumber daya yang ada di langganan, menggunakanskrip PowerShell ini.

  • Mencantumkan semua rahasia enkripsi disk untuk mengenkripsi komputer virtual dalam brankas kunci

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

Menggunakan skrip PowerShell prasyarat Azure Disk Encryption

Jika Anda sudah tidak asing dengan prasyarat untuk Azure Disk Encryption, Anda bisa menggunakan skrip PowerShell prasyarat Azure Disk Encryption. Untuk contoh penggunaan PowerShell ini, lihat Enkripsi Mulai Cepat Komputer Virtual. Anda bisa menghapus komentar dari bagian skrip, mulai dari baris 211, untuk mengenkripsi semua disk untuk komputer virtual yang ada di grup sumber daya yang ada.

Tabel berikut ini memperlihatkan parameter mana yang bisa digunakan dalam skrip PowerShell:

Parameter Deskripsi Wajib?
$resourceGroupName Nama grup sumber daya tempat KeyVault berada. Grup sumber daya baru dengan nama ini akan dibuat jika tidak ada. Benar
$keyVaultName Nama KeyVault tempat kunci enkripsi diletakkan. Brankas baru dengan nama ini akan dibuat jika belum ada. Benar
$location Lokasi KeyVault. Pastikan Keyvault dan komputer virtual dienkripsi di lokasi yang sama. Dapatkan daftar lokasi dengan Get-AzLocation. Benar
$subscriptionId Pengidentifikasi langganan Azure yang akan digunakan. Anda bisa mendapatkan ID Langganan Anda dengan Get-AzSubscription. Benar
$aadAppName Nama aplikasi Microsoft Entra yang akan digunakan untuk menulis rahasia ke KeyVault. Aplikasi baru dengan nama ini akan dibuat jika belum ada. Jika aplikasi ini sudah ada, berikan parameter aadClientSecret ke skrip. Salah
$aadClientSecret Rahasia klien aplikasi Microsoft Entra yang dibuat sebelumnya. Salah
$keyEncryptionKeyName Nama kunci enkripsi utama opsional di KeyVault. Kunci baru dengan nama ini akan dibuat jika belum ada. Salah

Mengenkripsi atau mendekripsi VM tanpa aplikasi Microsoft Entra

Mengenkripsi atau mendekripsi VM dengan aplikasi Microsoft Entra (rilis sebelumnya)

Mengenkripsi drive OS pada komputer virtual Linux yang sedang berjalan

Prasyarat untuk enkripsi disk OS

  • Komputer virtual haris menggunakan distribusi yang kompatibel dengan enkripsi disk OS seperti yang tercantum dalam sistem operasi yang didukung Azure Disk Encryption
  • Komputer virtual harus dibuat dari citra Marketplace di Azure Resource Manager.
  • Azure VM dengan setidaknya 4 GB RAM (ukuran yang disarankan adalah 7 GB). Lihat Persyaratan memori untuk informasi lebih lanjut.
  • (Untuk RHEL dan CentOS) Nonaktifkan SELinux. Untuk menonaktifkan SELinux, lihat "4.4.2. Menonaktifkan SELinux" dalam Panduan Pengguna dan Administrator SELinux pada komputer virtual.
  • Setelah Anda menonaktifkan SELinux, mulai ulang komputer virtual minimum satu kali.

Langkah-langkah

  1. Buat komputer virtual dengan menggunakan salah satu distribusi yang ditentukan sebelumnya.

  2. Konfigurasi komputer virtual sesuai dengan kebutuhan Anda. Jika Anda akan mengenkripsi semua drive (OS + data), drive data harus ditentukan dan bisa dipasang dari /etc/fstab.

    Catatan

    Gunakan UUID=... untuk menentukan drive data dalam /etc/fstab alih-alih menentukan nama perangkat blok (misalnya, /dev/sdb1). Selama enkripsi, urutan drive berubah pada komputer virtual. Jika komputer virtual Anda mengandalkan urutan perangkat blok tertentu, komputer virtual akan gagal memasangnya setelah enkripsi.

  3. Keluar dari sesi SSH.

  4. Untuk mengenkripsi OS, tentukan volumeType sebagai Semua atau OS saat Anda mengaktifkan enkripsi.

    Catatan

    Semua proses ruang pengguna yang tidak berjalan sebagai layanan systemd harus dimatikan dengan SIGKILL. Boot ulang komputer virtual. Saat Anda mengaktifkan enkripsi disk OS pada komputer virtual yang sedang berjalan, rencanakan pada waktu henti komputer virtual.

  5. Secara berkala memantau progres enkripsi dengan menggunakan instruksi di bagian berikutnya.

  6. Setelah Get-AzVmDiskEncryptionStatus menunjukkan "VMRestartPending", hidupkan ulang komputer virtual Anda dengan masuk ke dalamnya atau menggunakan portal, PowerShell, atau 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
    

    Sebelum memulai ulang, sebaiknya Anda menyimpan diagnostik boot komputer virtual.

Memantau progres enkripsi OS

Anda bisa memantau progres enkripsi OS dengan tiga cara:

  • Menggunakan cmdlet Get-AzVmDiskEncryptionStatus dan periksa bidang ProgressMessage:

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

    Setelah komputer virtual mencapai "enkripsi disk OS dimulai", perlu waktu sekitar 40 hingga 50 menit pada komputer virtual yang didukung penyimpanan Premium.

    Karena masalah #388 di WALinuxAgent, OsVolumeEncrypted dan DataVolumesEncrypted muncul sebagai Unknown dalam beberapa distribusi. Dengan WALinuxAgent versi 2.1.5 dan yang lebih baru, masalah ini diperbaiki secara otomatis. Jika Anda melihat Unknown dalam output, Anda bisa memverifikasi status enkripsi disk menggunakan Azure Resource Explorer.

    Masuk ke Azure Resource Explorer, lalu perluas hierarki ini di panel pilihan pada sebelah kiri:

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

    Di InstanceView, gulir ke bawah untuk melihat status enkripsi drive Anda.

    Tampilan Instans Komputer Virtual

  • Lihatlah diagnostik boot. Pesan dari ekstensi ADE harus diawali dengan [AzureDiskEncryption].

  • Masuk ke komputer virtual melalui SSH, dan dapatkan log ekstensi dari:

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

    Sebaiknya Anda tidak masuk ke komputer virtual saat enkripsi OS sedang berlangsung. Salin log hanya salin dua metode lainnya telah gagal.

Menyiapkan VHD Linux pra-enkripsi

Penyiapan untuk VHD pra-enkripsi bisa berbeda-beda tergantung distribusi. Contoh tentang menyiapkan Ubuntu, openSUSE, dan CentOS 7 tersedia.

Konfigurasikan enkripsi selama instalasi distribusi dengan melakukan langkah-langkah berikut:

  1. Pilih Konfigurasikan volume terenkripsi saat Anda mempartisi disk.

    Penyiapan Ubuntu 16.04 - Mengonfigurasi volume terenkripsi

  2. Buat drive boot terpisah, yang tidak boleh dienkripsi. Enkripsi driver akar Anda.

    Penyiapan Ubuntu 16.04 - Pilih perangkat untuk dienkripsi

  3. Berikan frasa sandi. Ini adalah frasa sandi yang Anda unggah ke brankas kunci.

    Ubuntu 16.04 Setup - Berikan frase sandi

  4. Selesaikan pemartisian.

    Penyiapan Ubuntu 16.04 - Selesaikan pemartisian

  5. Ketika Anda mem-boot komputer virtual dan dimintai frasa sandi, gunakan frasa sandi yang Anda berikan di langkah 3.

    Penyiapan Ubuntu 16.04 - Berikan frase sandi pada boot

  6. Siapkan komputer virtual untuk mengunggah ke Azure menggunakan instruksi ini. Jangan jalankan langkah terakhir (mendeprovisi komputer virtual) dulu.

Konfigurasikan enkripsi agar berfungsi pada Azure dengan melakukan langkah-langkah berikut:

  1. Buat file di bawah /usr/local/sbin/azure_crypt_key.sh, dengan konten dalam skrip berikut. Perhatikan KeyFileName, karena itu adalah nama file frasa sandi yang digunakan oleh 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. Ubah konfigurasi crypt dalam /etc/crypttab. Harusnya akan terlihat seperti ini:

     xxx_crypt uuid=xxxxxxxxxxxxxxxxxxxxx none luks,discard,keyscript=/usr/local/sbin/azure_crypt_key.sh
    
  3. Tambahkan izin yang dapat dijalankan ke skrip:

     sudo chmod +x /usr/local/sbin/azure_crypt_key.sh
    
  4. Edit /etc/initramfs-tools/modules dengan menambahkan baris:

     vfat
     ntfs
     nls_cp437
     nls_utf8
     nls_iso8859-1
    
  5. Jalankan update-initramfs -u -k all untuk memperbarui initramfs agar keyscript memberi dampak.

  6. Sekarang kau bisa mendeprovisi komputer virtual.

    Ubuntu 16.04 Setup - perbarui-initramfs

  7. Lanjutkan ke langkah berikutnya dan unggah VHD Anda ke Azure.

Unggah VHD terenkripsi ke akun penyimpanan Azure

Setelah enkripsi DM-Crypt diaktifkan, VHD terenkripsi lokal perlu diunggah ke akun penyimpanan Anda.

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

Mengunggah rahasia untuk komputer virtual pra-enkripsi ke brankas kunci Anda

Saat mengenkripsi menggunakan aplikasi Microsoft Entra (rilis sebelumnya), rahasia enkripsi disk yang Anda peroleh sebelumnya harus diunggah sebagai rahasia di brankas kunci Anda. Brankas kunci harus mengaktifkan enkripsi dan izin disk untuk klien Microsoft Entra Anda.

 $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

Rahasia enkripsi disk tidak dienkripsi dengan KEK

Untuk menyiapkan rahasia dalam brankas kunci Anda, gunakan Set-AzKeyVaultSecret. Frasa sandi dikodekan sebagai string base64 lalu diunggah ke brankas kunci. Selain itu, pastikan tag berikut diatur saat Anda membuat rahasia di brankas kunci.


 # 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

Gunakan $secretUrl di langkah berikutnya agar melampirkan disk OS tanpa menggunakan KEK.

Rahasia enkripsi disk yang dienkripsi dengan KEK

Sebelum Anda mengunggah rahasia ke brankas kunci, Anda bisa mengenkripsinya secara opsional dengan menggunakan kunci enkripsi utama. Gunakan API terbungkus untuk mengenkripsi rahasia dulu menggunakan kunci enkripsi utama. Output operasi terbungkus ini adalah string yang dikodekan URL base64, yang kemudian bisa Anda unggah sebagai rahasia dengan menggunakan 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

Gunakan $KeyEncryptionKey dan $secretUrl dalam langkah berikutnya untuk melampirkan disk OS menggunakan KEK.

Tentukan URL rahasia saat Anda melampirkan disk OS

Tanpa menggunakan KEK

Saat Anda melampirkan disk OS, Anda harus lolos $secretUrl. URL dihasilkan di bagian "Rahasia enkripsi disk tidak dienkripsi dengan KEK".

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

Menggunakan KEK

Ketika Anda melampirkan disk OS, lalui $KeyEncryptionKey dan $secretUrl. URL dihasilkan di bagian "Rahasia enkripsi disk dienkripsi dengan 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