Enable Virtual Machine Disk Encryption with Customer-Managed Keys

Trend Micro Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 750 automated best practice checks.

Risk level: High (not acceptable risk)

Ensure that the persistent disks attached to your Google Compute Engine instances are encrypted with Customer-Managed Keys (CMKs) in order to have a fine control over your sensitive data encryption and decryption process. You can create and manage your own Customer-Managed Keys (CMKs) with Cloud Key Management Service (Cloud KMS). Cloud KMS provides secure and efficient encryption key management, controlled key rotation, and revocation mechanisms.

Security

By default, the Compute Engine service encrypts all data at rest using Google-managed encryption keys. The cloud service manages this type of encryption without any additional actions from you and your application. However, if you want to fully control and manage instance disk encryption yourself, you can use your own Customer-Managed Keys (CMKs). Cloud KMS Customer-Managed Keys can be implemented to encrypt production or mission-critical data, and are often used in the enterprise world, where compliance and security controls are more stringent.


Audit

To determine if your virtual machine instance disks are encrypted with Customer-Managed Keys (CMKs), perform the following operations:

Using GCP Console

01 Sign in to Google Cloud Management Console.

02 Select the Google Cloud Platform (GCP) project that you want to examine from the console top navigation bar.

03 Navigate to Google Compute Engine dashboard at https://console.cloud.google.com/compute.

04 In the navigation panel, select VM instances to access the list with the virtual machine (VM) instances provisioned for the selected project.

05 Click on the name of the production VM instance that you want to examine.

06 Select the Details tab to access the configuration details available for selected instance.

07 In the Boot disk and Additional disks sections, check the encryption type available in the Encryption column for each disk attached to the instance. If the selected disk does not have the Encryption type set to Customer managed, the data on the verified disk is not encrypted with a Customer-Managed Key (CMK), therefore the disk(s) attached to your Google Compute Engine instance are not encrypted with CMKs.

08 Repeat step no. 5 – 7 for each virtual machine (VM) instance provisioned within the selected project.

09 Repeat steps no. 2 – 8 for each project deployed in your Google Cloud account.

Using GCP CLI

01 Run projects list command (Windows/macOS/Linux) using custom query filters to list the IDs of all the Google Cloud Platform (GCP) projects available in your cloud account:

gcloud projects list
	--format="table(projectId)"

02 The command output should return the requested GCP project IDs:

PROJECT_ID
cc-web-stack-project-123123
cc-backend-app-project-112233

03 Run compute instances list command (Windows/macOS/Linux) using the ID of the GCP project that you want to examine as identifier parameter and custom query filters to describe the name and zone for each VM instance launched for the selected project:

gcloud compute instances list
	--project cc-web-stack-project-123123
	--format="table(name,zone)"

04 The command output should return the name(s) of the instance(s) within the selected GCP project:

NAME                      ZONE
cc-production-instance    us-central1-a
cc-staging-vm-instance    us-central1-a

05 Run compute instances describe command (Windows/macOS/Linux) using the name and the zone of the instance that you want to examine as identifier parameter and custom filtering to list the name of each disk (boot or non-boot) attached to the selected instance:

gcloud compute instances describe cc-production-instance
	--zone us-central1-a
	--format="table(disks.deviceName)"

06 The command output should return the name(s) of the disk device(s):

DEVICE_NAME
['cc-production-instance-boot-disk', 'cc-production-instance-data-disk']

07 Run compute disks describe command (Windows/macOS/Linux) using the name of the VM instance disk that you want to examine as identifier parameter and custom query filters to describe the encryption key configured for the selected disk:

gcloud compute disks describe cc-production-instance-boot-disk
	--zone us-central1-a
	--format="json(diskEncryptionKey)"

08 The command output should return the requested encryption key details:

{
  "diskEncryptionKey": {
    "kmsKeyName": "projects/cc-web-stack-project-123123/locations/global/keyRings/cc-web-key-ring/cryptoKeys/cc-production-cryptokey/cryptoKeyVersions/2"
  }
}

If compute disks describe command output does not return a disk encryption key with the name property set to "kmsKeyName", as shown in the example above, the data available on the selected disk is not encrypted with a Customer-Managed Key (CMK).

09 Repeat step no. 7 and 8 for each disk attached to the selected virtual machine (VM) instance.

10 Repeat steps no. 5 – 9 for each virtual machine instance created within the selected project.

11 Repeat steps no. 3 – 10 for each GCP project deployed in your Google Cloud account.

Remediation / Resolution

To enable encryption with Cloud KMS Customer-Managed Keys (CMKs) for the disks attached to your Google Compute Engine instances, perform the following operations:

Using GCP Console

01 Sign in to Google Cloud Management Console.

02 Select the GCP project that you want to access from the console top navigation bar.

03 To create and configure your new Customer-Managed Key (CMK), perform the following:

  1. Navigate to Cloud Key Management Service (Cloud KMS) dashboard at https://console.cloud.google.com/security/kms.
  2. Before you can set up and manage any Customer-Managed Keys (CMKs), you must create a key ring. A KMS key ring is a grouping of cryptographic keys made available for organizational purposes in a specific location. In the navigation panel, select Cryptographic Keys, and click on the CREATE KEY RING button to set up the required key ring and the new Customer-Managed Key (CMK).
  3. A key ring requires a name and location. On the Create key ring page, provide a unique name in the Key ring name box, then choose the appropriate location from the Key ring location dropdown list. The location can be either global or associated with a particular region. If the CMKs created later within the key ring will be used to encrypt/decrypt resources in a given region, select that region as the key ring location. Click CREATE to deploy the new key ring.
  4. On the Create key page, select Generated key as the type of the CMK that you want to create. Provide a name for your new key in the Key name box, choose the protection level (software or Hardware Security Module) that you want to use, select Symmetric encrypt/decrypt from the Purpose dropdown list to define the types of operations that your cryptographic key can perform, and configure the key rotation parameters. Click CREATE to deploy your new Cloud KMS Customer-Managed Key (CMK).

04 Navigate to Google Compute Engine dashboard at https://console.cloud.google.com/compute.

05 In the navigation panel, select VM instances to access all the virtual machine (VM) instances provisioned for the selected project.

06 Click on the name of the instance that you want to re-create with Customer-Managed Keys (CMKs) as cryptographic keys (see Audit section part I to identify the right resource).

07 Select the Details tab and collect all the necessary configuration details available for selected VM instance.

08 Click on the STOP button from the dashboard top menu to stop the selected instance. Click STOP inside the confirmation box to confirm the action.

09 Once the VM instance is stopped, click on the instance boot disk and select CREATE IMAGE to create an image from the selected VM disk.

10 On the Create an image page, give your boot disk image a unique name, select the appropriate location, and click CREATE to deploy the image.

11 (Optional) If the selected instance has additional (non-boot) disks attached, it is recommended to create images from these disks as well.

12 Go back to the stopped VM instance, click on the START button from the dashboard top menu and restart the selected instance. Click START inside the confirmation box to confirm the action.

13 In the navigation panel, select VM instances, and click CREATE INSTANCE to launch a new virtual machine (VM) instance.

14 On the Create an instance page, perform the following actions:

  1. Provide a unique name for the new instance in the Name box.
  2. Click Change in the Boot disk configuration box, choose Custom images tab, and select the boot disk image created earlier from the Image dropdown list.
  3. Click on the Management, security, disks, networking, sole tenancy, choose the Disks tab, and perform the following commands to enable disk encryption using your own Customer-Managed Key (CMK):
    • In the Boot disk section, under Encryption, choose Customer-managed key option, and select the CMK created at step no. 3 from the Select a customer-managed key dropdown list.
    • (Optional) If the source (non-compliant) VM instance has additional data disks attached, click Add new disk, under Additional disks. On the New disk panel, under Source type, choose the Image tab and select the data disk image created at step no. 11, from the Source image dropdown list. Under Encryption, choose Customer-managed key, and select your own CMK from the Select a customer-managed key dropdown list. Click Done to close the panel.
  4. Make sure that all the instance settings are configured based on the information taken at step no. 7.
  5. Click Create to launch your new VM instance.

15 To avoid extra charges on your Google Cloud bill, you can remove the source instance from your GCP project. To remove the required instance, perform the following:

  1. In the navigation panel, select VM instances.
  2. Choose the VM instance that you want to remove, then click the 3-dot button for instance menu options and select Delete to initiate the removal process.
  3. Within the Delete an instance confirmation box, select DELETE to confirm the action and remove the selected instance from your project.

16 Repeat steps no. 6 – 15 to enable encryption at rest with Customer-Managed Keys (CMKs) for other VM instances available within the selected project.

17 Repeat steps no. 2 – 11 for each GCP project available in your Google Cloud account.

Using GCP CLI

01 Before you can set up and manage your Customer-Managed Keys (CMKs), you must create a key ring. A KMS key ring is a grouping of cryptographic keys made available for organizational purposes in a specific Google Cloud location. Run kms keyrings create command (Windows/macOS/Linux) to create a new Cloud KMS key ring in the specified location. If the CMKs created later within this key ring will be used to encrypt/decrypt resources in a given region, select that region as the key ring location:

gcloud kms keyrings create cc-production-key-ring
	--location=us
	--project=cc-web-stack-project-123123
	--format="table(name)"

02 The command output should return the identifier (name) of the newly created key ring:

NAME
projects/cc-web-stack-project-123123/locations/us/keyRings/cc-production-key-ring

03 Run kms keys create command (Windows/macOS/Linux) to create a new Cloud KMS Customer-Managed Key (CMK) within the KMS key ring created at the previous steps:

gcloud kms keys create cc-production-cmk
	--location=us
	--keyring=cc-production-key-ring
	--purpose=encryption
	--protection-level=software
	--rotation-period=90d
	--next-rotation-time=2020-9-10T12:00:00.0000Z
	--format="table(name)"

04 The command output should return the name of the new Customer-Managed Key (CMK):

NAME
projects/cc-web-stack-project-123123/locations/us/keyRings/cc-production-key-ring/cryptoKeys/cc-production-cmk

05 Run projects add-iam-policy-binding command (Windows/macOS/Linux) to assign the Cloud KMS "CryptoKey Encrypter/Decrypter" role to the Compute Engine Service Agent. Replace <kms-project-id> with the ID of the Google Cloud project where the Customer-Managed Keys are provisioned, and replace <project-number> with the project number (not the project ID) of the Google Cloud project that is running your Compute Engine instances:

gcloud projects add-iam-policy-binding <kms-project-id>
	--member serviceAccount:service-<project-number>@compute-system.iam.gserviceaccount.com
	--role roles/cloudkms.cryptoKeyEncrypterDecrypter

06 The command output should return the updated IAM policy (YAML format):

Updated IAM policy for project <kms-project-id>.
bindings:
- members:
  - serviceAccount:service-<project-number>@compute-system.iam.gserviceaccount.com
  role: roles/cloudkms.cryptoKeyEncrypterDecrypter
- members:
  - serviceAccount:service-<project-number>@compute-system.iam.gserviceaccount.com
  role: roles/compute.serviceAgent
- members:
  - serviceAccount:service-<project-number>@compute-system.iam.gserviceaccount.com
  - user:admin@cloudconformity.com
  role: roles/owner
etag: abcdabcdabcd
version: 1

07 Run compute instances describe command (Windows/macOS/Linux) using the name of the virtual machine (VM) instance that you want to re-create with a different encryption configuration as identifier parameter (see Audit section part II to identify the right resource), to describe and collect the configuration metadata available for the selected instance:

gcloud compute instances describe cc-production-instance
	--zone us-central1-a

08 The command output should return the requested configuration information:

cpuPlatform: Intel Haswell
deletionProtection: false
disks:
- autoDelete: true
  boot: true
  deviceName: cc-production-instance
  diskSizeGb: '150'
  guestOsFeatures:
  - type: VIRTIO_SCSI_MULTIQUEUE
  - type: UEFI_COMPATIBLE
  interface: SCSI
  kind: compute#attachedDisk
  mode: READ_WRITE
  source: https://www.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/zones/us-central1-a/disks/cc-production-instance
  type: PERSISTENT
displayDevice:
  enableDisplay: false

...

kind: compute#instance
machineType: https://www.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/zones/us-central1-a/machineTypes/n1-standard-8
name: cc-production-instance
  enableIntegrityMonitoring: true
  enableSecureBoot: false
  enableVtpm: true
shieldedInstanceIntegrityPolicy:
  updateAutoLearnPolicy: true
startRestricted: false
status: RUNNING
tags:
  items:
  - http-server
  - https-server
zone: https://www.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/zones/us-central1-a

09 Run compute instances stop command (Windows/macOS/Linux) using the name of the instance that you want to re-create (source instance) as identifier parameter, to stop the selected VM instance:

gcloud compute instances stop cc-production-instance
	--zone=us-central1-a

10 The command output should return the compute instances stop request status:

Stopping instance(s) cc-production-instance...done.
Updated [https://compute.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/zones/us-central1-a/instances/cc-production-instance].

11 Run compute images create command (Windows/macOS/Linux) using the name of the boot disk attached to the source instance as value for the --source-disk parameter, to create an image from the selected instance disk. The boot disk image will be used later, when the new VM instance will be created:

gcloud compute images create cc-production-boot-disk-image
	--source-disk cc-production-instance-boot-disk
	--source-disk-zone us-central1-a
	--storage-location us

12 The command output should return the name and the status of the newly created disk image:

Created [https://www.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/global/images/cc-production-boot-disk-image].

NAME                           PROJECT                      STATUS
cc-production-boot-disk-image  cc-web-stack-project-123123  READY

13 (Optional) If the selected VM instance has additional (non-boot) disks attached, it is recommended to create images from these disks as well.

14 Run compute instances start command (Windows/macOS/Linux) to restart the source Google Compute Engine instance:

gcloud compute instances start cc-production-instance
	--zone=us-central1-a

15 The command output should return the compute instances start request status:

Starting instance(s) cc-production-instance...done.
Updated [https://compute.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/zones/us-central1-a/instances/cc-production-instance].

16 Run compute instances create command (Windows/macOS/Linux) using the configuration information collected at step no. 8 as configuration parameters and the name of your new Cloud KMS Customer-Managed Key (CMK) as value for the --boot-disk-kms-key parameter, to create a new virtual machine (VM) instance with the appropriate encryption configuration, where the instance boot disk data is encrypted using your own CMK. (Optional) For additional (non-boot) instance disk(s), include the --disk=name=<data-disk-name> parameter in the command request, where <data-disk-name> is the name of your non-boot disk, protected with CMK, that you want to attach to the instance:

gcloud compute instances create cc-encrypted-production-instance
	--zone=us-central1-a
	--project=cc-web-stack-project-123123
	--machine-type=n1-standard-8
	--image-project=cc-web-stack-project-123123
	--image=cc-production-boot-disk-image
	--boot-disk-size=150GB
	--boot-disk-kms-key=projects/cc-web-stack-project-123123/locations/us/keyRings/cc-production-key-ring/cryptoKeys/cc-production-cmk

17 The command output should return the metadata available for the new VM instance:

Created [https://www.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/zones/us-central1-a/instances/cc-encrypted-production-instance].

NAME                              ZONE           MACHINE_TYPE   INTERNAL_IP  EXTERNAL_IP      STATUS
cc-encrypted-production-instance  us-central1-a  n1-standard-8  10.10.0.5    xxx.xxx.xxx.xxx  RUNNING

18 To avoid extra charges on your Google Cloud bill, you can remove the source (non-compliant) instance from your GCP project. To remove the required instance, run compute instances delete command (Windows/macOS/Linux) using the name of the source instance that you want to delete as identifier parameter, to remove the selected resource from your project:

gcloud compute instances delete cc-production-instance
	--zone us-central1-a

19 Press Y at the command prompt to confirm the Google Cloud resource removal:

The following instances will be deleted. Any attached disks configured to be auto-deleted will be deleted unless they are attached to any other instances or the `--keep-disks` flag is given and specifies them for keeping. Deleting a disk is irreversible and any data on the disk will be lost.
 - [cc-production-instance] in [us-central1-a]
Do you want to continue (Y/n)?

20 The command output should return the URL of the deleted virtual machine (VM) instance:

Deleted [https://www.googleapis.com/compute/v1/projects/cc-web-stack-project-123123/zones/us-central1-a/instances/cc-production-instance].

21 Repeat steps no. 7 – 20 to enable encryption at rest with Customer-Managed Keys (CMKs) for other VM instances provisioned within the selected project.

22 Repeat steps no. 1 – 21 for each GCP project deployed in your Google Cloud account.

References

Publication date Apr 21, 2021

Unlock the Remediation Steps


Gain free unlimited access
to our full Knowledge Base


Over 750 rules & best practices
for AWS and Azure

You are auditing:

Enable Virtual Machine Disk Encryption with Customer-Managed Keys

Risk level: High