From b238d5a8a95fd8fc612df5f9b1c72fac142620ba Mon Sep 17 00:00:00 2001 From: Tuomo Tanskanen Date: Wed, 11 Dec 2024 15:12:18 +0200 Subject: [PATCH] add keylime poc, part 2 Use existing docker compose as mockup of keylime services existing outside k8s cluster, but the agents need to be in k8s and accessible only via LoadBalancer IP / Ingress rules. Signed-off-by: Tuomo Tanskanen --- security/keylime-poc/Makefile | 28 +++ security/keylime-poc/README.md | 7 + security/keylime-poc/k8s/README.md | 217 ++++++++++++++++++ security/keylime-poc/k8s/clean.sh | 43 ++++ security/keylime-poc/k8s/config.sh | 36 +++ security/keylime-poc/k8s/keylime-agent.yaml | 169 ++++++++++++++ security/keylime-poc/k8s/run_docker.sh | 35 +++ security/keylime-poc/k8s/run_kind.sh | 44 ++++ security/keylime-poc/k8s/run_tenant.sh | 24 ++ .../scripts/enable_ima_measurement.sh | 41 ++++ security/keylime-poc/scripts/gen_allowlist.sh | 47 ++++ 11 files changed, 691 insertions(+) create mode 100644 security/keylime-poc/Makefile create mode 100644 security/keylime-poc/k8s/README.md create mode 100755 security/keylime-poc/k8s/clean.sh create mode 100644 security/keylime-poc/k8s/config.sh create mode 100644 security/keylime-poc/k8s/keylime-agent.yaml create mode 100755 security/keylime-poc/k8s/run_docker.sh create mode 100755 security/keylime-poc/k8s/run_kind.sh create mode 100755 security/keylime-poc/k8s/run_tenant.sh create mode 100755 security/keylime-poc/scripts/enable_ima_measurement.sh create mode 100755 security/keylime-poc/scripts/gen_allowlist.sh diff --git a/security/keylime-poc/Makefile b/security/keylime-poc/Makefile new file mode 100644 index 00000000..0fe14743 --- /dev/null +++ b/security/keylime-poc/Makefile @@ -0,0 +1,28 @@ +# simple makefile to make life easy + +.PHONY: e2e run docker kind verify clean realclean +.PHONY: compose + +e2e: run verify + "e2e done!" + +run: docker kind + echo "Done!" + +docker: + cd k8s; ./run_docker.sh + +kind: + cd k8s; ./run_kind.sh + +verify: + #cd k8s; ./verify.sh + +clean: + cd k8s; ./clean.sh + +realclean: + cd k8s; ./clean.sh realclean + +compose: + sudo apt install -y docker-compose-plugin diff --git a/security/keylime-poc/README.md b/security/keylime-poc/README.md index 7b05bda2..d602c48e 100644 --- a/security/keylime-poc/README.md +++ b/security/keylime-poc/README.md @@ -6,3 +6,10 @@ First part of POC is deploying Keylime services in [Docker Compose](compose/README.md). Setup is verified by a single Agent, backed by software TPM, also in Docker. + +## Kubernetes + +Second part of POC is deploying [Agent in k8s](k8s/README.md), fronted by +Ingress/LoadBalancer, while the Verifier and Registrar sit in Docker Compose. +This simulates the use-case of using existing non-K8s Keylime installation to +measure nodes in K8s cluster. diff --git a/security/keylime-poc/k8s/README.md b/security/keylime-poc/k8s/README.md new file mode 100644 index 00000000..6fa57999 --- /dev/null +++ b/security/keylime-poc/k8s/README.md @@ -0,0 +1,217 @@ +# Keylime POC + + +WIP: NOTHING IS EXPECTED WORK HERE YET! + +## Kubernetes + +Make a Proof of Concept of Keylime in k8s. + +This POC is needed as the concept of having Keylime Tenant/Verifier/Registrar +outside K8s cluster, but Keylime Agent in K8s cluster and being accessed via +Ingress/LoadBalancer IP, is something Keylime maintainers did not think +originally as a use-case. This has several issues with the current design, and +while there is a proposal/ study for changing from "pull model" to "push +model", it is miles away and this POC tries to find out the minimal changes +needed to make the current model work for this use case. + +## POC requirements + +Since Keylime is about using TPM and being secure, we have some requirements: + +1. A machine/VM where we can setup a K8s cluster, and the pods can have access + to TPM. +1. We need the TPM public certificates for said machine, EK CA etc. +1. Machine where we can run Keylime services/commands, Registrar, Verifier and + Tenant. Preferably a second machine, so we can't "cheat". +1. There needs to be connectivity between these. Preferably different networks, + again we don't want to "cheat". +1. Agents have unique UUID that are pre-set, generated or tied to TPM EK. + There should be more than one machine in Cluster, so we have multiple Agents. + +For test/reproducibility purposes, we must consider some shortcuts: + +1. Use of single laptop, where the separation is happening either via + - VM (does it expose TPM properly) + - Containers (eventually all services, directly on Docker or in K8s cluster + will run in the same container runtime) +1. Using TPM simulation software (might be good for reproducibility due + different manufacturers having different certs etc) +1. Using only one machine in K8s cluster, and hence only one Agent (this may + lead of incorrect configs as there is only one Agent as is always "correct" + target) + +We have some availability for infra: + +1. Xerces (OpenStack) does not expose TPM to the VMs, so it is ruled out +1. BML (Bare Metal Lab) has real machines that certainly would work, but those + are not for development (jump hosts) or run test payloads (actual servers). + Also access to those is not readily available to persons outside the ESJ + team. + +## POC setup + +As we're talking about POC, it is good to start with MVP, which here is: + +1. Use laptop as hardware for TPM access +1. Use containers to make it reproducible +1. Make all hardware related things configurable (EK certs, networks, ...) + +This leads to test setup looking like this. + +### Registrar in Docker + +1. Make Docker networking such it can be accessed by the K8s services (use + host network if needed) +1. Run Keylime Registrar image in local Docker +1. Run Keylime Verifier image in local Docker +1. Run Keylime Tenant CLI in local Docker + +### Agent in K8s + +1. Run K8s cluster with Kind +1. Install Keylime Agent in Kind +1. Expose the Agent with LoadBalancer IP (if Kind supports that?) +1. Make Ingress rule for a fake hostname (uuid0-31.uuid32-64.cluster.local) + +## POC plan + +With POC setup in place, we aim to achieve following steps. + +1. Agent registration to Registrar must work. + + - Connectivity from Agent -> Registrar + - Agent must be configured with valid data (for later stages) + - `contact_ip` + - ... + - See Keylime Rust Agent + [contact_ip issue](https://github.com/keylime/rust-keylime/issues/848) + +1. Tenant will add Agent to Verifier with data from Registrar/command line. + + - With use of Tenant CLI command, we add Agent to Verifier to be polled + - Verifier will query Registrar about Agent details, when it is supplied + with Agent UUID. This needs Tenant -> Verifier -> Registrar connectivity + and configuration to work. + +1. Verifier will query Agent for data + + - Verifier now has all needed data to poll Agent. This is the tricky part as + it will use data input by Agent to Registrar, but needs to also travel + through LoadBalancer IP and Ingress rules to the correct Agent. Data must + only go to the Agent with matching UUID. + - NOTE: In the POC setup we have only one Agent, leading to the risk of + sending all Agent queries to this single Agent, allowing "cheating" in + K8s configurations as the sole Agent is the only target and UUID based rules + might "cheat". + +1. Agent sends data back + + - Agent gets data from TPM and sends it to Verifier. + - Agent EK certs and Verifier EK certs need to match at this point. + +1. ... + +1. Profit! + + There might be some additional steps, but this is how far we've come right now. + Stay tuned! + +## POC steps + +Actual steps to take to achieve [POC plan](#poc-plan). For this, a +[Makefile](./makefile) and [helper scripts](./scripts/) are implemented in this +repository. + +1. `make e2e` to run e2e, ie. `run` + `verify` +1. `make run` to just setup everything, ie. `docker` + `kind` +1. `make docker` to setup Verifier/Registrar correctly +1. `make kind` to setup Agent in K8s cluster +1. `make verify` to have Tenant sign up the Agent and trigger the verification +1. `make clean` to clean everything up +1. `make realclean` to clean everything up + remove any temporary files + images + +Whole POC e2e can be executed with `make e2e` and cleaned away with +`make realclean`. + +For anything else, use `docker` and `kubectl` commands for digging into details, +and when everything is running, use [scripts/run_tenant.sh](./scripts/run_tenant.sh) +to issue Tenant commands. + +### Verifier and Registrar installation + +Running `make docker` sets up Verifier first, which generates certificates for +mTLS in the shared directory `/tmp/keylime/cv_ca`, which needs to be mounted as +`/var/lib/keylime/cv_ca` in all containers. + +See [scripts/run_docker.sh](./scripts/run_docker.sh) for the code. + +### Agent installation + +Running `make kind` sets up Kind cluster, then applies K8s manifests from `k8s` +subdirectory to run Keylime Agent as DaemonSet. + +For nitty gritty details of the K8s installation of the agent, see +[manifest generation details](#manifest-generation). + +See [scripts/run_kind.sh](./scripts/run_kind.sh) for the code. + +#### Manifest generation + +This K8s installation is created based on the +[attestation-operator](https://github.com/keylime/attestation-operator) templates +via following process (no need to repeat, resulting files are stored in this +POC): + +1. Clone attestation-operator repo +1. Run `make helm-keylime` +1. Run `kind create cluster` to have something to deploy into +1. Run `make helm-keylime-deploy` run deploy all components from the Helm chart +1. Run `kubectl -n keylime get daemonset hhkl-keylime-agent -o yaml` to get a + manifest for Agent. +1. Add some adaptation, especially around mTLS and cert mounts. Certs generated + by the Docker container must be made secrets etc + +### Verification with Tenant + +tbd + +## Issues found during POC + +1. [Agent contact_ip issue](https://github.com/keylime/rust-keylime/issues/848) + +## POC shortcomings + +As mentioned in [POC requirements](#poc-requirements) section, this POC for +sake of simplicity has its limits. Following items could be implemented for +more completeness, if time is not an issue. + +1. Two or mode nodes +1. Two or more machines +1. Adding TPM simulation (or removal of it) +1. tbc + +## Extras + +Some extra more or less useful notes related to this POC. + +### Ubuntu 24.04 tools + +Per [Keylime documentation on TPM2 tools](https://keylime-docs.readthedocs.io/en/latest/installation.html#tpm-2-0-support) +we need to install some tools manually. + +- `tpm2-tools` and `tpm2-tss-engine-tools` need to be installed (at least for + convenience) + - `sudo apt install tpm2-tools tpm2-tss-engine-tools` + +## References + +Collection of referenced docs, issues etc. + +1. [Keylime documentation](https://keylime-docs.readthedocs.io/en/latest/) +1. [Attestation Operator](https://github.com/keylime/attestation-operator) + aka Keylime in K8s +1. [Push model proxy doc](https://github.com/keylime/attestation-operator/blob/main/docs/push-model-proxy.md) +1. [Agent contact_ip issue](https://github.com/keylime/rust-keylime/issues/848) +1. [Slack discussion](https://cloud-native.slack.com/archives/C01ARE2QUTZ/p1727792733885549) +1. [RedHat's Keylime docs](https://docs.redhat.com/de/documentation/red_hat_enterprise_linux/9/html/security_hardening/assembly_ensuring-system-integrity-with-keylime_security-hardening#configuring-keylime-agent_assembly_ensuring-system-integrity-with-keylime) diff --git a/security/keylime-poc/k8s/clean.sh b/security/keylime-poc/k8s/clean.sh new file mode 100755 index 00000000..ee5acc06 --- /dev/null +++ b/security/keylime-poc/k8s/clean.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1091 + +# a clean up script for everything we've done + +set -eu + +# shall we do deep clean or not +REALCLEAN="${1:-}" + +. config.sh + +remove_docker_instances() +{ + docker rm -f "${KEYLIME_VERIFIER_NAME}" || true + docker rm -f "${KEYLIME_REGISTRAR_NAME}" || true +} + +remove_kind_cluster() +{ + kind delete cluster --name="${KIND_NAME}" || true +} + +remove_temporary_files() +{ + sudo rm -rf "${KEYLIME_TMP_DIR:?}" +} + +remove_docker_images() +{ + for image in "${KEYLIME_IMAGES[@]}"; do + docker image rm -f "${image}" + done +} + +# main +remove_docker_instances +remove_kind_cluster +remove_temporary_files + +if [[ -n "${REALCLEAN}" ]]; then + remove_docker_images +fi diff --git a/security/keylime-poc/k8s/config.sh b/security/keylime-poc/k8s/config.sh new file mode 100644 index 00000000..a471eca7 --- /dev/null +++ b/security/keylime-poc/k8s/config.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2034 + +# This holds the shared configuration options for Keylime scripts + +# container runtime +CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-docker}" + +# registry and image details +REGISTRY=quay.io/keylime +TAG=latest + +KEYLIME_TENANT_IMAGE="${REGISTRY}/keylime_tenant:${TAG}" +KEYLIME_REGISTRAR_IMAGE="${REGISTRY}/keylime_registrar:${TAG}" +KEYLIME_VERIFIER_IMAGE="${REGISTRY}/keylime_verifier:${TAG}" +KEYLIME_AGENT_IMAGE="${REGISTRY}/keylime_agent:${TAG}" + +declare -a KEYLIME_IMAGES=( + "${KEYLIME_TENANT_IMAGE}" + "${KEYLIME_REGISTRAR_IMAGE}" + "${KEYLIME_VERIFIER_IMAGE}" + "${KEYLIME_AGENT_IMAGE}" +) + +# docker instance names +KEYLIME_VERIFIER_NAME="keylime-verifier" +KEYLIME_REGISTRAR_NAME="keylime-registrar" +KEYLIME_TENANT_NAME="keylime-tenant" + +# shared directory name +KEYLIME_TMP_DIR="/tmp/keylime" +KEYLIME_INTERNAL_TLS_DIR="/var/lib/keylime/cv_ca" +KEYLIME_EXTERNAL_TLS_DIR="${KEYLIME_TMP_DIR}/cv_ca" + +# kind setup +KIND_NAME="keylime" diff --git a/security/keylime-poc/k8s/keylime-agent.yaml b/security/keylime-poc/k8s/keylime-agent.yaml new file mode 100644 index 00000000..309f3f47 --- /dev/null +++ b/security/keylime-poc/k8s/keylime-agent.yaml @@ -0,0 +1,169 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + annotations: + deprecated.daemonset.template.generation: "1" + meta.helm.sh/release-name: hhkl + meta.helm.sh/release-namespace: keylime + creationTimestamp: "2024-10-24T11:42:03Z" + generation: 1 + labels: + app.kubernetes.io/instance: hhkl + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: keylime-agent + app.kubernetes.io/version: latest + helm.sh/chart: keylime-agent-0.1.0 + name: hhkl-keylime-agent + namespace: keylime + resourceVersion: "3324" + uid: b271fc2c-af4d-4626-a981-2bda2bcf7fb2 +spec: + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/instance: hhkl + app.kubernetes.io/name: keylime-agent + template: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: hhkl + app.kubernetes.io/name: keylime-agent + spec: + containers: + - command: + - /bin/keylime_agent + env: + - name: KEYLIME_AGENT_CONTACT_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: KEYLIME_AGENT_SERVER_KEY + value: /etc/keylime/agent/server/certs/server-private.pem + - name: KEYLIME_AGENT_SERVER_CERT + value: /etc/keylime/agent/server/certs/server-cert.crt + - name: KEYLIME_AGENT_RUN_AS + - name: KEYLIME_AGENT_AGENT_DATA_PATH + value: /var/lib/keylime-persistent/agent_data.json + - name: RUST_LOG + value: keylime_agent=info + envFrom: + - configMapRef: + name: hhkl-keylime-config + image: quay.io/keylime/keylime_agent:latest + imagePullPolicy: IfNotPresent + name: keylime-agent + ports: + - containerPort: 9002 + name: agent + protocol: TCP + resources: {} + securityContext: + privileged: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/keylime/agent/server/certs + name: certs + readOnly: true + - mountPath: /var/lib/keylime/cv_ca/ + name: cvca-certs + readOnly: true + - mountPath: /var/lib/keylime-persistent + name: persistent + - mountPath: /var/lib/keylime/secure + name: secure + readOnly: true + - mountPath: /tmp + name: tmpfs + - mountPath: /sys/kernel/security + name: securityfs + readOnly: true + dnsPolicy: ClusterFirst + initContainers: + - command: + - /bin/bash + - -c + - | + # fail if any of the commands fail + set -e + + # copy the CA directory where we'll generate the certs from + cp -Rv /keylime/cv_ca /tmp/ + cd /tmp/cv_ca + + # now generate a new cert for the agent + # we need to do this on every start as the pod IP changes which is being used as the connection address + keylime_ca -d /tmp/cv_ca --command create --name "$POD_IP" + + # copy them to the expected destinations + cp -v /tmp/cv_ca/${POD_IP}-private.pem /certs/server-private.pem + cp -v /tmp/cv_ca/${POD_IP}-cert.crt /certs/server-cert.crt + env: + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + envFrom: + - configMapRef: + name: hhkl-keylime-config + - secretRef: + name: hhkl-keylime-ca-password + image: quay.io/keylime/keylime_tenant:latest + imagePullPolicy: IfNotPresent + name: keylime-agent-init + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + - mountPath: /keylime/cv_ca/ + name: cvca-certs + readOnly: true + - mountPath: /tmp + name: tmpfs + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: hhkl-keylime-agent + serviceAccountName: hhkl-keylime-agent + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /sys/kernel/security + type: Directory + name: securityfs + - hostPath: + path: /var/lib/keylime + type: DirectoryOrCreate + name: persistent + - emptyDir: + medium: Memory + sizeLimit: 10Mi + name: secure + - emptyDir: + medium: Memory + sizeLimit: 10Mi + name: certs + - name: cvca-certs + secret: + defaultMode: 420 + secretName: hhkl-keylime-certs + - emptyDir: {} + name: tmpfs + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate +status: + currentNumberScheduled: 1 + desiredNumberScheduled: 1 + numberMisscheduled: 0 + numberReady: 0 + numberUnavailable: 1 + observedGeneration: 1 + updatedNumberScheduled: 1 diff --git a/security/keylime-poc/k8s/run_docker.sh b/security/keylime-poc/k8s/run_docker.sh new file mode 100755 index 00000000..3d569e94 --- /dev/null +++ b/security/keylime-poc/k8s/run_docker.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1091 + +# This script runs Keylime Verifier and Registrar as Docker containers. +# It is complimented by the "run_tenant.sh" that runs Keylime Tenant in +# container, sharing the config witht this script. + +set -eux + +. config.sh + +run_verifier() +{ + # we need to supply cv_ca directory for sharing mtls certs + docker run \ + -d \ + -v "${KEYLIME_EXTERNAL_TLS_DIR}":"${KEYLIME_INTERNAL_TLS_DIR}":rw \ + --name "${KEYLIME_VERIFIER_NAME}" \ + "${KEYLIME_VERIFIER_IMAGE}" +} + +run_registrar() +{ + # we need to supply cv_ca directory for sharing mtls certs + docker run \ + -d \ + -v "${KEYLIME_EXTERNAL_TLS_DIR}":"${KEYLIME_INTERNAL_TLS_DIR}":rw \ + --name "${KEYLIME_REGISTRAR_NAME}" \ + "${KEYLIME_REGISTRAR_IMAGE}" +} + + +# main +run_verifier +run_registrar diff --git a/security/keylime-poc/k8s/run_kind.sh b/security/keylime-poc/k8s/run_kind.sh new file mode 100755 index 00000000..a28328be --- /dev/null +++ b/security/keylime-poc/k8s/run_kind.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1091 + +# This script runs Kind cluster and sets up Keylime Agent in the cluster. +# Keylime Agent runs as DaemonSet, and is then fronted by LoadBalancer +# service and Ingress rules. +# +# In first step, we run it without Ingress. It should be noted that this +# cheats in multiple ways: +# +# 1. It uses an IP address (not hostname) +# 2. It avoids Ingress rules for UUID based call routing + +set -eux + +. config.sh + +check_tools() +{ + declare -a tools=( + kind + kubectl + ) + + for tool in "${tools[@]}"; do + command -v "${tool}" &>/dev/null || { echo "error: ${tool} is not in PATH"; exit 1; } + done +} + +launch_kind_cluster() +{ + kind create cluster --name="${KIND_NAME}" +} + +run_agent() +{ + echo TBD +} + + +# main +check_tools +launch_kind_cluster +run_agent diff --git a/security/keylime-poc/k8s/run_tenant.sh b/security/keylime-poc/k8s/run_tenant.sh new file mode 100755 index 00000000..d4ddaff8 --- /dev/null +++ b/security/keylime-poc/k8s/run_tenant.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1091 + +# This script run Keylime Tenant in Docker container, allowing non-intrusive +# way of executing the Tenant CLI commands while sharing the configuration +# with the other Keylime components. + +set -eux + +. config.sh + +run_tenant() +{ + # we need to supply cv_ca directory for sharing mtls certs + docker run -it --rm \ + -v "${KEYLIME_EXTERNAL_TLS_DIR}":"${KEYLIME_INTERNAL_TLS_DIR}":rw \ + --name "${KEYLIME_TENANT_NAME}" \ + "${KEYLIME_TENANT_IMAGE}" \ + "$@" +} + + +# main +run_tenant "$@" diff --git a/security/keylime-poc/scripts/enable_ima_measurement.sh b/security/keylime-poc/scripts/enable_ima_measurement.sh new file mode 100755 index 00000000..845bee86 --- /dev/null +++ b/security/keylime-poc/scripts/enable_ima_measurement.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# This is enabling IMA measurement temporarily +# Need to set up grub/boottime parameters for permanent measurements +# If it doesn't work, grub config for safe startup: +# GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX ima=on integrity_audit=1 lsm=integrity,ima" + +# policy is auditing: change "audit" to "measure" + +# check requirements (tpm2-tools) +set -e +command -v tpm2_startup &>/dev/null + +# don't fail +set -x +set +e + +# Enable IMA measurement +echo "1" | sudo tee /sys/kernel/security/ima/policy_update +mkdir -p /etc/ima +sudo tee /etc/ima/ima-policy << 'EOF' +# Default IMA policy +# Don't measure files opened with read-only permissions +dont_measure obj_type=file mask=MAY_READ +# Measure all executed files +audit func=BPRM_CHECK mask=MAY_EXEC +# Measure files mmap()ed for execute +audit func=FILE_MMAP mask=MAY_EXEC +# Measure files opened for write or append +audit func=FILE_CHECK mask=MAY_WRITE uid=0 +EOF + +# load the ima policy +sudo cat /etc/ima/ima-policy | sudo tee /sys/kernel/security/ima/policy + +# Configure TPM PRC - this needs +# setup tpm2-tools to access the tpmserver in docker +export TPM2TOOLS_TCTI="mssim:host=localhost,port=2321" +tpm2_startup -c + +# PCR 10 will store IMA measurements +tpm2_pcrextend 10:sha256=0000000000000000000000000000000000000000000000000000000000000000 diff --git a/security/keylime-poc/scripts/gen_allowlist.sh b/security/keylime-poc/scripts/gen_allowlist.sh new file mode 100755 index 00000000..a5506106 --- /dev/null +++ b/security/keylime-poc/scripts/gen_allowlist.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Script to generate file hashes for allowlist +# redirect to target file "allowlist.txt" + +set -eu + +cat <