Description

Ensure that every Amazon EBS volume in the account is encrypted at rest with AWS KMS. An existing unencrypted volume cannot be encrypted in place; it must be replaced with an encrypted volume created from a snapshot of the original.

Rationale

Data on an unencrypted EBS volume, and on any snapshot taken from it, is stored in plaintext. Anyone who gains access to the volume or its snapshots can copy and read the raw data offline, harvest secrets, or alter system images. Encrypting all volumes with AWS KMS, and turning on EBS encryption by default for new volumes and snapshot copies, protects the confidentiality and integrity of data at rest.

Impact

  • Protects data at rest on the volume and on all snapshots taken from it

  • Replacing a volume requires stopping the instance (or unmounting the volume), which causes downtime for the workload

  • The encrypted volume has a new volume ID, so backups, scripts or monitoring that reference the old ID must be updated

Default Value

EBS volumes are not encrypted by default unless EBS encryption by default is turned on in the region, or encryption is selected when the volume is created.

Pre-Requisites

  • IAM permissions: ec2:DescribeVolumes, ec2:CreateSnapshot, ec2:CreateVolume, ec2:StopInstances, ec2:DetachVolume, ec2:AttachVolume, ec2:StartInstances, ec2:DeleteVolume and permission to use the KMS key

  • A maintenance window, because the instance must be stopped (or the volume unmounted) while the volume is replaced

  • For each volume: its Availability Zone, size, volume type, and the instance ID and device name it is attached to

Remediation

Test Plan

Console:

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the Amazon EC2 console and select Volumes under Elastic Block Store.

  3. Check the Encryption column of each volume.

  4. Repeat for each region in use.

  5. If any volume is Not encrypted, follow the implementation steps.

CLI:

List the unencrypted volumes with their attachment:

aws ec2 describe-volumes --filters Name=encrypted,Values=false --region <REGION> --query "Volumes[].[VolumeId,State,Size,AvailabilityZone,Attachments[0].InstanceId,Attachments[0].Device]" --output table

A volume fails if it is listed by this command. Both attached and unattached volumes are evaluated.

Implementation Steps

Console:

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the Amazon EC2 console and select Volumes under Elastic Block Store.

  3. Select the unencrypted volume and note its Availability Zone, attached instance and device name.

  4. Stop the instance that uses the volume (or stop the application and unmount the volume) so that no data is written after the snapshot. Warning: this causes downtime until the instance is started again.

  5. Select the volume, choose Actions, then Create snapshot, and wait until the snapshot status is Completed.

  6. Select the snapshot under Snapshots, choose Actions, then Create volume from snapshot:

    • select the same Volume type and Availability Zone as the original volume,

    • select Encrypt this volume and choose the KMS key,

    • choose Create volume.

  7. Select the old volume, choose Actions, then Detach volume.

  8. Select the new encrypted volume, choose Actions, then Attach volume, select the instance and enter the same device name.

  9. Start the instance and check that the application works and the volume shows as encrypted.

  10. Repeat for each affected volume in each region in use.

CLI:

The suggested single command chains several steps that each need an ID returned by the previous one, and the extra encrypted snapshot copy is not needed, so the steps are shown separately below.

Stop the instance first so that no data is written after the snapshot (warning: this causes downtime until the instance is started again):

aws ec2 stop-instances --instance-ids <INSTANCE_ID> --region <REGION>

Create a snapshot of the unencrypted volume and wait until it is completed:

aws ec2 create-snapshot --volume-id <VOLUME_ID> --description "Snapshot for encryption of <VOLUME_ID>" --region <REGION>

Create an encrypted volume from the snapshot in the same Availability Zone, with the same volume type as the original volume:

aws ec2 create-volume --snapshot-id <SNAPSHOT_ID> --availability-zone <AVAILABILITY_ZONE> --volume-type <VOLUME_TYPE> --encrypted --kms-key-id <KMS_KEY_ARN> --region <REGION>

Detach the old volume:

aws ec2 detach-volume --volume-id <VOLUME_ID> --region <REGION>

Attach the encrypted volume with the same device name and start the instance:

aws ec2 attach-volume --volume-id <NEW_VOLUME_ID> --instance-id <INSTANCE_ID> --device <DEVICE_NAME> --region <REGION>
aws ec2 start-instances --instance-ids <INSTANCE_ID> --region <REGION>

After the instance has been verified, delete the old unencrypted volume:

aws ec2 delete-volume --volume-id <VOLUME_ID> --region <REGION>

Backout Plan

Keep the old unencrypted volume until the instance has been verified with the new volume.

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the Amazon EC2 console and stop the instance.

  3. Under Volumes, detach the new encrypted volume.

  4. Attach the original volume to the instance with the original device name.

  5. Start the instance.

CLI:

aws ec2 stop-instances --instance-ids <INSTANCE_ID> --region <REGION>
aws ec2 detach-volume --volume-id <NEW_VOLUME_ID> --region <REGION>
aws ec2 attach-volume --volume-id <VOLUME_ID> --instance-id <INSTANCE_ID> --device <DEVICE_NAME> --region <REGION>
aws ec2 start-instances --instance-ids <INSTANCE_ID> --region <REGION>

Note: rolling back leaves the instance data unencrypted at rest.

Reference