From ecb881e5e6e3ea77721865c5bb1d61725579fd54 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Mon, 8 Mar 2021 18:06:04 +0900 Subject: [PATCH] add imgcrypt stream processors to the default config Enable the following config by default: ```toml version = 2 [plugins."io.containerd.grpc.v1.cri".image_decryption] key_model = "node" [stream_processors] [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"] accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"] returns = "application/vnd.oci.image.layer.v1.tar+gzip" path = "ctd-decoder" args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"] accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"] returns = "application/vnd.oci.image.layer.v1.tar" path = "ctd-decoder" args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] ``` Fix issue 5128 Signed-off-by: Akihiro Suda --- cmd/containerd/command/config.go | 38 ++++++++++++++++++++++++++++++-- docs/cri/decryption.md | 27 +++++++++++------------ images/mediatypes.go | 3 +++ pkg/cri/config/config_unix.go | 3 +++ pkg/cri/config/config_windows.go | 4 ++++ 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/cmd/containerd/command/config.go b/cmd/containerd/command/config.go index 92b455fc7..f843b8041 100644 --- a/cmd/containerd/command/config.go +++ b/cmd/containerd/command/config.go @@ -20,12 +20,15 @@ import ( gocontext "context" "io" "os" + "path/filepath" "github.com/BurntSushi/toml" "github.com/containerd/containerd/defaults" + "github.com/containerd/containerd/images" "github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/services/server" srvconfig "github.com/containerd/containerd/services/server/config" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/urfave/cli" ) @@ -125,7 +128,38 @@ func platformAgnosticDefaultConfig() *srvconfig.Config { MaxRecvMsgSize: defaults.DefaultMaxRecvMsgSize, MaxSendMsgSize: defaults.DefaultMaxSendMsgSize, }, - DisabledPlugins: []string{}, - RequiredPlugins: []string{}, + DisabledPlugins: []string{}, + RequiredPlugins: []string{}, + StreamProcessors: streamProcessors(), + } +} + +func streamProcessors() map[string]srvconfig.StreamProcessor { + const ( + ctdDecoder = "ctd-decoder" + basename = "io.containerd.ocicrypt.decoder.v1" + ) + decryptionKeysPath := filepath.Join(defaults.DefaultConfigDir, "ocicrypt", "keys") + ctdDecoderArgs := []string{ + "--decryption-keys-path", decryptionKeysPath, + } + ctdDecoderEnv := []string{ + "OCICRYPT_KEYPROVIDER_CONFIG=" + filepath.Join(defaults.DefaultConfigDir, "ocicrypt", "ocicrypt_keyprovider.conf"), + } + return map[string]srvconfig.StreamProcessor{ + basename + ".tar.gzip": { + Accepts: []string{images.MediaTypeImageLayerGzipEncrypted}, + Returns: ocispec.MediaTypeImageLayerGzip, + Path: ctdDecoder, + Args: ctdDecoderArgs, + Env: ctdDecoderEnv, + }, + basename + ".tar": { + Accepts: []string{images.MediaTypeImageLayerEncrypted}, + Returns: ocispec.MediaTypeImageLayer, + Path: ctdDecoder, + Args: ctdDecoderArgs, + Env: ctdDecoderEnv, + }, } } diff --git a/docs/cri/decryption.md b/docs/cri/decryption.md index abde945b8..32e2cd235 100644 --- a/docs/cri/decryption.md +++ b/docs/cri/decryption.md @@ -15,32 +15,31 @@ In this model encryption is tied to worker nodes. The usecase here revolves arou ### Configuring image decryption for "node" key model -The default configuration does not handle decrypting encrypted container images. +This is the default model since containerd v1.5. -An example for configuring the "node" key model for container image decryption: - -Configure `cri` to enable decryption with "node" key model +For containerd v1.4, you need to add the following configuration to `/etc/containerd/config.toml` and restart the `containerd` service manually. ```toml +version = 2 + [plugins."io.containerd.grpc.v1.cri".image_decryption] key_model = "node" -``` -Configure `containerd` daemon [`stream_processors`](https://github.com/containerd/containerd/blob/master/docs/stream_processors.md) to handle the -encrypted mediatypes. -```toml [stream_processors] [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"] accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"] returns = "application/vnd.oci.image.layer.v1.tar+gzip" - path = "/usr/local/bin/ctd-decoder" - args = ["--decryption-keys-path", "/keys"] + path = "ctd-decoder" + args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] + env= ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"] accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"] returns = "application/vnd.oci.image.layer.v1.tar" - path = "/usr/local/bin/ctd-decoder" - args = ["--decryption-keys-path", "/keys"] + path = "ctd-decoder" + args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] + env= ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] ``` -In this example, container image decryption is set to use the "node" key model. In addition, the decryption [`stream_processors`](https://github.com/containerd/containerd/blob/master/docs/stream_processors.md) are configured as specified in [containerd/imgcrypt project](https://github.com/containerd/imgcrypt), with the additional field `--decryption-keys-path` configured to specify where decryption keys are located locally in the node. +In this example, container image decryption is set to use the "node" key model. +In addition, the decryption [`stream_processors`](https://github.com/containerd/containerd/blob/master/docs/stream_processors.md) are configured as specified in [containerd/imgcrypt project](https://github.com/containerd/imgcrypt), with the additional field `--decryption-keys-path` configured to specify where decryption keys are located locally in the node. -After modify this config, you need restart the `containerd` service. +The `$OCICRYPT_KEYPROVIDER_CONFIG` environment variable is used for [ocicrypt keyprovider protocol](https://github.com/containers/ocicrypt/blob/master/docs/keyprovider.md). diff --git a/images/mediatypes.go b/images/mediatypes.go index 996cec59a..785d71291 100644 --- a/images/mediatypes.go +++ b/images/mediatypes.go @@ -49,6 +49,9 @@ const ( MediaTypeContainerd1CheckpointRuntimeOptions = "application/vnd.containerd.container.checkpoint.runtime.options+proto" // Legacy Docker schema1 manifest MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws" + // Encypted media types + MediaTypeImageLayerEncrypted = ocispec.MediaTypeImageLayer + "+encrypted" + MediaTypeImageLayerGzipEncrypted = ocispec.MediaTypeImageLayerGzip + "+encrypted" ) // DiffCompression returns the compression as defined by the layer diff media diff --git a/pkg/cri/config/config_unix.go b/pkg/cri/config/config_unix.go index f91208538..66ee417a4 100644 --- a/pkg/cri/config/config_unix.go +++ b/pkg/cri/config/config_unix.go @@ -72,5 +72,8 @@ func DefaultConfig() PluginConfig { TolerateMissingHugetlbController: true, DisableHugetlbController: true, IgnoreImageDefinedVolumes: false, + ImageDecryption: ImageDecryption{ + KeyModel: KeyModelNode, + }, } } diff --git a/pkg/cri/config/config_windows.go b/pkg/cri/config/config_windows.go index 2a1c45753..9d33eb7f8 100644 --- a/pkg/cri/config/config_windows.go +++ b/pkg/cri/config/config_windows.go @@ -67,5 +67,9 @@ func DefaultConfig() PluginConfig { MaxConcurrentDownloads: 3, IgnoreImageDefinedVolumes: false, // TODO(windows): Add platform specific config, so that most common defaults can be shared. + + ImageDecryption: ImageDecryption{ + KeyModel: KeyModelNode, + }, } }