Merge pull request #796 from docker/dct-plugin-675

DCT plugin 675
This commit is contained in:
Justin I. Nevill 2018-10-26 14:22:33 -04:00 committed by GitHub
commit a8659a4bb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 112 additions and 47 deletions

View File

@ -199,6 +199,21 @@ capability removal, or less secure through the addition of capabilities.
The best practice for users would be to remove all capabilities except
those explicitly required for their processes.
## Docker Content Trust Signature Verification
The Docker Engine can be configured to only run signed images. The Docker Content
Trust signature verification feature is built directly into the `dockerd` binary.
This is configured in the Dockerd configuration file.
To enable this feature, trustpinning can be configured in `daemon.json`, whereby
only repositories signed with a user-specified root key can be pulled and run.
This feature provides more insight to administrators than previously available with
the CLI for enforcing and performing image signature verification.
For more information on configuring Docker Content Trust Signature Verificiation, go to
(Content trust in Docker)[engine/security/trust/content_trust].
## Other kernel security features
Capabilities are just one of the many security features provided by

View File

@ -13,29 +13,23 @@ data received from a registry over any channel.
## About trust in Docker
Content trust allows operations with a remote Docker registry to enforce
client-side signing and verification of image tags. Content trust provides the
Docker Content Trust (DCT) allows operations with a remote Docker registry to enforce
client-side signing and verification of image tags. DCT provides the
ability to use digital signatures for data sent to and received from remote
Docker registries. These signatures allow client-side verification of the
integrity and publisher of specific image tags.
Currently, content trust is disabled by default. To enable it, set
the `DOCKER_CONTENT_TRUST` environment variable to `1`. Refer to the
[environment variables](../../reference/commandline/cli.md#environment-variables)
and [Notary](../../reference/commandline/cli.md#notary) configuration
for the docker client for more options.
Once DCT is enabled, image publishers can sign their images. Image consumers
can ensure that the images they use are signed. Publishers and consumers can
either be individuals or organizations. DCT supports users and automated processes
such as builds.
Once content trust is enabled, image publishers can sign their images. Image consumers can
ensure that the images they use are signed. Publishers and consumers can be
individuals alone or in organizations. Docker's content trust supports users and
automated processes such as builds.
When you enable DCT, signing occurs on the client after push and verification
happens on the client after pull if you use Docker CE. If you use UCP, and you
have configured UCP to require images to be signed before deploying, signing is
verified by UCP.
When you enable content trust, signing occurs on the client after push and
verification happens on the client after pull if you use Docker CE. If you use
Docker EE with UCP, and you have configured UCP to require images to be signed
before deploying, signing is verified by UCP.
### Image tags and content trust
### Image tags and DCT
An individual image record has the following identifier:
@ -47,7 +41,7 @@ A particular image `REPOSITORY` can have multiple tags. For example, `latest` an
`3.1.2` are both tags on the `mongo` image. An image publisher can build an image
and tag combination many times changing the image with each build.
Content trust is associated with the `TAG` portion of an image. Each image
DCT is associated with the `TAG` portion of an image. Each image
repository has a set of keys that image publishers use to sign an image tag.
Image publishers have discretion on which tags they sign.
@ -68,24 +62,24 @@ push replaces the last unsigned tag `latest` but does not affect the signed `lat
The ability to choose which tags they can sign, allows publishers to iterate over
the unsigned version of an image before officially signing it.
Image consumers can enable content trust to ensure that images they use were
signed. If a consumer enables content trust, they can only pull, run, or build
with trusted images. Enabling content trust is like wearing a pair of
Image consumers can enable DCT to ensure that images they use were
signed. If a consumer enables DCT, they can only pull, run, or build
with trusted images. Enabling DCT is like wearing a pair of
rose-colored glasses. Consumers "see" only signed image tags and the less
desirable, unsigned image tags are "invisible" to them.
![Trust view](images/trust_view.png)
To the consumer who has not enabled content trust, nothing about how they
To the consumer who has not enabled DCT, nothing about how they
work with Docker images changes. Every image is visible regardless of whether it
is signed or not.
### Content trust operations and keys
### DCT operations and keys
When content trust is enabled, `docker` CLI commands that operate on tagged images must
When DCT is enabled, `docker` CLI commands that operate on tagged images must
either have content signatures or explicit content hashes. The commands that
operate with content trust are:
operate with DCT are:
* `push`
* `build`
@ -93,7 +87,7 @@ operate with content trust are:
* `pull`
* `run`
For example, with content trust enabled a `docker pull someimage:latest` only
For example, with DCT enabled a `docker pull someimage:latest` only
succeeds if `someimage:latest` is signed. However, an operation with an explicit
content hash always succeeds as long as the hash exists:
@ -102,17 +96,17 @@ $ docker pull someimage@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d8
```
Trust for an image tag is managed through the use of signing keys. A key set is
created when an operation using content trust is first invoked. A key set consists
created when an operation using DCT is first invoked. A key set consists
of the following classes of keys:
- an offline key that is the root of content trust for an image tag
- an offline key that is the root of DCT for an image tag
- repository or tagging keys that sign tags
- server-managed keys such as the timestamp key, which provides freshness
security guarantees for your repository
The following image depicts the various signing keys and their relationships:
![Content trust components](images/trust_components.png)
![Content Trust components](images/trust_components.png)
>**WARNING**:
> Loss of the root key is **very difficult** to recover from.
@ -125,9 +119,9 @@ The following image depicts the various signing keys and their relationships:
You should backup the root key somewhere safe. Given that it is only required
to create new repositories, it is a good idea to store it offline in hardware.
For details on securing, and backing up your keys, make sure you
read how to [manage keys for content trust](trust_key_mng.md).
read how to [manage keys for DCT](trust_key_mng.md).
## Survey of typical content trust operations
## Survey of typical DCT operations
This section surveys the typical trusted operations users perform with Docker
images. Specifically, we go through the following steps to help us exercise
@ -139,15 +133,71 @@ these various trusted operations:
* Pull the signed image pushed above
* Pull unsigned image pushed above
### Enable and disable content trust per-shell or per-invocation
### Enabling DCT in Docker Engine Configuration
In a shell, you can enable content trust by setting the `DOCKER_CONTENT_TRUST`
environment variable. Enabling per-shell is useful because you can have one
shell configured for trusted operations and another terminal shell for untrusted
operations. You can also add this declaration to your shell profile to have it
turned on always by default.
Engine Signature Verification prevents the following behaviors on an image:
* Running a container to build an image (the base image must be signed, or must be scratch)
* Creating a container from an image that is not signed
To enable content trust in a `bash` shell enter the following command:
DCT does not verify that a running containers filesystem has not been altered from what
was in the image. For example, it does not prevent a container from writing to the filesystem, nor
the containers filesystem from being altered on disk.
It will also pull and run signed images from registries, but will not prevent unsigned images from being
imported, loaded, or created.
The image name, digest, or tag must be verified if DCT is enabled. The latest DCT metadata for
an image must be downloaded from the trust server associated with the registry:
* If an image tag does not have a digest, the DCT metadata translates the name to an image digest
* If an image tag has an image digest, the DCT metadata verifies that the name matches the provided digest
* If an image digest does not have an image tag, the DCT metadata does a reverse lookup and provides the image tag as well as the digest.
The signature verification feature is configured in the Docker daemon configuration file
`daemon.json`.
```
{
...
“content-trust”: {
“trust-pinning”: {
“root-keys”: {
“myregistry.com/myorg/*”: [“keyID1”, “keyID2”],
“myregistry.com/otherorg/repo”: [“keyID3”]
},
“official-images”: true,
},
“mode”: “disabled” | “permissive” | “enforced”,
“allow-expired-trust-cache”: true,
}
}
```
| ***Stanza*** | ***Description*** |
| ----------------------- |---------------|
| `trust-pinning:root-keys` | Root key IDs are canonical IDs that sign the root metadata of the image trust data. In Docker Certified Trust (DCT), the root keys are unique certificates tying the name of the image to the repo metadata.  The private key ID (the canonical key ID) corresponding to the certificate does not depend on the image name. If an images name matches more than one glob, then the most specific (longest) one is chosen.|
|`trust-pinning:library-images` | This option pins the official libraries (`docker.io/library/*`) to the hard-coded Docker official images root key. DCT trusts the official images by default. This is in addition to whatever images are specified by `trust-pinning:root-keys`. If `trustpinning:root-keys` specifies a key mapping for `docker.io/library/*`, those keys will be preferred for trust pinning. Otherwise, if a more general `docker.io/*` or `*` are specified, the official images key will be preferred.|
| `allow-expired-trust-cache` | Specifies whether cached locally expired metadata validates images if an external server is unreachable or does not have image trust metadata. This is necessary for machines which may be often offline, as may be the case for edge. This does not provide mitigations against freeze attacks, which is a necessary to provide availability in low-connectivity environments. |
| `mode` | Specifies whether DCT is enabled and enforced. Valid modes are: <br>
`disabled`: Verification is not active and the remainder of the content-trust related metadata will be ignored. *NOTE* that this is the default configuration if “mode” is not specfied. <br>
`permissive`: Verification will be performed, but only failures will only be logged and remain unenforced. This configuration is intended for testing of changes related to content-trust. <br>
`enforced`: DCT will be enforced and an image that cannot be verified successfully will not be pulled or run. |
***Note:*** The DCT configuration defined here is agnostic of any policy defined in
[UCP](https://docs.docker.com/v17.09/datacenter/ucp/2.0/guides/content-trust/#configure-ucp).
Images that can be deployed by the UCP trust policy but are disallowed by the Docker Engine
configuration will not successfully be deployed or run on that engine.
### Enable and disable DCT per-shell or per-invocation
Instead of enabling DCT through the system-wide configuration, DCT can be enabled or disabled
on a per-shell or per-invocation basis.
To enable on a per-shell basis, enable the `DOCKER_CONTENT_TRUST` environment variable.
Enabling per-shell is useful because you can have one shell configured for trusted operations
and another terminal shell for untrusted operations. You can also add this declaration to
your shell profile to have it enabled by default.
To enable DCT in a `bash` shell enter the following command:
```bash
export DOCKER_CONTENT_TRUST=1
@ -157,7 +207,7 @@ Once set, each of the "tag" operations requires a key for a trusted tag.
In an environment where `DOCKER_CONTENT_TRUST` is set, you can use the
`--disable-content-trust` flag to run individual operations on tagged images
without content trust on an as-needed basis.
without DCT on an as-needed basis.
Consider the following Dockerfile that uses an untrusted parent image:
@ -185,7 +235,7 @@ $ docker push --disable-content-trust <username>/nottrusttest:latest
...
```
To invoke a command with content trust enabled regardless of whether or how the `DOCKER_CONTENT_TRUST` variable is set:
To invoke a command with DCT enabled regardless of whether or how the `DOCKER_CONTENT_TRUST` variable is set:
```bash
$ docker build --disable-content-trust=false -t <username>/trusttest:testing .
@ -196,9 +246,9 @@ All of the trusted operations support the `--disable-content-trust` flag.
### Push trusted content
To create signed content for a specific image tag, simply enable content trust
To create signed content for a specific image tag, simply enable DCT
and push a tagged image. If this is the first time you have pushed an image
using content trust on your system, the session looks like this:
using DCT on your system, the session looks like this:
```bash
$ docker push <username>/trusttest:testing
@ -220,7 +270,7 @@ Repeat passphrase for new repository key with id docker.io/<username>/trusttest
Finished initializing "docker.io/<username>/trusttest"
```
When you push your first tagged image with content trust enabled, the `docker`
When you push your first tagged image with DCT enabled, the `docker`
client recognizes this is your first push and:
- alerts you that it is creating a new root key
@ -232,8 +282,8 @@ client recognizes this is your first push and:
The passphrase you chose for both the root key and your repository key-pair
should be randomly generated and stored in a *password manager*.
> **NOTE**: If you omit the `testing` tag, content trust is skipped. This is true
even if content trust is enabled and even if this is your first push.
> **NOTE**: If you omit the `testing` tag, DCT is skipped. This is true
even if DCT is enabled and even if this is your first push.
```bash
$ docker push <username>/trusttest
@ -245,7 +295,7 @@ No tag specified, skipping trust metadata push
```
It is skipped because as the message states, you did not supply an image `TAG`
value. In Docker content trust, signatures are associated with tags.
value. In DCT, signatures are associated with tags.
Once you have a root key on your system, subsequent images repositories
you create can use that same root key:
@ -269,7 +319,7 @@ these.
### Pull image content
A common way to consume an image is to `pull` it. With content trust enabled, the Docker
A common way to consume an image is to `pull` it. With DCT enabled, the Docker
client only allows `docker pull` to retrieve signed images. Let's try to pull the image
you signed and pushed earlier: