From 8dd36bd4e61bbb25bf1c1ae566ab8e13fa052c0a Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Fri, 2 Feb 2024 23:44:30 +0100 Subject: [PATCH] trustedboot docs (#133) * wip: trustedboot docs * updates * Small refinements * Update content/en/docs/Installation/trustedboot.md Co-authored-by: Mauro Morales * Update content/en/docs/Installation/trustedboot.md Co-authored-by: Itxaka * Small refinements * updates * Update content/en/docs/Architecture/trustedboot.md Co-authored-by: Dimitris Karakasilis * Update content/en/docs/Architecture/trustedboot.md Co-authored-by: Dimitris Karakasilis * Update content/en/docs/Installation/trustedboot.md Co-authored-by: Itxaka * Update content/en/docs/Architecture/trustedboot.md Co-authored-by: Dimitris Karakasilis * Update content/en/docs/Architecture/trustedboot.md Co-authored-by: Dimitris Karakasilis * Update content/en/docs/Installation/trustedboot.md Co-authored-by: Dimitris Karakasilis * reorder * upgrade process --------- Co-authored-by: Itxaka Co-authored-by: Mauro Morales Co-authored-by: Dimitris Karakasilis --- content/en/docs/Architecture/trustedboot.md | 86 ++++++++++ content/en/docs/Getting started/_index.md | 3 +- content/en/docs/Installation/trustedboot.md | 179 ++++++++++++++++++++ content/en/docs/Upgrade/trustedboot.md | 86 ++++++++++ 4 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 content/en/docs/Architecture/trustedboot.md create mode 100644 content/en/docs/Installation/trustedboot.md create mode 100644 content/en/docs/Upgrade/trustedboot.md diff --git a/content/en/docs/Architecture/trustedboot.md b/content/en/docs/Architecture/trustedboot.md new file mode 100644 index 00000000..beec396c --- /dev/null +++ b/content/en/docs/Architecture/trustedboot.md @@ -0,0 +1,86 @@ +--- +title: "Trusted Boot Architecture" +linkTitle: "Trusted Boot" +weight: 6 +date: 2022-11-13 +description: > +--- + +{{% alert title="Warning" %}} +This section is still a work in progress and only available in Kairos v3.x releases and alphas. +{{% /alert %}} + +Trusted boot is a combination of technologies that allows us to enhance the security posture of a running system. It is composed by FDE, Secure Boot and Measured Boot. +Trusted boot is an architectural requirement of [SENA (Secure Edge Native Architecture)](https://www.spectrocloud.com/product/sena) and is a key component of Kairos. + +> You can read more about Trusted Boot in https://0pointer.de/blog/brave-new-trusted-boot-world.html and about SENA here: https://kairos.io/blog/2023/04/18/kairos-is-now-part-of-the-secure-edge-native-architecture-by-spectro-cloud-and-intel/ + +By combining Secure Boot, Measured Boot and FDE we can guarantee that a system was not tampered with, and the user-data is protected by cold attacks, we refer to this combination of technologies stacked together with “Trusted Boot” or “Trusted Boot Experience”. + +*FDE* stands for Full Disk Encryption. It is a security measure that encrypts the entire contents of a disk drive, including the operating system, system files, and user data. The purpose of FDE is to protect data stored on the disk from unauthorized access in the event of theft or loss of the device. + +*Secure Boot* is a security feature in modern computer systems that ensures only properly signed and authenticated OSes are allowed to run during the boot process. It helps prevent the loading of malicious or unauthorized code at the early stages of the system startup, thus helping in protecting the integrity of the boot process. + +*Measured Boot*, on the other hand, is a security mechanism that goes beyond Secure Boot. It involves creating a record, or "measurements," of each step in the boot process and storing these measurements in a specific hardware dedicated to cryptographically secure operations ( trusted platform module, or TPM) or a similar secure storage. This allows the system to verify the integrity of each component of the boot process and detect any unauthorized changes. Measured Boot provides a more comprehensive and continuous security check throughout the boot sequence. + + +### UKI and USI + +[UKI](https://uapi-group.org/specifications/specs/unified_kernel_image/) is a specific file format tailored to achieve a tamper-proof system and encryption of user-data bound to the silicon by relying on HW capabilities. + +> UKI stands for “Unified Kernel Images”. UKI files are a single, fat binary that encompasses the OS and the needed bits in order to boot the full system with a single, verified file. You can read technical details here: [Brave New Trusted Boot World](https://0pointer.de/blog/brave-new-trusted-boot-world.html). + +Trusted Boot in Kairos works by generating UKI images from container images. The UKI file is a single, fat binary that encompasses the OS and the needed bits in order to boot the full system with a single, verified file. This file can be used for upgrades and used as usual in the lifecycle of the Kairos node. + +The UKI file is signed with the Secure Boot keys, and the user-data is encrypted with the PCR policies. The UKI file is then loaded by the firmware and booted directly, without any second stage or system pivoting. This is why the UKI file can grow large, and why it requires a specific firmware that supports booting large EFI files. + +Due to the design choice to not boot into a second stage, this is being refered nowadays as **USI** (Unified System Image) instead of UKI, or more simply "Bootstrap Image". The benefits of using Unified system images in opposite of UKIs are that the system can be upgraded without the need of a second stage, and that the entire system is verified and signed. + +### Building process + +For Trusted boot it is required to build a specific installable ISO file medium that contains the UKI files and a container image used for upgrades. Every time to upgrade a system it is required to re-generate the assets with the same keys and use the generated container image for the upgrades. + +The UKI files are generated from container images as usual. + +![Trusted boot](https://github.com/kairos-io/kairos-docs/assets/2420543/2f49d592-9ae3-43ee-b22b-0313be455bf7) + +The process to generate the installable medium is described in the [Trustedboot installation documentation]({{%relref "/docs/installation/trustedboot" %}}). Internally we rely on the *osbuilder* tool to generate all the installation artifacts from a single container image. + +### Booting process + +![boot_1](https://github.com/kairos-io/kairos-docs/assets/2420543/9c406796-b622-4571-abd5-b8d8fed44591) + +The booting process of an installed system with Trusted Boot is different from a standard Kairos installation, and can be split down in 4 steps: + +1. The Firmware loads the `systemd-boot` bootloader from the EFI partition +2. `systemd-boot` loads the UKI file from the EFI partition (that can be either the Active system, the passive or recovery system) +3. The EFI system starts. The kernel and the initrd are loaded from the UKI file, and the kernel is booted with the command line specified in the UKI file. +4. The initrd will decrypt the user-data and mount the portions of it in the root filesystem. This includes for instance any changes to `/etc` (like adding new users and passwords), `/usr/local`, and all the mount bindpoints specified in the configuration file (see [Bind mount d ocumentation]({{%relref "/docs/advanced/customizing#bind-mounts" %}}) ). There is no second stage loaded and no system pivoting, the system is booted directly from the UKI file. + +### Booting system + +![Trusted boot](https://github.com/kairos-io/kairos-docs/assets/2420543/757870d3-3b40-46ea-9c86-13c4a545f167) + +There is no difference with a layout of a standard Kairos system (as explained in the [Immutable OS]({{%relref "/docs/architecture/immutable" %}}) page), however in this setup now the partitions containing data are always encrypted: + +- [List of persistent data path overlayed and encrypted](https://github.com/kairos-io/packages/blob/528682cddf7191fb52580e7c41a33e73c1ee0001/packages/static/kairos-overlay-files/files/system/oem/00_rootfs_uki.yaml#L18) (see also [the bind mount documentation]({{%relref "/docs/advanced/customizing#bind-mounts" %}}) to customize it with your own paths). +- `/oem` encrypted +- `/usr/local` encrypted +- `/etc` ephemeral +- `/usr` read only +- `/` immutable + +### User data encryption and key generation + +It is required in order to generate USI images to have a set of keys and certificates. In order to understand why those keys are required, we need to understand how the user-data is encrypted and how the system is booted. + +![bootingkeys](https://github.com/kairos-io/kairos-docs/assets/2420543/725745a0-0ea6-4330-bea3-e6483f53cc3f) + + +The keys are used to sign the UKI file, and to generate a PCR policy keypair required later on by the system in order to decrypt the encrypted partitions. The keys and certificates are generated with the `enki` tool, that is available in the `enki` container image. + +### Considerations + +#### Booting command lines + +UKI file's signatures are including also the kernel command line, so any change to the kernel command line will require a new UKI file to be generated and the installer image to be rebuilt. This implies that you cannot change the booting options once the system is installed (and the system won't be able to access the encrypted data) \ No newline at end of file diff --git a/content/en/docs/Getting started/_index.md b/content/en/docs/Getting started/_index.md index 5c6b8888..6b846446 100644 --- a/content/en/docs/Getting started/_index.md +++ b/content/en/docs/Getting started/_index.md @@ -8,7 +8,8 @@ description: > --- {{% alert title="Note" %}} -If you prefer video format, you can also watch our [Introduction to Kairos video]({{< relref "Media#introduction-to-kairos" >}} "Media") on the [Media Section]({{< relref "Media" >}} "Media") +- If you prefer video format, you can also watch our [Introduction to Kairos video]({{< relref "Media#introduction-to-kairos" >}} "Media") on the [Media Section]({{< relref "Media" >}} "Media") +- If you are looking into installing Kairos with Full disk encryption, see [here]({{< relref "../installation/trustedboot" >}}) {{% /alert %}} Ready to launch your Kubernetes cluster with ease? With Kairos, deployment is a breeze! Simply download the pre-packaged artifacts, boot up on a VM or bare metal, and let Kairos handle the rest. Whether you're a Linux or Windows user, our quickstart guide will have you up and running in no time. Kairos can build a Kubernetes cluster for you with just a few simple steps! diff --git a/content/en/docs/Installation/trustedboot.md b/content/en/docs/Installation/trustedboot.md new file mode 100644 index 00000000..6bb63023 --- /dev/null +++ b/content/en/docs/Installation/trustedboot.md @@ -0,0 +1,179 @@ +--- +title: "Trusted Boot Installations" +linkTitle: "Trusted Boot" +weight: 6 +date: 2022-11-13 +description: > +--- + +{{% alert title="Warning" %}} +This section is still a work in progress and only available in Kairos v3.x releases and alphas. +{{% /alert %}} + +"Trusted Boot" is a combination of technologies that allows us to guarantee that a system was not tampered with, and the user-data is protected by cold attacks, it is composed by FDE, Secure Boot and Measured Boot. + +If you want to learn more on what Trusted Boot is and how it works, see the [Trusted Boot Architecture]({{< relref "../architecture/trustedboot" >}}) page. This page describes how to enable Trusted Boot support in Kairos. + +Kairos supports Trusted boot by generating specific installable medium. This feature is optional and works alongside how Kairos works. + +## Requirements + +The Hardware that will run Kairos needs to have the following requirements: + +- Secure boot available in the system +- The Hardware should have a TPM chip or fTPM enabled +- The Hardware should be capable of booting large EFI files (>32MB) +- Base image of the OS needs to have at least systemd 252 or newer ( for example ubuntu >=23.10 or fedora >=38 ) + +To build the installable medium you need the following installed in the system you use to build the installable medium: + +- Docker +- Git +- A Linux machine with KVM (for testing the images locally) + +## Usage + +In order to boot into UKI mode, you need to build a special ISO file with the UKI files. To build this medium you have to generate a set of keypairs first: one for the Secure boot and one for the PCR policies required to encrypt the user-data. + +Any change, or upgrade of the node to a new version of the OS requires those assets to be regenerated with these keypairs, including the installer ISO, and the EFI files used for upgrading. The keys are used to *sign* and *verify* the EFI files, and the PCR policies are used to *encrypt* and *decrypt* the user-data, and thus are required to be the same for the whole lifecycle of the node. + +The steps below will guide you into generating the installable assets, and how to re-generate the assets to upgrade the node to a new version of the OS. + +## Build the container image used to generate keys and installable medium + +```bash +# Build the container image that will be used to generate the keys and installable medium +git clone https://github.com/kairos-io/enki.git +cd enki +docker build -t enki --target tools-image . +``` + +## Key generation + +To generate the Secure boot certificates and keys run the following commands: + +```bash +MY_ORG="Acme Corp" +# Generate the keys +docker run -v $PWD/keys:/work/keys -ti --rm enki genkey "$MY_ORG" -o /work/keys +``` +{{% alert title="Warning" %}} +Substitute `$MY_ORG` for your own string, this can be anything but it help identifying the Keys +{{% /alert %}} + +{{% alert title="Warning" %}} +It is very important to preserve the keys generated in this process in a safe place. Loosing the keys will prevent you to generate new images that can be used for upgrades. +{{% /alert %}} + +## Building installable medium + +To build the installable medium you need to run the following commands: + +{{< tabpane text=true >}} +{{% tab header="From a container image" %}} +```bash +CONTAINER_IMAGE=quay.io/kairos/fedora:38-core-amd64-generic-v3.0.0-alpha1 +# ubuntu: +# CONTAINER_IMAGE=quay.io/kairos/ubuntu:23.10-core-amd64-generic-v3.0.0-alpha1 +docker run -ti --rm -v $PWD/build:/result -v $PWD/keys/:/keys enki build-uki $CONTAINER_IMAGE -t iso -d /result/ -k /keys +``` +{{% /tab %}} +{{% tab header="From a directory" %}} +```bash +# Assuming you have a "rootfs" directory with the content of the OS +# If the image is in a directory ($PWD/rootfs) you can use the following command +docker run -ti --rm -v $PWD/build:/result -v $PWD/rootfs:/rootfs -v $PWD/keys/:/keys enki build-uki dir:/rootfs/ -t iso -d /result/ -k /keys +``` +{{% /tab %}} +{{< /tabpane >}} + +## Installation + +The installation process is performed as usual and the [Installation instructions]({{< relref "../installation" >}}) can be followed, however the difference is that user-data will be automatically encrypted (both the OEM and the persistent partition) by using the TPM chip and the Trusted Boot mechanism. + +### Enroll the keys in Secure Boot + +If your machine is in UEFI setup mode Secure Boot keys will be automatically enrolled. To enter UEFI Setup mode you need to clear the Secure Boot keys (PKs) from the BIOS/UEFI. + +If UEFI setup mode is not available, you need to enroll the keys manually in the BIOS/UEFI. + +This process can vary depending on the vendor, but in general you need to enter the BIOS/UEFI setup during early boot and import the keys, for an example outline you can check the steps for [HPE Hardware](https://techlibrary.hpe.com/docs/iss/proliant-gen10-uefi/GUID-E4427875-D123-4BBF-9056-342168478A02.html). + +A video of the process of importing keys in QEMU is available [here](https://github.com/kairos-io/kairos/assets/2420543/e45f6a08-ec74-4cfd-bdf0-aeb7b23ac9bc). + +## Upgrades + +See the [Trusted Boot Upgrade]({{< relref "../upgrade/trustedboot" >}}) page. + +## Testing the images locally + +To test the ISO file locally QEMU can be used. In order to test Secure Boot components you need an ed2k firmware with secureboot in QEMU. If you don't have QEMU locally and/or you don't have the correct dependencies you can follow the steps below that build a container image with QEMU and the needed dependencies and use that container to run the ISO file in a VM with Docker. + +1. Build the container image with the QEMU/Secure Boot dependencies (note to replace disk, VM size and ISO file name): + +```bash +docker build -t fedora-qemu -<> /entrypoint.sh +echo 'nohup swtpm socket --tpmstate dir=/tmp/ --ctrl type=unixio,path=/tmp/swtpm-sock --log level=20 --tpm2 &>/dev/null & ' >> /entrypoint.sh +echo '[ ! -e /work/disk.img ] && qemu-img create -f qcow2 "/work/disk.img" 8G' >> /entrypoint.sh +echo '/usr/bin/qemu-system-x86_64 -drive if=pflash,format=raw,unit=0,file="/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd",readonly=on -drive if=pflash,unit=1,format=raw,file="/efivars.fd" -accel kvm -cpu host -m 8096 -drive file=/work/disk.img,if=none,index=0,media=disk,format=qcow2,id=disk1 -device virtio-blk-pci,drive=disk1,bootindex=0 -boot order=dc -vga virtio -cpu host -smp cores=4,threads=1 -machine q35,smm=on -chardev socket,id=chrtpm,path=/tmp/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0 \$@' >> /entrypoint.sh +EOF +RUN chmod +x /entrypoint.sh +ENTRYPOINT [ "/entrypoint.sh" ] +DOCKER +``` + +2. Run the container image with the ISO file (replace the iso file name with yours): + +```bash +# console only +docker run --privileged -v $PWD:/work -v /dev/kvm:/dev/kvm --rm -ti fedora-qemu -cdrom /work/kairos-fedora-38-core-amd64-generic-v3.0.0-alpha1.uki.iso -nographic +``` + +Note: To stop the QEMU container you can use `Ctrl-a x` or `Ctrl-a c` to enter the QEMU console and then `quit` to exit. + +## Data Encryption + +The user-data will be automatically encrypted during installation, along with the OEM and the persistent partition by using the TPM chip and the Trusted Boot mechanism. + +### Additional partitions + +Additional partitions can be encrypted and specified as part of the cloud-config used during the installation process, for example: + +```yaml +install: + extra-partitions: + - name: second_partition + size: 100 + fs: ext2 + label: PARTITION_TWO + encrypted_partitions: + - PARTITION_TWO +``` + +A full example can be: +```yaml +install: + device: "auto" # Install to the biggest drive + auto: true # Enables auto installation + partitions: + persistent: + size: 500 # Set persistent partition to 500MB (otherwise takes the whole disk) + extra-partitions: + - name: second_partition + size: 100 + fs: ext2 + label: PARTITION_TWO + encrypted_partitions: + - PARTITION_TWO +``` diff --git a/content/en/docs/Upgrade/trustedboot.md b/content/en/docs/Upgrade/trustedboot.md new file mode 100644 index 00000000..989242a1 --- /dev/null +++ b/content/en/docs/Upgrade/trustedboot.md @@ -0,0 +1,86 @@ +--- +title: "Trusted Boot Upgrades" +linkTitle: "Trusted Boot Upgrades" +weight: 6 +date: 2022-11-13 +description: > +--- + + +{{% alert title="Warning" %}} +This section is still a work in progress and only available in Kairos v3.x releases and alphas. +{{% /alert %}} + +This section covers how to upgrade a Kairos node with Trusted Boot enabled. + +See the [Trusted Boot Installation]({{< relref "../installation/trustedboot" >}}) and [Trusted Boot Architecture]({{< relref "../architecture/trustedboot" >}}) pages for more references. + +### Upgrades + +In order to upgrade a node to a new version of the OS, you need to generate again the installable medium with the same keys used in the steps before. + +{{% alert title="Note" %}} +The resulting container image can be used for upgrades with `kairos-agent`. +{{% /alert %}} + +The process will generate an EFI file which we will pack into a container image that will be used to upgrade the node. + +First we need to extract the EFI file from the ISO file generated with what explained in the [Trusted Boot Installation documentation]({{< relref "../installation/trustedboot" >}}): + +{{% alert title="Warning" %}} +This step is required until [#2171](https://github.com/kairos-io/kairos/issues/2171) is implemented. +{{% /alert %}} + +#### Generate the upgrade image + +1. Build the container image used to generate the upgrade image + +```bash +# Build the container image that will be used to generate the keys and installable medium +git clone https://github.com/kairos-io/enki.git +cd enki +docker build -t enki --target tools-image . +``` + +2. Build the Container image used for upgrades + +```bash +CONTAINER_IMAGE=quay.io/kairos/fedora:38-core-amd64-generic-v3.0.0-alpha1 + +# ubuntu: +# CONTAINER_IMAGE=quay.io/kairos/ubuntu:23.10-core-amd64-generic-v3.0.0-alpha1 +docker run --rm -v $PWD/keys:/keys -v $PWD:/work -ti enki build-uki $CONTAINER_IMAGE -t uki -d /work/upgrade-image -k /keys + + +CONF=$(basename $(ls -1 $PWD/upgrade-image/loader/entries/*.conf)) +# Replace with the version of the OS you are upgrading to (next boot auto selection) +cat < upgrade-image/loader/loader.conf +default $CONF +timeout 5 +console-mode max +editor no +EOF + +## Generate the container image +docker run --rm -v $PWD:/work --entrypoint /bin/tar -ti enki -cf /work/src.tar /work/upgrade-image + +CONTAINER_IMAGE_NAME="my-upgrade-image" +docker run -ti -v $PWD:/work quay.io/luet/base:latest util pack $CONTAINER_IMAGE_NAME /work/src.tar /work/upgrade_image.tar + +``` + +3. Push the upgrade image to a registry + +```bash +# Now you can load upgrade_image.tar to a registry and use it with kairos-agent +docker load -i upgrade_image.tar + +docker push $CONTAINER_IMAGE_NAME +``` + +{{% alert title="Upgrades with Kubernetes" %}} + +In order to upgrade with Kubernetes using system upgrade controller plans you can use the image used to generate the installable medium, and use it as a base image for the upgrade image. +When invoking `kairos-agent` in the plan however, you need to specify the `--source` flag to point to the image that contains the UKI file. + +{{% /alert %}}