Skip to content

Commit

Permalink
Merge pull request #136 from IBM/keylime
Browse files Browse the repository at this point in the history
Introduce Keylime as a tool for building node x509
  • Loading branch information
mrsabath authored May 13, 2022
2 parents 729f3a5 + 8bec606 commit f00543f
Show file tree
Hide file tree
Showing 22 changed files with 971 additions and 5 deletions.
Binary file added docs/ppt/Secure Supply Chain.SPIRE.pptx
Binary file not shown.
105 changes: 105 additions & 0 deletions docs/spire-keylime-attestion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Setting up the SPIRE NodeAttestor with Keylime
[Keylime](https://keylime.dev) is an open-source tool,
part of the [CNCF](https://cncf.io/) project,
that provides a highly scalable remote boot attestation
and runtime integrity measurement solution.
Keylime enables users to monitor remote nodes
using a hardware based cryptographic root of trust.

In this example, the Node Attestation is done using Keylime (and TPM),
tying the Workload Identity with Hardware Root of Trust:
* It guarantees the identity of the node beyond any doubt
* It attests the software stack, from booting to the kernel.
We know the firmware, packages, libraries. Enforcement of the software bill of materials (SBOM)
* It measures and enforces the integrity of files (IMA)

Once the node is attested by Keylime, the Keylime agents deliver securely
`intermediate.key.pem` and `intermediate.cert.pem`
to the node, and then create and sign
`node.key.pem` and `node.cert.pem` used by
SPIRE `x509pop` NodeAttestor (x509 proof of possession):
([server plugin](https://github.com/spiffe/spire/blob/main/doc/plugin_server_nodeattestor_x509pop.md),
[agent plugin](https://github.com/spiffe/spire/blob/main/doc/plugin_agent_nodeattestor_x509pop.md))

This example requires x509 certificates. The samples are provided in
[../sample-x509](../sample-x509).
Instructions for creating your own are available [here](x509-create.md)

## Obtain a Kubernetes cluster with deployed Keylime
We use an internal process for deploying a cluster with Keylime.
Connect to the node that has Keylime server.


## Deploy the x509 keys to all the nodes
Obtain the Trusted Service Identity project
```console
cd ~
git clone https://github.com/IBM/trusted-service-identity.git
cd trusted-service-identity
git checkout conf_container
```

Check the status of the current Keylime nodes and make sure they are all in
`verified` state:

```console
keylime-op -u /root/undercloud.yml -m /root/mzone.yml -o status
```
Sample response:
```
{
"concise": "verified",
"status": {
"small7-agent0": "verified",
"small7-agent1": "verified",
"small7-agent2": "verified",
"small7-agent3": "verified",
"small7-agent4": "verified"
}
}
```
Execute the key deployment script
```console
cd utils
./deployKeys_keylime.sh
```

Once all the nodes show Keylime agents as verified again, check if the keys
were correctly deployed. Ssh to a hosts:

```console
ssh small7-agent0 "ls -l /run/spire/x509/; cat /run/spire/x509/*"
```

When everything is good, setup the `spire-bundle` and execute the helm installation.

Capture the spire-bundle on the SPIRE Server:

```console
kubectl -n tornjak get configmap spire-bundle -oyaml | kubectl patch --type json --patch '[{"op": "replace", "path": "/metadata/namespace", "value":"spire"}]' -f - --dry-run=client -oyaml > spire-bundle.yaml
```

Bring it to the newly created cluster with deployed x509 keys and install:
```console
kubectl create ns spire
kubectl create -f spire-bundle.yaml
```

Setup the CLUSTER_NAME, REGION variables, and location of your SPIRE_SERVER:

```
cd ~/trusted-service-identity/
export CLUSTER_NAME=css
export REGION=us-ykt
export SPIRE_SERVER=spire-server-tornjak.us-east.containers.appdomain.cloud
```

Execute the SPIRE Agent installation:
```console
helm install --set "spireServer.address=$SPIRE_SERVER" \
--set "namespace=spire" \
--set "clustername=$CLUSTER_NAME" --set "trustdomain=openshift.space-x.com" \
--set "region=$REGION" \
--set "x509=true" \
--set "openShift=false" spire charts/spire --debug
```
17 changes: 12 additions & 5 deletions docs/spire-oidc-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ In this example we will deploy Tornjak and SPIRE server on OpenShift in IBM Clou

## Deploy Tornjak, SPIRE Server and Agents
Follow the documentation to deploy [Tornjak on Openshift](./spire-on-openshift.md#deploy-on-openshift])
with exception of enabling the `--oidc` flag:
with exception of enabling the `--oidc` flag.

```
# install:
Expand All @@ -17,12 +17,12 @@ utils/install-open-shift-tornjak.sh -c $CLUSTER_NAME -t $TRUST_DOMAIN -p $PROJEC
for example:

```console
utils/install-open-shift-tornjak.sh -c space-x01 -t openshift.space-x.com --oidc
utils/install-open-shift-tornjak.sh -c $CLUSTER_NAME -t openshift.space-x.com --oidc
```

This creates an output that has a following ending:

```console
```
export SPIRE_SERVER=spire-server-tornjak.space-x-01-9d995c4a8c7c5f281ce13d5467ff-0000.us-south.containers.appdomain.cloud
Tornjak (http): http://tornjak-http-tornjak.space-x-01-9d995c4a8c7c5f281ce13d5467ff-0000.us-south.containers.appdomain.cloud/
Expand Down Expand Up @@ -60,13 +60,20 @@ This output confirms that the OIDC endpoint is accessible and responds with vali

Let's install the [SPIRE Agents](./spire-on-openshift.md#step-2-installing-spire-agents-on-openshift):

```
```console
oc new-project spire --description="My TSI Spire Agent project on OpenShift"
kubectl get configmap spire-bundle -n tornjak -o yaml | sed "s/namespace: tornjak/namespace: spire/" | kubectl apply -n spire -f -
```

Then export the value of the SPIRE_SERVER frome above:

```
export SPIRE_SERVER=spire-server-tornjak.space-x-01-9d995c4a8c7c5f281ce13d5467ff-0000.us-south.containers.appdomain.cloud
```
and run the agents installation:

utils/install-open-shift-spire.sh -c space-x01 -r $REGION -s $SPIRE_SERVER -t openshift.space-x.com
```console
utils/install-open-shift-spire.sh -c $CLUSTER_NAME -r $REGION -s $SPIRE_SERVER -t openshift.space-x.com
```

Confirm the agents were successfully deployed and get the host for the registrar:
Expand Down
102 changes: 102 additions & 0 deletions docs/x509-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Deploy SPIRE Agent with x509pop (Proof of Possession) Node Attestor for Confidential Computing project

The `x509pop` nodeAttestor plugin attests nodes that have been provisioned with
an x509 identity through an out-of-band mechanism.
It verifies that the certificate is rooted to a trusted set of CAs
and issues a signature based proof-of-possession challenge to the agent plugin
to verify that the node is in possession of the private key.

This document is a second part of the 2 part activity, see [Deploy SPIRE Server with x509pop](./x509.md)

## Pre-install: Get the installation code and sample keys
Obtain the clone of the repo:

```console
git clone https://github.com/IBM/trusted-service-identity.git
git checkout conf_container
```

Sample keys are already created in `sample-x509` directory.


## Deploy SPIRE Agents

### Env. Setup
Setup `KUBECONFIG` for your Kubernetes cluster.

Setup CLUSTER_NAME, REGION and SPIRE
In IBM Cloud, use the script:

```console
utils/get-cluster-info.sh
```

otherwise setup them up directly, for now, use any strings:
```console
export CLUSTER_NAME=
export REGION=
```

Point at the SPIRE Server, this is the server deployed in previous step:
```console
export SPIRE_SERVER=
```

### Deploy the keys
Eventually, the x509 cert will be delivered to the host out-of-bound, but for now, let's pass them as secrets.

```console
# create a namespace:
kubectl create ns spire

# create a secret with keys:
kubectl -n spire create secret generic agent-x509 \
--from-file=key.pem="sample-x509/leaf1-key.pem" \
--from-file=cert.pem="sample-x509/leaf1-crt-bundle.pem"
```

### Deploy `spire-bundle`
Deploy `spire-bundle` obtained from the SPIRE server.

```console
kubectl -n spire create -f spire-bundle.yaml
```

## Install the Spire Agents

If installing on OpenShift:

```console
utils/install-open-shift-spire.sh -c $CLUSTER_NAME -r $REGION -s $SPIRE_SERVER -t openshift.space-x.com
```

If installing in native Kubernetes environment:

```console
helm install --set "spireServer.address=$SPIRE_SERVER" \
--set "namespace=spire" \
--set "clustername=$CLUSTER_NAME" --set "trustdomain=openshift.space-x.com" \
--set "region=$REGION" \
--set "x509=true" \
--set "openShift=false" spire charts/spire --debug
```

## Validate the installation
The number of Spire agents corresponds to the number of nodes:
```console
kubectl -n spire get no
NAME STATUS ROLES AGE VERSION
10.188.196.81 Ready <none> 1h v1.22.8+IKS
10.188.196.82 Ready <none> 1h v1.22.8+IKS
kubectl -n spire get po
NAME READY STATUS RESTARTS AGE
spire-agent-h9f2j 1/1 Running 0 11s
spire-agent-s2bjt 1/1 Running 0 11s
spire-registrar-5bb497cfd8-vpxnl 1/1 Running 0 11s
```

### To cleanup the cluster (removes everything)

```console
utils/install-open-shift-spire.sh --clean
```
Loading

0 comments on commit f00543f

Please sign in to comment.