From cf2cfd873d3472f324aad930d75f233c9670710c Mon Sep 17 00:00:00 2001 From: Jiale Zhang Date: Fri, 21 Oct 2022 21:47:18 +0800 Subject: [PATCH] QuickStart: Reorganize and refined simplification Fixed: #96 The current quick start is relatively lengthy, this commit make the technology stacks for special HW separate markdown pages: - Use simple-kbs to encrypt container image and deploy it on SEV: `guides/sev-guide.md` - Use Verdictd to encrypt container image and deploy it on TDX: `guides/eaa-verdictd-guide.md` Signed-off-by: Jiale Zhang --- guides/eaa-verdictd-guide.md | 52 +++ guides/sev-guide.md | 548 +++++++++++++++++++++++++++++++ quickstart.md | 610 +---------------------------------- 3 files changed, 607 insertions(+), 603 deletions(-) create mode 100644 guides/eaa-verdictd-guide.md create mode 100644 guides/sev-guide.md diff --git a/guides/eaa-verdictd-guide.md b/guides/eaa-verdictd-guide.md new file mode 100644 index 0000000..34953d4 --- /dev/null +++ b/guides/eaa-verdictd-guide.md @@ -0,0 +1,52 @@ +# EAA Verdictd Guide + +EAA is used to perform attestation at runtime and provide guest with confidential resources such as keys. +It is based on [rats-tls](https://github.com/inclavare-containers/rats-tls). + +[Verdictd](https://github.com/inclavare-containers/verdictd) is the Key Broker Service and Attestation Service of EAA. +The EAA KBC is an optional module in the attestation-agent at compile time, +which can be used to communicate with Verdictd. +The communication is established on the encrypted channel provided by rats-tls. + +EAA can now be used on intel TDX and intel SGX platforms. + +## Create encrypted image + +Before build encrypted image, you need to make sure Skopeo and Verdictd(EAA KBS) have been installed: +- [Skopeo](https://github.com/containers/skopeo): the command line utility to perform encryption operations. +- [Verdictd](https://github.com/inclavare-containers/verdictd): EAA Key Broker Service and Attestation Service. + +1. Pull unencrypted image. + +Here use `alpine:latest` for example: + +```sh +${SKOPEO_HOME}/bin/skopeo copy --insecure-policy docker://docker.io/library/alpine:latest oci:busybox +``` + +2. Follow the [Verdictd README #Generate encrypted container image](https://github.com/inclavare-containers/verdictd#generate-encrypted-container-image) to encrypt the image. + +3. Publish the encrypted image to your registry. + +## Deploy encrypted image + +1. Build rootfs with EAA component: + +Specify `AA_KBC=eaa_kbc` parameters when using kata-containers `rootfs.sh` scripts to create rootfs. + +2. Launch Verdictd + +Verdictd performs remote attestation at runtime and provides the key needed to decrypt the image. +It is actually both Key Broker Service and Attestation Service of EAA. +So when deploy the encrypted image, Verdictd is needed to be launched: + +```sh +verdictd --listen <$ip>:<$port> --mutual +``` + +> **Note** The communication between Verdictd and EAA KBC is based on rats-tls, +so you need to confirm that [rats-tls](https://github.com/inclavare-containers/rats-tls) has been correctly installed in your running environment. + +3. Agent Configuration + +Add configuration `aa_kbc_params= 'eaa_kbc::<$IP>:<$PORT>'` to agent config file, the IP and PORT should be consistent with verdictd. diff --git a/guides/sev-guide.md b/guides/sev-guide.md new file mode 100644 index 0000000..110322d --- /dev/null +++ b/guides/sev-guide.md @@ -0,0 +1,548 @@ +# SEV Guide + +## Creating a CoCo workload using a pre-existing encrypted image on SEV + +#### Platform Setup + +To enable SEV on the host platform, first ensure that it is supported. Then follow these instructions to enable SEV: + +[AMD SEV - Prepare Host OS](https://github.com/AMDESE/AMDSEV#prepare-host-os) + +#### Install sevctl and Export SEV Certificate Chain + +[sevctl](https://github.com/virtee/sevctl) is the SEV command line utility and is needed to export the SEV certificate chain. + +Follow these steps to install `sevctl`: + +* Debian / Ubuntu: + + ``` + # Rust must be installed to build + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + source $HOME/.cargo/env + sudo apt install -y musl-dev musl-tools + + # Additional packages are required to build + sudo apt install -y pkg-config libssl-dev + + # Clone the repository + git clone https://github.com/virtee/sevctl.git + + # Build + (cd sevctl && cargo build) + ``` + +* CentOS / Fedora / RHEL: + + ``` + sudo dnf install sevctl + ``` + +> **Note** Due to [this bug](https://bugzilla.redhat.com/show_bug.cgi?id=2037963) on sevctl for RHEL and Fedora you might need to build the tool from sources to pick the fix up. + +If using the SEV kata configuration template file, the SEV certificate chain must be placed in `/opt/sev`. Export the SEV certificate chain using the following commands: + +``` +sudo mkdir -p /opt/sev +sudo ./sevctl/target/debug/sevctl export --full /opt/sev/cert_chain.cert +``` + +#### Setup and Run the simple-kbs + +The [simple-kbs](https://github.com/confidential-containers/simple-kbs) is a basic key broker service that hosts secret storage and provides secret release policies configurable by container workload creators or users. + +The `simple-kbs` is a prototype implementation under development and is not intended for production use at this time. + +For the SEV encrypted image use case, it is required to host the key used to encrypt the container image from the `simple-kbs`. + +The CoCo project has created a sample encrypted container image ([encrypted-image-tests](ghcr.io/fitzthum/encrypted-image-tests:encrypted)). This image is encrypted using a key that comes already provisioned inside the `simple-kbs` for ease of testing. No `simple-kbs` policy is required to get things running. + +The image encryption key and key for SSH access have been attached to the CoCo sample encrypted container image as docker labels. This image is meant for TEST purposes only as these keys are published publicly. In a production use case, these keys would be generated by the workload administrator and kept secret. For further details, see the section how to [Create an Encrypted Image](#create-an-encrypted-image). + +To learn more about creating custom policies, see the section on [Creating a simple-kbs Policy to Verify the SEV Firmware Measurement](#creating-a-simple-kbs-policy-to-verify-the-sev-firmware-measurement). + +A KBS is not required to run unencrypted containers. +Instead, disable pre-attestation by editing the Kata config file located at `/opt/confidential-containers/share/defaults/kata-containers/configuration-qemu-sev.toml`. +``` +guest_pre_attestation = false +``` +Image decryption and signature validation will not work if pre-attestation is disabled. + +> **Note** It is not recommended to edit the Kata configuration file manually. +These changes might be overwritten by the operator. + +If you are using attestation, you will need to update the above Kata configuration file to point +to the URI of the KBS. + +For example, set +`guest_pre_attestation_proxy = ":44444"` + +You will also need to update the Kata configuration to add an extra kernel parameter specifying KBS information. +For example, add `agent.aa_kbc_params=online_sev_kbc:::44444` +to the `kernel_params` field in the configuration file. + +The KBS IP must be accesible from inside the guest. Port 44444 is the default port per the directions below, but it can be configured. + +`docker-compose` is required to run the `simple-kbs` and its database in docker containers: + +* Debian / Ubuntu: + + ``` + sudo apt install docker-compose + ``` + +* CentOS / Fedora / RHEL: + + ``` + sudo dnf install docker-compose-plugin + ``` + +Clone the repository for specified tag: +``` +simple_kbs_tag="0.1.1" +git clone https://github.com/confidential-containers/simple-kbs.git +(cd simple-kbs && git checkout -b "branch_${simple_kbs_tag}" "${simple_kbs_tag}") +``` + +Run the service with `docker-compose`: + +* Debian / Ubuntu: + + ``` + (cd simple-kbs && sudo docker-compose up -d) + ``` + +* CentOS / Fedora / RHEL: + + ``` + (cd simple-kbs && sudo docker compose up -d) + ``` + +#### Launch the Pod and Verify SEV Encryption + +Here is a sample kubernetes service yaml for an encrypted image: + +``` +kind: Service +apiVersion: v1 +metadata: + name: encrypted-image-tests +spec: + selector: + app: encrypted-image-tests + ports: + - port: 22 +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: encrypted-image-tests +spec: + selector: + matchLabels: + app: encrypted-image-tests + template: + metadata: + labels: + app: encrypted-image-tests + spec: + runtimeClassName: kata-qemu-sev + containers: + - name: encrypted-image-tests + image: ghcr.io/fitzthum/encrypted-image-tests:encrypted + imagePullPolicy: Always +``` + +Save this service yaml to a file named `encrypted-image-tests.yaml`. Notice the image URL specified points to the previously described CoCo sample encrypted container image. `kata-qemu-sev` must also be specified as the `runtimeClassName`. + +Start the service: + +``` +kubectl apply -f encrypted-image-tests.yaml +``` + +Check for pod errors: + +``` +pod_name=$(kubectl get pod -o wide | grep encrypted-image-tests | awk '{print $1;}') +kubectl describe pod ${pod_name} +``` + +If there are no errors, a CoCo encrypted container with SEV has been successfully launched! + +#### Verify SEV Memory Encryption + +The container `dmesg` report can be parsed to verify SEV memory encryption. + +Get pod IP: + +``` +pod_ip=$(kubectl get pod -o wide | grep encrypted-image-tests | awk '{print $6;}') +``` + +Get the CoCo sample encrypted container image SSH access key from docker image label and save it to a file. +Currently the docker client cannot pull encrypted images. We can inspect the unencrypted image instead, +which has the same labels. You could also use `skopeo inspect` to get the labels from the encrypted image. + +``` +docker pull ghcr.io/fitzthum/encrypted-image-tests:unencrypted +docker inspect ghcr.io/fitzthum/encrypted-image-tests:unencrypted | \ + jq -r '.[0].Config.Labels.ssh_key' \ + | sed "s|\(-----BEGIN OPENSSH PRIVATE KEY-----\)|\1\n|g" \ + | sed "s|\(-----END OPENSSH PRIVATE KEY-----\)|\n\1|g" \ + > encrypted-image-tests +``` + +Set permissions on the SSH private key file: + +``` +chmod 600 encrypted-image-tests +``` + +Run a SSH command to parse the container `dmesg` output for SEV enabled messages: + +``` +ssh -i encrypted-image-tests \ + -o "StrictHostKeyChecking no" \ + -t root@${pod_ip} \ + 'dmesg | grep SEV' +``` + +The output should look something like this: +``` +[ 0.150045] Memory Encryption Features active: AMD SEV +``` + +## Create an Encrypted Image + +If SSH access to the container is desired, create a keypair: + +``` +ssh-keygen -t ed25519 -f encrypted-image-tests -P "" -C "" <<< y +``` + +The above command will save the keypair in a file named `encrypted-image-tests`. + +Here is a sample Dockerfile to create a docker image: + +``` +FROM alpine:3.16 + +# Update and install openssh-server +RUN apk update && apk upgrade && apk add openssh-server + +# Generate container ssh key +RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -P "" + +# A password needs to be set for login to work. An empty password is +# unproblematic as password-based login to root is not allowed. +RUN passwd -d root + +# Copy the remote generated public key to the container authorized_keys +# Generate with 'ssh-keygen -t ed25519 -f encrypted-image-tests -P "" -C ""' +COPY encrypted-image-tests.pub /root/.ssh/authorized_keys + +# Entry point - run sshd +ENTRYPOINT /usr/sbin/sshd -D +``` + +Store this `Dockerfile` in the same directory as the `encrypted-image-tests` ssh keypair. + +Build image: + +``` +docker build -t encrypted-image-tests . +``` + +Tag and upload this unencrypted docker image to a registry: + +``` +docker tag encrypted-image-tests:latest [REGISTRY_URL]:unencrypted +docker push [REGISTRY_URL]:unencrypted +``` + +Be sure to replace `[REGISTRY_URL]` with the desired registry URL. + +[skopeo](https://github.com/containers/skopeo) is required to encrypt the container image. Follow the instructions here to install `skopeo`: + +[skopeo Installation](https://github.com/containers/skopeo/blob/main/install.md) + +The Attestation Agent hosts a grpc service to support encrypting the image. Clone the repository: + +``` +attestation_agent_tag="v0.1.0" +git clone https://github.com/confidential-containers/attestation-agent.git +(cd simple-kbs && git checkout -b "branch_${attestation_agent_tag}" "${attestation_agent_tag}") +``` + +Run the offline_fs_kbs: + +``` +(cd attestation-agent/sample_keyprovider/src/enc_mods/offline_fs_kbs \ +&& cargo run --release --features offline_fs_kbs -- --keyprovider_sock 127.0.0.1:50001 &) +``` + +Create the Attestation Agent keyprovider: + +``` +cat > attestation-agent/sample_keyprovider/src/enc_mods/offline_fs_kbs/ocicrypt.conf < keys.json <:44444"` - -You will also need to update the Kata configuration to add an extra kernel parameter specifying KBS information. -For example, add `agent.aa_kbc_params=online_sev_kbc:::44444` -to the `kernel_params` field in the configuration file. - -The KBS IP must be accesible from inside the guest. Port 44444 is the default port per the directions below, but it can be configured. - -`docker-compose` is required to run the `simple-kbs` and its database in docker containers: - -* Debian / Ubuntu: - - ``` - sudo apt install docker-compose - ``` - -* CentOS / Fedora / RHEL: - - ``` - sudo dnf install docker-compose-plugin - ``` - -Clone the repository for specified tag: -``` -simple_kbs_tag="0.1.1" -git clone https://github.com/confidential-containers/simple-kbs.git -(cd simple-kbs && git checkout -b "branch_${simple_kbs_tag}" "${simple_kbs_tag}") -``` - -Run the service with `docker-compose`: - -* Debian / Ubuntu: - - ``` - (cd simple-kbs && sudo docker-compose up -d) - ``` - -* CentOS / Fedora / RHEL: - - ``` - (cd simple-kbs && sudo docker compose up -d) - ``` - -#### Launch the Pod and Verify SEV Encryption - -Here is a sample kubernetes service yaml for an encrypted image: - -``` -kind: Service -apiVersion: v1 -metadata: - name: encrypted-image-tests -spec: - selector: - app: encrypted-image-tests - ports: - - port: 22 ---- -kind: Deployment -apiVersion: apps/v1 -metadata: - name: encrypted-image-tests -spec: - selector: - matchLabels: - app: encrypted-image-tests - template: - metadata: - labels: - app: encrypted-image-tests - spec: - runtimeClassName: kata-qemu-sev - containers: - - name: encrypted-image-tests - image: ghcr.io/fitzthum/encrypted-image-tests:encrypted - imagePullPolicy: Always -``` - -Save this service yaml to a file named `encrypted-image-tests.yaml`. Notice the image URL specified points to the previously described CoCo sample encrypted container image. `kata-qemu-sev` must also be specified as the `runtimeClassName`. - -Start the service: - -``` -kubectl apply -f encrypted-image-tests.yaml -``` - -Check for pod errors: - -``` -pod_name=$(kubectl get pod -o wide | grep encrypted-image-tests | awk '{print $1;}') -kubectl describe pod ${pod_name} -``` - -If there are no errors, a CoCo encrypted container with SEV has been successfully launched! - -#### Verify SEV Memory Encryption - -The container `dmesg` report can be parsed to verify SEV memory encryption. - -Get pod IP: - -``` -pod_ip=$(kubectl get pod -o wide | grep encrypted-image-tests | awk '{print $6;}') -``` - -Get the CoCo sample encrypted container image SSH access key from docker image label and save it to a file. -Currently the docker client cannot pull encrypted images. We can inspect the unencrypted image instead, -which has the same labels. You could also use `skopeo inspect` to get the labels from the encrypted image. - -``` -docker pull ghcr.io/fitzthum/encrypted-image-tests:unencrypted -docker inspect ghcr.io/fitzthum/encrypted-image-tests:unencrypted | \ - jq -r '.[0].Config.Labels.ssh_key' \ - | sed "s|\(-----BEGIN OPENSSH PRIVATE KEY-----\)|\1\n|g" \ - | sed "s|\(-----END OPENSSH PRIVATE KEY-----\)|\n\1|g" \ - > encrypted-image-tests -``` - -Set permissions on the SSH private key file: - -``` -chmod 600 encrypted-image-tests -``` - -Run a SSH command to parse the container `dmesg` output for SEV enabled messages: - -``` -ssh -i encrypted-image-tests \ - -o "StrictHostKeyChecking no" \ - -t root@${pod_ip} \ - 'dmesg | grep SEV' -``` - -The output should look something like this: -``` -[ 0.150045] Memory Encryption Features active: AMD SEV -``` - -## Building a new encrypted container image and deploying it as a CoCo workload - -### Use EAA KBC and Verdictd (TDX) - -EAA is used to perform attestation at runtime and provide guest with confidential resources such as keys. -It is based on [rats-tls](https://github.com/inclavare-containers/rats-tls). - -[Verdictd](https://github.com/inclavare-containers/verdictd) is the Key Broker Service and Attestation Service of EAA. -The EAA KBC is an optional module in the attestation-agent at compile time, -which can be used to communicate with Verdictd. -The communication is established on the encrypted channel provided by rats-tls. - -EAA can now be used on intel TDX and intel SGX platforms. - -#### Create encrypted image - -Before build encrypted image, you need to make sure Skopeo and Verdictd(EAA KBS) have been installed: -- [Skopeo](https://github.com/containers/skopeo): the command line utility to perform encryption operations. -- [Verdictd](https://github.com/inclavare-containers/verdictd): EAA Key Broker Service and Attestation Service. - -1. Pull unencrypted image. - -Here use `alpine:latest` for example: - -```sh -${SKOPEO_HOME}/bin/skopeo copy --insecure-policy docker://docker.io/library/alpine:latest oci:busybox -``` - -2. Follow the [Verdictd README #Generate encrypted container image](https://github.com/inclavare-containers/verdictd#generate-encrypted-container-image) to encrypt the image. - -3. Publish the encrypted image to your registry. - -#### Deploy encrypted image - -1. Build rootfs with EAA component: - -Specify `AA_KBC=eaa_kbc` parameters when using kata-containers `rootfs.sh` scripts to create rootfs. - -2. Launch Verdictd - -Verdictd performs remote attestation at runtime and provides the key needed to decrypt the image. -It is actually both Key Broker Service and Attestation Service of EAA. -So when deploy the encrypted image, Verdictd is needed to be launched: - -```sh -verdictd --listen <$ip>:<$port> --mutual -``` - -> **Note** The communication between Verdictd and EAA KBC is based on rats-tls, -so you need to confirm that [rats-tls](https://github.com/inclavare-containers/rats-tls) has been correctly installed in your running environment. - -3. Agent Configuration - -Add configuration `aa_kbc_params= 'eaa_kbc::<$IP>:<$PORT>'` to agent config file, the IP and PORT should be consistent with verdictd. - -### Use offline SEV KBC and simple-kbs (SEV) - -#### Create an Encrypted Image - -If SSH access to the container is desired, create a keypair: - -``` -ssh-keygen -t ed25519 -f encrypted-image-tests -P "" -C "" <<< y -``` - -The above command will save the keypair in a file named `encrypted-image-tests`. - -Here is a sample Dockerfile to create a docker image: - -``` -FROM alpine:3.16 - -# Update and install openssh-server -RUN apk update && apk upgrade && apk add openssh-server - -# Generate container ssh key -RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -P "" - -# A password needs to be set for login to work. An empty password is -# unproblematic as password-based login to root is not allowed. -RUN passwd -d root - -# Copy the remote generated public key to the container authorized_keys -# Generate with 'ssh-keygen -t ed25519 -f encrypted-image-tests -P "" -C ""' -COPY encrypted-image-tests.pub /root/.ssh/authorized_keys - -# Entry point - run sshd -ENTRYPOINT /usr/sbin/sshd -D -``` - -Store this `Dockerfile` in the same directory as the `encrypted-image-tests` ssh keypair. - -Build image: - -``` -docker build -t encrypted-image-tests . -``` - -Tag and upload this unencrypted docker image to a registry: - -``` -docker tag encrypted-image-tests:latest [REGISTRY_URL]:unencrypted -docker push [REGISTRY_URL]:unencrypted -``` - -Be sure to replace `[REGISTRY_URL]` with the desired registry URL. - -[skopeo](https://github.com/containers/skopeo) is required to encrypt the container image. Follow the instructions here to install `skopeo`: - -[skopeo Installation](https://github.com/containers/skopeo/blob/main/install.md) - -The Attestation Agent hosts a grpc service to support encrypting the image. Clone the repository: - -``` -attestation_agent_tag="v0.1.0" -git clone https://github.com/confidential-containers/attestation-agent.git -(cd simple-kbs && git checkout -b "branch_${attestation_agent_tag}" "${attestation_agent_tag}") -``` - -Run the offline_fs_kbs: - -``` -(cd attestation-agent/sample_keyprovider/src/enc_mods/offline_fs_kbs \ -&& cargo run --release --features offline_fs_kbs -- --keyprovider_sock 127.0.0.1:50001 &) -``` - -Create the Attestation Agent keyprovider: - -``` -cat > attestation-agent/sample_keyprovider/src/enc_mods/offline_fs_kbs/ocicrypt.conf < keys.json <