Skip to content

Commit

Permalink
add keylime-poc
Browse files Browse the repository at this point in the history
Make a Proof of Concept of Keylime is k8s cluster.

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.

Signed-off-by: Tuomo Tanskanen <[email protected]>
  • Loading branch information
tuminoid committed Dec 5, 2024
1 parent f953eba commit e79df37
Show file tree
Hide file tree
Showing 23 changed files with 1,568 additions and 0 deletions.
28 changes: 28 additions & 0 deletions security/keylime-poc/Makefile
Original file line number Diff line number Diff line change
@@ -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
12 changes: 12 additions & 0 deletions security/keylime-poc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Keylime POC
<!-- cSpell:ignore keylime -->

WIP: ANYTHING CAN CHANGE AND BE OUT OF DATE FOR NOW!

## Docker Compose

Make a Proof of Concept of [Keylime in Docker Compose](compose/README.md).

## Kubernetes

Make a Proof of Concept of [Keylime in k8s](k8s/README.md).
85 changes: 85 additions & 0 deletions security/keylime-poc/agent-with-swtpm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
##############################################################################
# keylime TPM 2.0 Dockerfile
#
# This file is for automatic test running of Keylime and rust-keylime.
# It is not recommended for use beyond testing scenarios.
##############################################################################

FROM quay.io/fedora/fedora

# environment variables
ARG BRANCH=master
ENV container docker
ENV HOME /root
ENV KEYLIME_HOME ${HOME}/keylime
ENV TPM_HOME ${HOME}/swtpm2
COPY dbus-policy.conf /etc/dbus-1/system.d/

# Packaged dependencies
ENV PKGS_DEPS "automake \
clang clang-devel \
createrepo_c \
czmq-devel \
dbus \
dbus-daemon \
dbus-devel \
dnf-plugins-core \
efivar-devel \
gcc \
git \
glib2-devel \
glib2-static \
gnulib \
iproute \
kmod \
libarchive-devel \
libselinux-python3 \
libtool \
libtpms \
llvm llvm-devel \
make \
openssl-devel \
pkg-config \
procps \
python3-cryptography \
python3-dbus \
python3-devel \
python3-gpg \
python3-pip \
python3-requests \
python3-setuptools \
python3-sqlalchemy \
python3-tornado \
python3-virtualenv \
python3-yaml \
python3-zmq \
redhat-rpm-config \
rpm-build \
rpm-sign \
rust clippy cargo \
swtpm \
swtpm-tools \
tpm2-abrmd \
tpm2-tools \
tpm2-tss \
tpm2-tss-devel \
uthash-devel \
wget \
which"

ENV DEV_DEPS "strace openssl"

RUN dnf makecache && \
dnf -y install $PKGS_DEPS $DEV_DEPS && \
dnf clean all && \
rm -rf /var/cache/dnf/*

RUN git clone https://github.com/keylime/rust-keylime \
&& cd rust-keylime \
&& make all \
&& make install \
&& cd .. \
&& rm -rf rust-keylime

COPY start.sh /
CMD ["/start.sh"]
12 changes: 12 additions & 0 deletions security/keylime-poc/agent-with-swtpm/dbus-policy.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy context="default">
<!-- Allow everything to be sent -->
<allow send_destination="*" eavesdrop="true"/>
<!-- Allow everything to be received -->
<allow eavesdrop="true"/>
<!-- Allow anyone to own anything -->
<allow own="*"/>
</policy>
</busconfig>
57 changes: 57 additions & 0 deletions security/keylime-poc/agent-with-swtpm/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash

set -eux

KEYLIME=/var/lib/keylime
TPMDIR=/tmp/tpmdir

# configure swtpm2 and start it
mkdir -p "${TPMDIR}"
chown tss:tss "${TPMDIR}"
chmod 750 "${TPMDIR}"

swtpm_setup --tpm2 \
--tpmstate "${TPMDIR}" \
--createek --decryption --create-ek-cert \
--create-platform-cert \
--display || true
swtpm socket --tpm2 \
--tpmstate dir="${TPMDIR}" \
--flags startup-clear \
--ctrl type=tcp,port=2322 \
--server type=tcp,port=2321 \
--daemon
sleep 2

# configure dbus for abmrd
sudo rm -rf /var/run/dbus
sudo mkdir /var/run/dbus
sudo dbus-daemon --system

# run abmrd
tpm2-abrmd \
--logger=stdout \
--tcti=swtpm: \
--allow-root \
--flush-all \
&
sleep 2

# prep image for running agent as non-root
useradd -s /sbin/nologin -g tss keylime || true

chown keylime:tss "${KEYLIME}" "${KEYLIME}"/secure
chmod 770 "${KEYLIME}" "${KEYLIME}"/secure
cp "${KEYLIME}"/cv_ca/cacert.crt "${KEYLIME}"/secure/
chown keylime:tss "${KEYLIME}"/secure/cacert.crt

# make swtpm CA accessible to tenant to validate EK cert
# and verify it to be sure we have it right to avoid issues down the road
cat /var/lib/swtpm-localca/{issuercert,swtpm-localca-rootca-cert}.pem > "${KEYLIME}"/tpm_cert_store/swtpm_localca.pem
tpm2_getekcertificate > "${KEYLIME}"/ek.bin
openssl x509 -inform DER -in "${KEYLIME}"/ek.bin -out "${KEYLIME}"/ek.pem
openssl verify -CAfile "${KEYLIME}"/tpm_cert_store/swtpm_localca.pem "${KEYLIME}"/ek.pem
sleep 2

# run agent
keylime_agent
1 change: 1 addition & 0 deletions security/keylime-poc/compose/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
allowlist.txt
10 changes: 10 additions & 0 deletions security/keylime-poc/compose/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Keylime POC
<!-- cSpell:ignore keylime -->

WIP: ANYTHING CAN CHANGE AND BE OUT OF DATE FOR NOW!

## Docker Compose

Make a Proof of Concept of [Keylime in Docker Compose](compose/README.md).

TBD documentation.
87 changes: 87 additions & 0 deletions security/keylime-poc/compose/agent.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
[agent]
# The configuration file version
version = "2.3"

# The agent's UUID.
uuid = "c47b9ea2-2bc2-461b-957b-e77dbcf35e5e"
# uuid = "hash_ek"
# uuid = "generate"

# The keylime working directory. The default value is /var/lib/keylime
keylime_dir = "/var/lib/keylime"

# The size of the memory-backed tmpfs partition where Keylime stores crypto keys.
# Use syntax that the 'mount' command would accept as a size parameter for tmpfs.
# The default below sets it to 1 megabyte.
secure_size = "1m"
# run_as = "keylime:tss"

# Enable mTLS communication between agent, verifier and tenant.
# Details on why setting it to "false" is generally considered insecure can be found
# on https://github.com/keylime/keylime/security/advisories/GHSA-2m39-75g9-ff5r
agent_enable_mtls = "true"

# The name of the file containing the Keylime agent TLS server private key.
# This private key is used to serve the Keylime agent REST API
# A new private key is generated in case it is not found.
# If set as "default", the "server-private.pem" value is used.
# If a relative path is set, it will be considered relative from the keylime_dir.
# If an absolute path is set, it is used without change
server_key = "secure/agent.key"

# The name of the file containing the X509 certificate used as the Keylime agent
# server TLS certificate.
# This certificate must be self signed.
# If set as "default", the "server-cert.crt" value is used
# If a relative path is set, it will be considered relative from the keylime_dir.
# If an absolute path is set, it is used without change.
server_cert = "secure/agent.crt"

# The CA that signs the client certificates of the tenant and verifier.
# If set as "default" the "cv_ca/cacert.crt" value, relative from the
# keylime_dir is used.
# If a relative path is set, it will be considered relative from the keylime_dir.
# If an absolute path is set, it is used without change.
trusted_client_ca = "secure/cacert.crt"

# The address and port of registrar server which agent communicate with
registrar_ip = "127.0.0.2"
registrar_port = 8890

# tbd
# The binding IP address and port for the agent server
ip = "0.0.0.0"
port = 9002

# Address and port where the verifier and tenant can connect to reach the agent.
# These keys are optional.
contact_ip = "127.0.0.3"
contact_port = 9002

# Use this option to state the existing TPM ownerpassword.
# This option should be set only when a password is set for the Endorsement
# Hierarchy (e.g. via "tpm2_changeauth -c e").
# In order to use a hex value for the password, use the prefix "hex:"
# For example if tpm2_changeauth -c e "hex:00a1b2c3e4" has run, the config option
# would be 'tpm_ownerpassword = "hex:00a1b2c3e4"'
# If no password was set, keep the empty string "".
tpm_ownerpassword = ""
tpm_version = "2"

# enc_keyname = "derived_tci_key"
# dec_payload_file = "decrypted_payload"
# extract_payload_zip = true
# enable_revocation_notifications = false
# revocation_actions_dir = "/usr/libexec/keylime"
# revocation_cert = "default"
# revocation_actions = ""
# payload_script = "autorun.sh"
# allow_payload_revocation_actions = true
# tpm_hash_alg = "sha256"
# tpm_encryption_alg = "rsa"
# tpm_signing_alg = "rsassa"
# ek_handle = "generate"
# enable_iak_idevid = false
# agent_data_path = ""
# ima_ml_path = "default"
# measuredboot_ml_path = "default"
73 changes: 73 additions & 0 deletions security/keylime-poc/compose/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
services:
keylime-verifier:
# image: quay.io/keylime/keylime_verifier:v7.10.0
image: keylime_verifier:latest # locally built
hostname: keylime-verifier
volumes:
- ./verifier.conf:/etc/keylime/verifier.conf:ro
- ./logging.conf:/etc/keylime/logging.conf:ro
- secure_volume:/var/lib/keylime
ports:
- "8881:8881"
user: root

keylime-registrar:
# image: quay.io/keylime/keylime_registrar:v7.10.0
image: keylime_registrar:latest # locally built
hostname: keylime-registrar
depends_on:
- keylime-verifier
volumes:
- ./registrar.conf:/etc/keylime/registrar.conf:ro
- ./logging.conf:/etc/keylime/logging.conf:ro
- secure_volume:/var/lib/keylime
ports:
- "8891:8891"
- "8890:8890"
user: root
entrypoint: ["bash", "-c", "sleep 5; keylime_registrar"]

keylime-tenant:
# image: quay.io/keylime/keylime_tenant:v7.10.0
image: keylime_tenant:latest # locally built
hostname: keylime-tenant
network_mode: host
depends_on:
- keylime-verifier
volumes:
- ./tenant.conf:/etc/keylime/tenant.conf:ro
- ./logging.conf:/etc/keylime/logging.conf:ro
- secure_volume:/var/lib/keylime
- ./allowlist.txt:/tmp/allowlist.txt:ro
user: root
entrypoint: ["bash", "-c", "tail -f /dev/null"]

keylime-agent:
build:
# image: quay.io/keylime/keylime_agent:master + swtpm config
context: ../agent-with-swtpm
dockerfile: ../agent-with-swtpm/Dockerfile
hostname: keylime-agent
network_mode: host
user: root
depends_on:
- keylime-verifier
- keylime-registrar
environment:
- TPM2TOOLS_TCTI=tabrmd:bus_type=system
- TCTI=tabrmd:bus_type=system
- RUST_LOG=keylime_agent=debug
volumes:
- /sys/kernel/security:/sys/kernel/security:ro
- ./agent.conf:/etc/keylime/agent.conf:ro
- ./target/debug/:/rust-keylime
- secure_volume:/var/lib/keylime
- agent_volume:/var/lib/keylime/secure
# command: keylime_agent

volumes:
secure_volume:
agent_volume:
driver_opts:
type: tmpfs
device: tmpfs
Loading

0 comments on commit e79df37

Please sign in to comment.