Skip to content

Commit

Permalink
[#347] Add TLS Flags, CM Signed Images How-To guide and properties (#348
Browse files Browse the repository at this point in the history
)

* [#292] Add missing TLS flags for the local communication (#294)

Signed-off-by: Antonia Avramova <[email protected]>

* [#306] Update container manager reference guide in regards to the signed container images support (#308)

Signed-off-by: Dimitar Dimitrov <[email protected]

* [#311] Update default_ctrs_stop_timeout in Container Management reference guide (#312)

* [#311] Update default_ctrs_stop_timeout in Container Management reference guide

---------

Signed-off-by: Dimitar Dimitrov <[email protected]
Co-authored-by: Daniel Milchev <[email protected]>

* Provide how to guide for verifying signed container images (#309)

---------

Signed-off-by: Dimitar Dimitrov <[email protected]>

---------

Signed-off-by: Antonia Avramova <[email protected]>
Signed-off-by: Dimitar Dimitrov <[email protected]
Signed-off-by: Dimitar Dimitrov <[email protected]>
Co-authored-by: Antonia Avramova <[email protected]>
Co-authored-by: Daniel Milchev <[email protected]>
  • Loading branch information
3 people authored Jun 12, 2024
1 parent c23e90e commit 708ccbd
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 3 deletions.
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

0 comments on commit 708ccbd

Please sign in to comment.