2022-05-30 05:38:06 -04:00
## Setup
2022-10-19 07:10:15 -04:00
- Install mkosi (from git):
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
```sh
cd /tmp/
git clone https://github.com/systemd/mkosi
cd mkosi
tools/generate-zipapp.sh
cp builddir/mkosi /usr/local/bin/
```
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
- Install tools:
< details >
< summary > Ubuntu / Debian< / summary >
```sh
sudo apt-get update
sudo apt-get install --assume-yes --no-install-recommends \
dnf \
systemd-container \
qemu-system-x86 \
qemu-utils \
ovmf \
e2fsprogs \
squashfs-tools \
efitools \
sbsigntool \
coreutils \
curl \
jq \
util-linux \
2022-10-17 11:39:49 -04:00
virt-manager \
2022-10-24 06:23:18 -04:00
python3-crc32c \
rpm
2022-10-19 07:10:15 -04:00
```
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
< / details >
< details >
< summary > Fedora< / summary >
```sh
sudo dnf install -y \
edk2-ovmf \
systemd-container \
qemu \
e2fsprogs \
squashfs-tools \
efitools \
sbsigntools \
coreutils \
curl \
jq \
util-linux \
virt-manager
2022-05-30 05:38:06 -04:00
```
2022-10-19 07:10:15 -04:00
< / details >
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
- Prepare secure boot PKI (see `secure-boot/genkeys.sh` )
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
## Build
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
When building your first image, prepare the secure boot PKI (see `secure-boot/genkeys.sh` ) for self-signed, locally built images.
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
After that, you can build the image with:
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
```sh
# OPTIONAL: to create a debug image, export the following line
# export BOOTSTRAPPER_BINARY=$(realpath ${PWD}/../../build/debugd)
2023-01-16 06:20:01 -05:00
# OPTIONAL: to enable the serial console, export the following line
# export AUTOLOGIN=true
2022-10-19 07:10:15 -04:00
# OPTIONAL: symlink custom path to secure boot PKI to ./pki
# ln -s /path/to/pki/folder ./pki
sudo make -j $(nproc)
```
2022-05-30 05:38:06 -04:00
2022-11-17 06:12:00 -05:00
Raw images will be placed in `mkosi.output.<CSP>/fedora~37/image.raw` .
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
## Prepare Secure Boot
2022-08-09 03:05:05 -04:00
2022-10-19 07:10:15 -04:00
The generated images are partially signed by Microsoft ([shim loader](https://github.com/rhboot/shim)), and partially signed by Edgeless Systems (systemd-boot and unified kernel images consisting of the linux kernel, initramfs and kernel commandline).
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
For QEMU and Azure, you can pre-generate the NVRAM variables for secure boot. This is not necessary for GCP, as you can specify secure boot parameters via the GCP API on image creation.
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
< details >
2022-11-16 09:45:10 -05:00
< summary > < a id = "qemu-secure-boot" > libvirt / QEMU / KVM< / a > < / summary >
2022-08-02 11:14:13 -04:00
2022-10-19 07:10:15 -04:00
```sh
2022-11-17 06:12:00 -05:00
secure-boot/generate_nvram_vars.sh mkosi.output.qemu/fedora~37/image.raw
2022-08-02 11:14:13 -04:00
```
2022-10-19 07:10:15 -04:00
< / details >
2022-08-09 03:05:05 -04:00
2022-10-19 07:10:15 -04:00
< details >
< summary > < a id = "azure-secure-boot" > Azure< / a > < / summary >
2022-08-09 03:05:05 -04:00
2022-10-19 07:10:15 -04:00
These steps only have to performed once for a fresh set of secure boot certificates.
VMGS blobs for testing and release images already exist.
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
First, create a disk without embedded MOK EFI variables.
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
```sh
# set these variables
export AZURE_SECURITY_TYPE=ConfidentialVM # or TrustedLaunch
export AZURE_RESOURCE_GROUP_NAME= # e.g. "constellation-images"
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
export AZURE_REGION=northeurope
2022-11-04 11:48:52 -04:00
export AZURE_REPLICATION_REGIONS=
2022-10-19 07:10:15 -04:00
export AZURE_DISK_NAME=constellation-$(date +%s)
export AZURE_SNAPSHOT_NAME=${AZURE_DISK_NAME}
2022-11-17 06:12:00 -05:00
export AZURE_RAW_IMAGE_PATH=${PWD}/mkosi.output.azure/fedora~37/image.raw
export AZURE_IMAGE_PATH=${PWD}/mkosi.output.azure/fedora~37/image.vhd
2022-10-19 07:10:15 -04:00
export AZURE_VMGS_FILENAME=${AZURE_SECURITY_TYPE}.vmgs
2022-11-17 06:12:00 -05:00
export AZURE_JSON_OUTPUT=${PWD}/mkosi.output.azure/fedora~37/image-upload.json
2022-10-19 07:10:15 -04:00
export BLOBS_DIR=${PWD}/blobs
upload/pack.sh azure "${AZURE_RAW_IMAGE_PATH}" "${AZURE_IMAGE_PATH}"
upload/upload_azure.sh --disk-name "${AZURE_DISK_NAME}-setup-secure-boot" ""
secure-boot/azure/launch.sh -n "${AZURE_DISK_NAME}-setup-secure-boot" -d --secure-boot true --disk-name "${AZURE_DISK_NAME}-setup-secure-boot"
```
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
Ignore the running launch script and connect to the serial console once available.
The console shows the message "Verification failed: (0x1A) Security Violation". You can import the MOK certificate via the UEFI shell:
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
Press OK, then ENTER, then "Enroll key from disk".
Select the following key: `/EFI/loader/keys/auto/db.cer` .
Press Continue, then choose "Yes" to the question "Enroll the key(s)?".
Choose reboot.
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
Extract the VMGS from the running VM (this includes the MOK EFI variables) and delete the VM:
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
```sh
secure-boot/azure/extract_vmgs.sh --name "${AZURE_DISK_NAME}-setup-secure-boot"
secure-boot/azure/delete.sh --name "${AZURE_DISK_NAME}-setup-secure-boot"
```
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
< / details >
## Upload to CSP
2022-10-17 11:39:49 -04:00
< details >
< summary > AWS< / summary >
- Install `aws` cli (see [here ](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html ))
- Login to AWS (see [here ](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html ))
- Choose secure boot PKI public keys (one of `pki_dev` , `pki_test` , `pki_prod` )
- `pki_dev` can be used for local image builds
- `pki_test` is used by the CI for non-release images
- `pki_prod` is used for release images
```sh
# set these variables
export AWS_IMAGE_NAME= # e.g. "constellation-v1.0.0"
export PKI=${PWD}/pki
export AWS_REGION=eu-central-1
export AWS_REPLICATION_REGIONS="us-east-2"
export AWS_BUCKET=constellation-images
2022-11-17 06:12:00 -05:00
export AWS_EFIVARS_PATH=${PWD}/mkosi.output.aws/fedora~37/efivars.bin
export AWS_IMAGE_PATH=${PWD}/mkosi.output.aws/fedora~37/image.raw
2022-10-17 11:39:49 -04:00
export AWS_IMAGE_FILENAME=image-$(date +%s).raw
2022-11-17 06:12:00 -05:00
export AWS_JSON_OUTPUT=${PWD}/mkosi.output.aws/fedora~37/image-upload.json
2022-10-17 11:39:49 -04:00
secure-boot/aws/create_uefivars.sh "${AWS_EFIVARS_PATH}"
2022-11-16 09:45:10 -05:00
upload/upload_aws.sh
2022-10-17 11:39:49 -04:00
```
< / details >
2022-10-19 07:10:15 -04:00
< details >
< summary > GCP< / summary >
- Install `gcloud` and `gsutil` (see [here ](https://cloud.google.com/sdk/docs/install ))
- Login to GCP (see [here ](https://cloud.google.com/sdk/docs/authorizing ))
- Choose secure boot PKI public keys (one of `pki_dev` , `pki_test` , `pki_prod` )
- `pki_dev` can be used for local image builds
- `pki_test` is used by the CI for non-release images
- `pki_prod` is used for release images
```sh
# set these variables
export GCP_IMAGE_FAMILY= # e.g. "constellation"
export GCP_IMAGE_NAME= # e.g. "constellation-v1.0.0"
export PKI=${PWD}/pki
export GCP_PROJECT=constellation-images
export GCP_REGION=europe-west3
export GCP_BUCKET=constellation-images
2022-11-17 06:12:00 -05:00
export GCP_RAW_IMAGE_PATH=${PWD}/mkosi.output.gcp/fedora~37/image.raw
2022-10-19 07:10:15 -04:00
export GCP_IMAGE_FILENAME=$(date +%s).tar.gz
2022-11-17 06:12:00 -05:00
export GCP_IMAGE_PATH=${PWD}/mkosi.output.gcp/fedora~37/image.tar.gz
export GCP_JSON_OUTPUT=${PWD}/mkosi.output.gcp/fedora~37/image-upload.json
2022-10-19 07:10:15 -04:00
upload/pack.sh gcp ${GCP_RAW_IMAGE_PATH} ${GCP_IMAGE_PATH}
upload/upload_gcp.sh
```
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
< / details >
< details >
< summary > Azure< / summary >
2022-11-09 04:11:23 -05:00
Note:
> For testing purposes, it is a lot simpler to disable Secure Boot for the uploaded image!
> Disabling Secure Boot allows you to skip the VMGS creation steps above.
2022-10-19 07:10:15 -04:00
- Install `az` and `azcopy` (see [here ](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli ))
- Login to Azure (see [here ](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli ))
2022-11-09 04:11:23 -05:00
- Optional (if Secure Boot should be enabled) [Prepare virtual machine guest state (VMGS) with customized NVRAM or use existing VMGS blob ](#azure-secure-boot )
2022-10-19 07:10:15 -04:00
```sh
# set these variables
export AZURE_GALLERY_NAME= # e.g. "Constellation"
export AZURE_IMAGE_DEFINITION= # e.g. "constellation"
export AZURE_IMAGE_VERSION= # e.g. "1.0.0"
2022-11-09 04:11:23 -05:00
# Set this variable to a path if you want to use Secure Boot.
# Otherwise, set it to export AZURE_VMGS_PATH=
export AZURE_VMGS_PATH= # e.g. nothing OR "path/to/ConfidentialVM.vmgs"
# AZURE_SECURITY_TYPE can be one of
# - "ConfidentialVMSupported" (ConfidentialVM with secure boot disabled),
# - "ConfidentialVM" (ConfidentialVM with Secure Boot) or
# - TrustedLaunch" (Trusted Launch with or without Secure Boot)
export AZURE_SECURITY_TYPE=ConfidentialVMSupported
2022-10-19 07:10:15 -04:00
export AZURE_RESOURCE_GROUP_NAME=constellation-images
export AZURE_REGION=northeurope
export AZURE_REPLICATION_REGIONS="northeurope eastus westeurope westus"
export AZURE_IMAGE_OFFER=constellation
2022-12-09 07:20:00 -05:00
export AZURE_SKU=${AZURE_IMAGE_DEFINITION}
2022-10-19 07:10:15 -04:00
export AZURE_PUBLISHER=edgelesssys
export AZURE_DISK_NAME=constellation-$(date +%s)
2022-11-17 06:12:00 -05:00
export AZURE_RAW_IMAGE_PATH=${PWD}/mkosi.output.azure/fedora~37/image.raw
export AZURE_IMAGE_PATH=${PWD}/mkosi.output.azure/fedora~37/image.vhd
export AZURE_JSON_OUTPUT=${PWD}/mkosi.output.azure/fedora~37/image-upload.json
2022-10-19 07:10:15 -04:00
upload/pack.sh azure "${AZURE_RAW_IMAGE_PATH}" "${AZURE_IMAGE_PATH}"
upload/upload_azure.sh -g --disk-name "${AZURE_DISK_NAME}" "${AZURE_VMGS_PATH}"
```
2022-05-30 05:38:06 -04:00
2022-10-19 07:10:15 -04:00
< / details >
2022-11-16 09:45:10 -05:00
< details >
< summary > QEMU< / summary >
- Install `aws` cli (see [here ](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html ))
- Login to AWS (see [here ](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html ))
```sh
# set these variables
2022-12-09 05:51:38 -05:00
export REF= # e.g. feat-xyz (branch name encoded with dashes)
export STREAM= # e.g. "nightly", "debug", "stable" (depends on the type of image and if it is a release)
export IMAGE_VERSION= # e.g. v2.1.0" or output of pseudo-version tool
2022-11-17 10:14:38 -05:00
export QEMU_BUCKET=cdn-constellation-backend
2022-11-16 09:45:10 -05:00
export QEMU_BASE_URL="https://cdn.confidential.cloud"
2022-11-17 06:12:00 -05:00
export QEMU_IMAGE_PATH=${PWD}/mkosi.output.qemu/fedora~37/image.raw
export QEMU_JSON_OUTPUT=${PWD}/mkosi.output.qemu/fedora~37/image-upload.json
2022-11-16 09:45:10 -05:00
upload/upload_qemu.sh
```
< / details >