Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#347] Merge dev-m5 branch in main #348

Merged
merged 4 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions web/site/content/docs/how-to-guides/verify-signed-container-images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
title: "Verify signed container images"
type: docs
description: >
Verify that container image is signed when creating a container from it in Kanto Container Management.
weight: 5
---

By following the steps below, you will sign a container image and push it to a local registry using a{{% refn "https://github.com/notaryproject/notation" %}}`notation`{{% /refn %}}. Then a notation trust policy and the Kanto Container Management service will be configured in a way that running containers from the signed image via kanto-cm CLI will be successful, while running containers from unsigned images will fail.

### Before you begin

To ensure that your edge device is capable to execute the steps in this guide, you need:

* If you don't have an installed and running Eclipse Kanto, follow {{% relrefn "install" %}} Install Eclipse Kanto {{% /relrefn %}}
* Installed {{% refn "https://notaryproject.dev/docs/user-guides/installation/cli/" %}} Notation CLI {{% /refn %}}
* Installed and running {{% refn "https://www.docker.com/products/docker-desktop/" %}} Docker {{% /refn %}}

### Create an image and push it to a local registry using docker and than sign it with notation

Create and run a local container registry:
```shell
sudo kanto-cm create --ports 5000:5000 --e REGISTRY_STORAGE_DELETE_ENABLED=true --name registry docker.io/library/registry:latest
sudo kanto-cm start -n registry
```

Build a dummy hello world image and push it to the registry:
```shell
cat <<EOF | sudo docker build -t localhost:5000/dummy-hello:signed -
FROM busybox:latest
CMD [ "echo", "Hello World" ]
EOF
sudo docker push localhost:5000/dummy-hello:signed
```

{{% tip %}}
When signing and verifying container images it is recommended to use the image digest instead of a tag as the digest is immutable.
{{% /tip %}}
Get the image digest and assign it to an environment variable to be used the next steps of the guide:
```shell
export IMAGE=$(sudo docker inspect --format='{{index .RepoDigests 0}}' localhost:5000/dummy-hello:signed)
echo $IMAGE
```

Generate a key-pair with notation and add it as the default signing key:
```shell
notation cert generate-test --default "kanto"
```

Sign the image and store the signature in the registry:
```shell
notation sign $IMAGE
```

### Configure notation truspolicy and container management verifier

Get the notation config directory and assign it to an environment variable to be used in the next steps of the guide:
```shell
export NOTATION_CONFIG=${XDG_CONFIG_HOME:-$HOME/.config}/notation
echo $NOTATION_CONFIG
```

Create a simple {{% refn "https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#trust-policy" %}} notation trustpolicy {{% /refn %}} as a `trustpolicy.json` file in the notation config directory:
```shell
cat <<EOF | tee $NOTATION_CONFIG/trustpolicy.json
{
"version": "1.0",
"trustPolicies": [
{
"name": "kanto-images",
"registryScopes": [ "*" ],
"signatureVerification": {
"level" : "strict"
},
"trustStores": [ "ca:kanto" ],
"trustedIdentities": [ "*" ]
}
]
}
EOF
```

Create a backup of the initial Kanto Container Management configuration that is found in `/etc/container-management/config.json`(the backup will be restored at the end of the guide):
```shell
sudo cp /etc/container-management/config.json /etc/container-management/config-backup.json
```

Configure the use of notation verifier, set its config directory, mark the local registry as an insecure one, and set the image expiry time to zero seconds, so the local cache of the images used in the how-to will be deleted upon container removal:
```shell
cat <<EOF | sudo tee /etc/container-management/config.json
{
"log": {
"log_file": "/var/log/container-management/container-management.log"
},
"containers": {
"image_verifier_type": "notation",
"image_verifier_config": {
"configDir": "$NOTATION_CONFIG"
},
"insecure_registries": [ "localhost:5000" ],
"image_expiry": "0s"
}
}
EOF
```

Restart the Container Management service for the changes to take effect:
```shell
sudo systemctl restart container-management.service
```

### Verify

Create and run a container from the signed image. The container prints `Hello world` to the console:
```shell
sudo kanto-cm create --name dummy-hello --rp no --t $IMAGE
sudo kanto-cm start --name dummy-hello --a
```


Make sure that a docker hub hello-world image is not cached locally, by removing any containers with this image, and verify that creating containers from it fails, as the image is not signed, and the signature verification fails:
```shell
sudo kanto-cm remove -f $(sudo kanto-cm list --quiet --filter image=docker.io/library/hello-world:latest)
sudo kanto-cm create --name dockerhub-hello --rp no --t docker.io/library/hello-world:latest
```

### Clean up

Remove the created containers from the Kanto Container Management:
```shell
sudo kanto-cm remove -n dummy-hello
sudo kanto-cm remove -n registry -f
```

Restore the initial Kanto Container Management configuration and restart the service:
```shell
sudo mv -f /etc/container-management/config-backup.json /etc/container-management/config.json
sudo systemctl restart container-management.service
```

Remove the localy cached images from Docker:
```shell
sudo docker image rm localhost:5000/dummy-hello:signed registry:latest
```

Reset the notation configuration by removing the directory:
```shell
rm -r $NOTATION_CONFIG
```

Unset exported environment variables:
```shell
unset IMAGE NOTATION_CONFIG
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ Be aware that some combinations may be incompatible
{
"provisioningFile": "provisioning.json",
"address": "mqtts://mqtt.bosch-iot-hub.com:8883",
"alpn" : [],
"deviceId": "",
"authId": "",
"tenantId": "",
"password": "",
"username": "",
"clientId": "",
"policyId": "",
"alpn" : [],
"caCert": "iothub.crt",
"cert": "",
"key": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ To control all aspects of the container manager behavior.
| exec_root_dir | string | /var/run/container-management | Root directory for the container manager's executable artifacts |
| container_client_sid | string | container-management.service.local.v1.service-containerd-client | Unique identifier that is used for an interaction with the runtime |
| network_manager_sid | string | container-management.service.local.v1.service-libnetwork-manager | Unique identifier that is used for networking |
| default_ctrs_stop_timeout | int | 30 | Timeout in seconds for a container to stop gracefully, otherwise its root process will be force stopped |
| default_ctrs_stop_timeout | string | 30s | Timeout for a container to stop gracefully in duration string format (e.g. 1h2m3s5ms), otherwise its root process will be forcefully stopped |
| **Runtime** | | | |
| default_ns | string | kanto-cm | Namespace that is used by the runtime for isolation |
| address_path | string | /run/containerd/containerd.sock | Path to the runtime's communication endpoint |
Expand All @@ -28,6 +28,8 @@ To control all aspects of the container manager behavior.
| image_expiry | string | 744h | Time period for the cached images and content to be kept in the form of e.g. 72h3m0.5s |
| image_expiry_disable | bool | false | Disable expiry management of cached images and content, must be used with caution as it may lead to large memory volumes being persistently allocated |
| lease_id | string | kanto-cm.lease | Lease identifier to be used for container resources persistence |
| image_verifier_type | string | none | The image verifier type - possible values are none and notation, when set to none image signatures wil not be verified |
| image_verifier_config | map[string]string | | The configuration of the image verifier, as a string map - possible keys for notation verifier are `configDir` and `libexecDir`, for more info check [notation documentation](https://notaryproject.dev/docs/user-guides/how-to/directory-structure/#user-level) |
| **Registry access - secure** | | | |
| user_id | string | | User unique identifier to authenticate to the image registry |
| password | string | | Password to authenticate to the image registry |
Expand Down Expand Up @@ -133,6 +135,10 @@ Be aware that in the registry configuration the host (used as a key) has to be s
"runc_runtime": "io.containerd.runc.v2",
"image_expiry": "744h",
"image_expiry_disable": false,
"image_verifier_type": "notation",
"image_verifier_config": {
"configDir": "/home/user/.config/notation"
},
"lease_id": "kanto-cm.lease",
"registry_configurations": {
"": {
Expand Down
7 changes: 7 additions & 0 deletions web/site/content/docs/references/software-update-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ To control all aspects of the software update behavior.
| broker | string | tcp://localhost:1883 | Address of the MQTT server/broker that the software update will connect for the local communication, the format is: `scheme://host:port` |
| username | string | | Username that is a part of the credentials |
| password | string | | Password that is a part of the credentials |
| **Local connectivity - TLS** | | | |
| caCert | string | | PEM encoded CA certificates file |
| cert | string | | PEM encoded certificate file to authenticate to the MQTT server/broker |
| key | string | | PEM encoded unencrypted private key file to authenticate to the MQTT server/broker |
| **Logging** | | | |
| logFile | string | log/software-update.log | Path to the file where log messages are written |
| logLevel | string | INFO | All log messages at this or higher level will be logged, the log levels in descending order are: ERROR, WARN, INFO, DEBUG and TRACE |
Expand Down Expand Up @@ -67,6 +71,9 @@ The following template illustrates all possible properties with their default va
"broker": "tcp://localhost:1883",
"username": "",
"password": "",
"caCert": "",
"cert": "",
"key": "",
"logFile": "log/software-update.log",
"logLevel": "INFO",
"logFileCount": 5,
Expand Down
9 changes: 8 additions & 1 deletion web/site/content/docs/references/system-metrics-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ To control all aspects of the system metrics behavior.
| broker | string | tcp://localhost:1883 | Address of the MQTT server/broker that the system metrics will connect for the local communication, the format is: `scheme://host:port` |
| username | string | | Username that is a part of the credentials |
| password | string | | Password that is a part of the credentials |
| **Local connectivity - TLS** | | | |
| caCert | string | | PEM encoded CA certificates file |
| clientCert | string | | PEM encoded certificate file to authenticate to the MQTT server/broker |
| clientKey | string | | PEM encoded unencrypted private key file to authenticate to the MQTT server/broker |
| **Logging** | | | |
| logFile | string | log/system-metrics.log | Path to the file where log messages are written |
| logLevel | string | INFO | All log messages at this or higher level will be logged, the log levels in descending order are: ERROR, WARN, INFO, DEBUG and TRACE |
Expand All @@ -42,10 +46,13 @@ The following template illustrates all possible properties with their default va

```json
{
"frequency" : ""
"frequency" : "",
"broker": "tcp://localhost:1883",
"username": "",
"password": "",
"caCert": "",
"clientCert": "",
"cleintKey": "",
"logFile": "log/system-metrics.log",
"logLevel": "INFO",
"logFileCount": 5,
Expand Down