Skip to content

Instantly share code, notes, and snippets.

@stevekerrison
Last active January 4, 2024 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevekerrison/5be8e38d9e5fb0f6de3dab91e6fdd6f8 to your computer and use it in GitHub Desktop.
Save stevekerrison/5be8e38d9e5fb0f6de3dab91e6fdd6f8 to your computer and use it in GitHub Desktop.
Adding UEFI SecureBoot to ARM64 AMIs in AWS EC2
#!/bin/bash
#
# Enable SecureBoot for ARM with Linux AMIs on AWS where the OS is signed against Microsoft's SecureBoot chain
#
# Probably works for x86 too, with some adjustments.
# To use your own keys, follow the AWS docs instead: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/uefi-secure-boot.html
#
# Usage: ./aws-uefi-ms-sb.sh <SOURCE_AMI_ID> <SOURCE_REGION_ID> <DESTINATION_IMAGE_NAME>
#
# Requirements: AWS CLI and jq
#
# The script presumes to copy a public AMI to your AWS account. If you already have an AMI in your account, you can set
# the environment variable IMAGE_ID to skip the copy, e.g.: IMAGE_ID=ami-abcd1235 /aws-uefi-ms-sb.sh - - secboot-img
#
# It also presumes your default profile has a region set. Adjust accordingly.
#
# Author: Steve Kerrison <git@stevekerrison.com>
#
# WARNING: This script will create assets that are billable to your AWS account, so be sure of what it (and you)
# are doing. This script comes with NO WARRANTY.
#
set -ue
SRC_AMI=$1
SRC_REGION=$2
DST_NAME=$3
set +u
#
# Blob produced by https://github.com/canonical/aws-secureboot-blob
# or https://github.com/awslabs/python-uefivars and https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/aws-binary-blob-creation.html
#
UEFI_BLOB="QU1aTlVFRkni4yd4AAAAAHj5a7fZ94NNtzFB6QBvHSgLPQh1kFZboAN096ljUaNA5GJgmIu8Xb1hsUbN2EQ0pUdeiwuXmylcMYdSH4xO5wzUdM5IazkxMoyOq4/scXVqVjuwCjAlyQFHrQMTV2HDVuuwCQBrnR+wWofj8hGwWpahVOvQaJEqLjcjZuGwu3m0Xz/arx/KtdPo+oiRvT4CfVqAktoJAPbjzLE="
if [ -z "$IMAGE_ID" ]; then
echo "Need to copy image"
IMAGE_ID=$(aws ec2 copy-image --name pre-$DST_NAME --source-image-id $SRC_AMI --source-region $SRC_REGION | jq -r '.ImageId')
fi
echo "New AMI will be: $IMAGE_ID"
CMD="aws ec2 describe-images --image-id $IMAGE_ID | jq -r '.Images[0].State'"
echo -n "Waiting for image to be copied and available..."
IMAGE_STATUS=$(eval $CMD)
while [ "$IMAGE_STATUS" != "available" ]; do
echo -n "."
sleep 10
IMAGE_STATUS=$(eval $CMD)
done
echo "Done!"
SNAPSHOT_ID=$(aws ec2 describe-images --image-id $IMAGE_ID | jq -r '.Images[0].BlockDeviceMappings[0].Ebs.SnapshotId')
echo "New snapshot is $SNAPSHOT_ID"
echo "Adding UEFI vars to a new AMI based on the snapshot"
NEW_IMAGE_ID=$(aws ec2 register-image --name $DST_NAME --uefi-data $UEFI_BLOB \
--block-device-mappings "DeviceName=/dev/sda1,Ebs={SnapshotId=$SNAPSHOT_ID}" \
--architecture arm64 --root-device-name /dev/sda1 --virtualization-type hvm --ena-support --boot-mode uefi \
| jq -r '.ImageId')
echo -n "Waiting for new AMI $NEW_IMAGE_ID to be available..."
CMD="aws ec2 describe-images --image-id $NEW_IMAGE_ID | jq -r '.Images[0].State'"
IMAGE_STATUS=$(eval $CMD)
while [ "$IMAGE_STATUS" != "available" ]; do
echo -n "."
sleep 10
IMAGE_STATUS=$(eval $CMD)
done
echo "Done!"
echo "You can now launch a SecureBooted EC2 instance using $NEW_IMAGE_ID!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment