Skip to content

Commit

Permalink
docs/test: Move test images into securesystems DockerHub repository (#79
Browse files Browse the repository at this point in the history
)

Previously, we had test images at docker.io/connytest/testimage but decided we wanted to have have the securesystems repository instead. This PR follows up on that decision. In addition, it ensures that the images are regularly download, both checking and ensuring DockerHub does not delete them.

Fix #41
  • Loading branch information
Starkteetje committed Jan 29, 2021
1 parent 6938af9 commit 8f02217
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 21 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/dockerhub-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: "Check DockerHub images"

on:
schedule:
- cron: '37 6 * * 3'

jobs:
dockerhub-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install yq
run: sudo snap install yq
- name: Check main image
run: DOCKER_CONTENT_TRUST=1 docker pull docker.io/$(yq e '.deployment.image' helm/values.yaml)
- name: Check signed test image
run: DOCKER_CONTENT_TRUST=1 docker pull docker.io/securesystemsengineering/testimage:signed
- name: Check unsigned test image
run: DOCKER_CONTENT_TRUST=0 docker pull docker.io/securesystemsengineering/testimage:unsigned
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ Make sure `docker`, `git`, `helm`, `kubectl`, `make` and `yq` (>= v4) are instal
```

- Install Connaisseur on the cluster via `make install`.
- Trying to deploy an unsigned app to your cluster will be denied due to lack of trust data: `kubectl run unsigned --image=docker.io/connytest/testimage:unsigned`
- However, the signature of our signed image is successfully verified: `kubectl run signed --image=docker.io/connytest/testimage:signed`
- You can compare the trust data of the two images via `docker trust inspect --pretty docker.io/connytest/testimage`.
- Trying to deploy an unsigned app to your cluster will be denied due to lack of trust data: `kubectl run unsigned --image=docker.io/securesystemsengineering/testimage:unsigned`
- However, the signature of our signed image is successfully verified: `kubectl run signed --image=docker.io/securesystemsengineering/testimage:signed`
- You can compare the trust data of the two images via `docker trust inspect --pretty docker.io/securesystemsengineering/testimage`.
- To uninstall Connaisseur from your cluster after the demo, run `make uninstall`.

Congrats :bowtie:! You have successfully validated authenticity and integrity of our test images before deploying to your cluster. Below you can find a guide how to setup Connaisseur in your own environment.
Expand Down
12 changes: 6 additions & 6 deletions connaisseur/tests/integration/integration-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ make install || { echo 'Failed to install Connaisseur'; exit 1; }
echo 'Successfully installed Connaisseur'

echo 'Testing unsigned image...'
kubectl run pod --image=connytest/testimage:unsigned >output.log 2>&1 || true
kubectl run pod --image=securesystemsengineering/testimage:unsigned >output.log 2>&1 || true

if [[ "$(cat output.log)" != 'Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: could not find signed digest for image "docker.io/connytest/testimage:unsigned" in trust data.' ]]; then
if [[ "$(cat output.log)" != 'Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: could not find signed digest for image "docker.io/securesystemsengineering/testimage:unsigned" in trust data.' ]]; then
echo 'Failed to deny unsigned image or failed with unexpected error. Output:'
cat output.log
exit 1
Expand All @@ -23,18 +23,18 @@ else
fi

echo 'Testing image signed under different key...'
kubectl run pod --image=securesystemsengineering/connaisseur:signed >output.log 2>&1 || true
kubectl run pod --image=library/redis >output.log 2>&1 || true

if [[ "$(cat output.log)" != 'Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: failed to verify signature of trust data.' ]]; then
echo 'Failed to deny image signed different key or failed with unexpected error. Output:'
echo 'Failed to deny image signed with different key or failed with unexpected error. Output:'
cat output.log
exit 1
else
echo 'Successfully denied usage of image signed under different key'
fi

echo 'Testing signed image...'
kubectl run pod --image=connytest/testimage:signed >output.log 2>&1 || true
kubectl run pod --image=securesystemsengineering/testimage:signed >output.log 2>&1 || true

if [[ "$(cat output.log)" != 'pod/pod created' ]]; then
echo 'Failed to allow signed image. Output:'
Expand All @@ -47,7 +47,7 @@ fi
echo 'Testing deployment of unsigned init container along with a valid container...'
kubectl apply -f connaisseur/tests/integration/valid_container_with_unsigned_init_container_image.yml >output.log 2>&1 || true

if [[ "$(cat output.log)" != 'Error from server: error when creating "connaisseur/tests/integration/valid_container_with_unsigned_init_container_image.yml": admission webhook "connaisseur-svc.connaisseur.svc" denied the request: could not find signed digest for image "docker.io/connytest/testimage:unsigned" in trust data.' ]]; then
if [[ "$(cat output.log)" != 'Error from server: error when creating "connaisseur/tests/integration/valid_container_with_unsigned_init_container_image.yml": admission webhook "connaisseur-svc.connaisseur.svc" denied the request: could not find signed digest for image "docker.io/securesystemsengineering/testimage:unsigned" in trust data.' ]]; then
echo 'Allowed an unsigned image via init container or failed due to an unexpected error handling init containers. Output:'
cat output.log
exit 1
Expand Down
4 changes: 2 additions & 2 deletions connaisseur/tests/integration/update.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ notary:
enabled: false
rootPubKey: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETBDLAICCabJQXB01DOy315nDm0aD
BREZ4aWG+uphuFrZWw0uAVLW9B/AIcJkHa7xQ/NLtrDi3Ou5dENzDy+Lkg==
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsx28WV7BsQfnHF1kZmpdCTTLJaWe
d0CA+JOi8H4REuBaWSZ5zPDe468WuOJ6f71E7WFg3CVEVYHuoZt2UYbN/Q==
-----END PUBLIC KEY-----
policy:
- pattern: "*:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ metadata:
spec:
containers:
- name: valid_container
image: connytest/testimage:signed
image: securesystemsengineering/testimage:signed
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: unsigned_init_container
image: connytest/testimage:unsigned
image: securesystemsengineering/testimage:unsigned
command: ['sh', '-c', 'sleep 5']
6 changes: 3 additions & 3 deletions connaisseur/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def process_chain_of_trust(
potentially 'targets/releases' are requested in this order and afterwards
validated, also according to the `policy_rule`.
Returns the the signed image targets, which contain the digests.
Returns the signed image targets, which contain the digests.
Raises `NotFoundExceptions` should no required delegetions be present in
the trust data, or no image targets be found.
Expand All @@ -99,9 +99,9 @@ def process_chain_of_trust(
)

# validate all trust data's signatures, expiry dates and hashes.
# when delegation are added to the repository, but weren't yet used for signing, the
# when delegations are added to the repository, but weren't yet used for signing, the
# delegation files don't exist yet and are `None`. in this case they can't be
# validated and must be skipped.
# validated and must be skipped
for role in trust_data:
if trust_data[role] is not None:
trust_data[role].validate(key_store)
Expand Down
3 changes: 3 additions & 0 deletions setup/Dockerfile.unsigned
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM python:3.7-alpine
RUN echo "echo 'Hello World of untrusted images D: (will sleep for forever)'; sleep infinity;" >> hello.sh
CMD ["sh", "hello.sh"]
10 changes: 5 additions & 5 deletions setup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Let's test if our configuration works. We need to prepare a signed and an unsign

```bash
# Typically, IMAGE_PATH=<YOUR-REGISTRY>/<YOUR-REPOSITORY-NAME-/-DOCKER-HUB-ID>/<IMAGE-NAME>
IMAGE_PATH=docker.io/connytest/testimage
IMAGE_PATH=docker.io/securesystemsengineering/testimage
```

We start with the signed image and use the `Dockerfile` in `connaisseur/setup` as sample:
Expand All @@ -201,12 +201,12 @@ DOCKER_CONTENT_TRUST=0 docker push ${IMAGE_PATH}:unsigned
We can check if everything works via `docker trust inspect --pretty ${IMAGE_PATH}` and should get something like:

```bash
Signatures for docker.io/connytest/testimage
Signatures for docker.io/securesystemsengineering/testimage

SIGNED TAG DIGEST SIGNERS
signed 0c5d7013f91c03a2e87c29439ecfd093527266d92bfb051cab2103b80791193a (Repo Admin)

Administrative keys for docker.io/connytest/testimage
Administrative keys for docker.io/securesystemsengineering/testimage

Repository Key: 130b5abbea417fea7e2a0acd2cc0a3a84f81d5b763ed82dcfaad8dceebac0b75
Root Key: 6b35860633a0cf852670fd9b5c12ba068875f3804d6711feb16fcd74c723c816
Expand All @@ -233,13 +233,13 @@ kubectl run unsigned --image=${IMAGE_PATH}:unsigned
You should see the deployment being rejected with an error similar to:

```bash
Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: could not find signed digest for image "docker.io/connytest/testimage:unsigned" in trust data.
Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: could not find signed digest for image "docker.io/securesystemsengineering/testimage:unsigned" in trust data.
```
or if you pushed the unsigned image to another registry altogether:
```bash
Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: no trust data for image "docker.io/connytest/testimage:unsigned".
Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: no trust data for image "docker.io/securesystemsengineering/testimage:unsigned".
```
> Note that while deployment of containers is blocked, Kubernetes will still create services or other resources you might specify in a `deployment.yaml` because those do not reference an image and are thus not denied by Connaisseur. You might have to clean up denied deployments.
Expand Down

0 comments on commit 8f02217

Please sign in to comment.