Merge pull request #1625 from moxiegirl/fix-1598
Updated per conversation with Richard
This commit is contained in:
commit
e90ff92895
3 changed files with 117 additions and 88 deletions
|
@ -8,83 +8,104 @@ keywords = ["registry, on-prem, images, tags, repository, distribution, insecure
|
||||||
|
|
||||||
# Insecure Registry
|
# Insecure Registry
|
||||||
|
|
||||||
While it's highly recommended to secure your registry using a TLS certificate issued by a known CA, you may alternatively decide to use self-signed certificates, or even use your registry over plain http.
|
While it's highly recommended to secure your registry using a TLS certificate
|
||||||
|
issued by a known CA, you may alternatively decide to use self-signed
|
||||||
|
certificates, or even use your registry over plain http.
|
||||||
|
|
||||||
You have to understand the downsides in doing so, and the extra burden in configuration.
|
You have to understand the downsides in doing so, and the extra burden in
|
||||||
|
configuration.
|
||||||
|
|
||||||
## Deploying a plain HTTP registry
|
## Deploying a plain HTTP registry
|
||||||
|
|
||||||
> **Warning**: it's not possible to use an insecure registry with basic authentication
|
> **Warning**: it's not possible to use an insecure registry with basic authentication.
|
||||||
|
|
||||||
This basically tells Docker to entirely disregard security for your registry.
|
This basically tells Docker to entirely disregard security for your registry.
|
||||||
|
While this is relatively easy to configure the daemon in this way, it is
|
||||||
|
**very** insecure. It does expose your registry to trivial MITM. Only use this
|
||||||
|
solution for isolated testing or in a tightly controlled, air-gapped
|
||||||
|
environment.
|
||||||
|
|
||||||
1. edit the file `/etc/default/docker` so that there is a line that reads: `DOCKER_OPTS="--insecure-registry myregistrydomain.com:5000"` (or add that to existing `DOCKER_OPTS`)
|
1. Open the `/etc/default/docker` file or `/etc/sysconfig/docker` for editing.
|
||||||
2. restart your Docker daemon: on ubuntu, this is usually `service docker stop && service docker start`
|
|
||||||
|
Depending on your operating system, your Engine daemon start options.
|
||||||
|
|
||||||
|
2. Edit (or add) the `DOCKER_OPTS` line and add the `--insecure-registry` flag.
|
||||||
|
|
||||||
|
This flag takes the URL of your registry, for example.
|
||||||
|
|
||||||
|
`DOCKER_OPTS="--insecure-registry myregistrydomain.com:5000"`
|
||||||
|
|
||||||
|
3. Close and save the configuration file.
|
||||||
|
|
||||||
|
4. Restart your Docker daemon
|
||||||
|
|
||||||
|
The command you use to restart the daemon depends on your operating system.
|
||||||
|
For example, on Ubuntu, this is usually the `service docker stop` and `service
|
||||||
|
docker start` command.
|
||||||
|
|
||||||
|
5. Repeat this configuration on every Engine host that wants to access your registry.
|
||||||
|
|
||||||
**Pros:**
|
|
||||||
|
|
||||||
- relatively easy to configure
|
|
||||||
|
|
||||||
**Cons:**
|
|
||||||
|
|
||||||
- this is **very** insecure: you are basically exposing yourself to trivial MITM, and this solution should only be used for isolated testing or in a tightly controlled, air-gapped environment
|
|
||||||
- you have to configure every docker daemon that wants to access your registry
|
|
||||||
|
|
||||||
## Using self-signed certificates
|
## Using self-signed certificates
|
||||||
|
|
||||||
> **Warning**: using this along with basic authentication requires to **also** trust the certificate into the OS cert store for some versions of docker (see below)
|
> **Warning**: using this along with basic authentication requires to **also** trust the certificate into the OS cert store for some versions of docker (see below)
|
||||||
|
|
||||||
Generate your own certificate:
|
This is more secure than the insecure registry solution. You must configure every docker daemon that wants to access your registry
|
||||||
|
|
||||||
|
1. Generate your own certificate:
|
||||||
|
|
||||||
mkdir -p certs && openssl req \
|
mkdir -p certs && openssl req \
|
||||||
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
|
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
|
||||||
-x509 -days 365 -out certs/domain.crt
|
-x509 -days 365 -out certs/domain.crt
|
||||||
|
|
||||||
Be sure to use the name `myregistrydomain.com` as a CN.
|
2. Be sure to use the name `myregistrydomain.com` as a CN.
|
||||||
|
|
||||||
Use the result to [start your registry with TLS enabled](https://github.com/docker/distribution/blob/master/docs/deploying.md#get-a-certificate)
|
3. Use the result to [start your registry with TLS enabled](https://github.com/docker/distribution/blob/master/docs/deploying.md#get-a-certificate)
|
||||||
|
|
||||||
Then you have to instruct every docker daemon to trust that certificate. This is done by copying the `domain.crt` file to `/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt`.
|
4. Instruct every docker daemon to trust that certificate.
|
||||||
|
|
||||||
Don't forget to restart docker after doing so.
|
This is done by copying the `domain.crt` file to `/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt`.
|
||||||
|
|
||||||
**Pros:**
|
5. Don't forget to restart the Engine daemon.
|
||||||
|
|
||||||
- more secure than the insecure registry solution
|
## Troubleshooting insecure registry
|
||||||
|
|
||||||
**Cons:**
|
This sections lists some common failures and how to recover from them.
|
||||||
|
|
||||||
- you have to configure every docker daemon that wants to access your registry
|
### Failing...
|
||||||
|
|
||||||
## Failing...
|
Failing to configure the Engine daemon and trying to pull from a registry that is not using
|
||||||
|
TLS will results in the following message:
|
||||||
Failing to configure docker and trying to pull from a registry that is not using TLS will result in the following message:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
FATA[0000] Error response from daemon: v1 ping attempt failed with error:
|
FATA[0000] Error response from daemon: v1 ping attempt failed with error:
|
||||||
Get https://myregistrydomain.com:5000/v1/_ping: tls: oversized record received with length 20527.
|
Get https://myregistrydomain.com:5000/v1/_ping: tls: oversized record received with length 20527.
|
||||||
If this private registry supports only HTTP or HTTPS with an unknown CA certificate,please add
|
If this private registry supports only HTTP or HTTPS with an unknown CA certificate,please add
|
||||||
`--insecure-registry myregistrydomain.com:5000` to the daemon's arguments.
|
`--insecure-registry myregistrydomain.com:5000` to the daemon's arguments.
|
||||||
In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag;
|
In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag;
|
||||||
simply place the CA certificate at /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
|
simply place the CA certificate at /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker still complains about the certificate when using authentication?
|
### Docker still complains about the certificate when using authentication?
|
||||||
|
|
||||||
When using authentication, some versions of docker also require you to trust the certificate at the OS level.
|
When using authentication, some versions of docker also require you to trust the certificate at the OS level. Usually, on Ubuntu this is done with:
|
||||||
|
|
||||||
Usually, on Ubuntu this is done with:
|
```bash
|
||||||
|
$ cp certs/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt
|
||||||
cp certs/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt
|
update-ca-certificates
|
||||||
update-ca-certificates
|
```
|
||||||
|
|
||||||
... and on Red Hat (and its derivatives) with:
|
... and on Red Hat (and its derivatives) with:
|
||||||
|
|
||||||
cp certs/domain.crt /etc/pki/ca-trust/source/anchors/myregistrydomain.com.crt
|
```bash
|
||||||
update-ca-trust
|
cp certs/domain.crt /etc/pki/ca-trust/source/anchors/myregistrydomain.com.crt
|
||||||
|
update-ca-trust
|
||||||
|
```
|
||||||
|
|
||||||
... On some distributions, e.g. Oracle Linux 6, the Shared System Certificates feature needs to be manually enabled:
|
... On some distributions, e.g. Oracle Linux 6, the Shared System Certificates feature needs to be manually enabled:
|
||||||
|
|
||||||
update-ca-trust enable
|
```bash
|
||||||
|
$ update-ca-trust enable
|
||||||
|
```
|
||||||
|
|
||||||
Now restart docker (`service docker stop && service docker start`, or any other way you use to restart docker).
|
Now restart docker (`service docker stop && service docker start`, or any other way you use to restart docker).
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
<!--[metadata]>
|
<!--[metadata]>
|
||||||
+++
|
+++
|
||||||
draft = true
|
title = "Image Manifest V 2, Schema 1 "
|
||||||
|
description = "image manifest for the Registry."
|
||||||
|
keywords = ["registry, on-prem, images, tags, repository, distribution, api, advanced, manifest"]
|
||||||
|
[menu.main]
|
||||||
|
parent="smn_registry_ref"
|
||||||
+++
|
+++
|
||||||
<![end-metadata]-->
|
<![end-metadata]-->
|
||||||
|
|
||||||
# Image Manifest Version 2, Schema 1
|
# Image Manifest Version 2, Schema 1
|
||||||
|
|
||||||
This document outlines the format of of the V2 image manifest. The image
|
This document outlines the format of of the V2 image manifest. The image
|
||||||
manifest described herein was introduced in the Docker daemon in the [v1.3.0
|
manifest described herein was introduced in the Docker daemon in the [v1.3.0
|
||||||
|
@ -25,9 +29,9 @@ signed manifest | "application/vnd.docker.distribution.manifest.v1+prettyjws"
|
||||||
|
|
||||||
*Note that "application/json" will also be accepted for schema 1.*
|
*Note that "application/json" will also be accepted for schema 1.*
|
||||||
|
|
||||||
References:
|
References:
|
||||||
|
|
||||||
- [Proposal: JSON Registry API V2.1](https://github.com/docker/docker/issues/9015)
|
- [Proposal: JSON Registry API V2.1](https://github.com/docker/docker/issues/9015)
|
||||||
- [Proposal: Provenance step 1 - Transform images for validation and verification](https://github.com/docker/docker/issues/8093)
|
- [Proposal: Provenance step 1 - Transform images for validation and verification](https://github.com/docker/docker/issues/8093)
|
||||||
|
|
||||||
## *Manifest* Field Descriptions
|
## *Manifest* Field Descriptions
|
||||||
|
@ -40,47 +44,47 @@ Manifest provides the base accessible fields for working with V2 image format
|
||||||
name is the name of the image's repository
|
name is the name of the image's repository
|
||||||
|
|
||||||
- **`tag`** *string*
|
- **`tag`** *string*
|
||||||
|
|
||||||
tag is the tag of the image
|
tag is the tag of the image
|
||||||
|
|
||||||
- **`architecture`** *string*
|
- **`architecture`** *string*
|
||||||
|
|
||||||
architecture is the host architecture on which this image is intended to
|
architecture is the host architecture on which this image is intended to
|
||||||
run. This is for information purposes and not currently used by the engine
|
run. This is for information purposes and not currently used by the engine
|
||||||
|
|
||||||
- **`fsLayers`** *array*
|
- **`fsLayers`** *array*
|
||||||
|
|
||||||
fsLayers is a list of filesystem layer blob sums contained in this image.
|
fsLayers is a list of filesystem layer blob sums contained in this image.
|
||||||
|
|
||||||
An fsLayer is a struct consisting of the following fields
|
An fsLayer is a struct consisting of the following fields
|
||||||
- **`blobSum`** *digest.Digest*
|
- **`blobSum`** *digest.Digest*
|
||||||
|
|
||||||
blobSum is the digest of the referenced filesystem image layer. A
|
blobSum is the digest of the referenced filesystem image layer. A
|
||||||
digest must be a sha256 hash.
|
digest must be a sha256 hash.
|
||||||
|
|
||||||
|
|
||||||
- **`history`** *array*
|
- **`history`** *array*
|
||||||
|
|
||||||
history is a list of unstructured historical data for v1 compatibility. It
|
history is a list of unstructured historical data for v1 compatibility. It
|
||||||
contains ID of the image layer and ID of the layer's parent layers.
|
contains ID of the image layer and ID of the layer's parent layers.
|
||||||
|
|
||||||
history is a struct consisting of the following fields
|
history is a struct consisting of the following fields
|
||||||
- **`v1Compatibility`** string
|
- **`v1Compatibility`** string
|
||||||
|
|
||||||
V1Compatibility is the raw V1 compatibility information. This will
|
V1Compatibility is the raw V1 compatibility information. This will
|
||||||
contain the JSON object describing the V1 of this image.
|
contain the JSON object describing the V1 of this image.
|
||||||
|
|
||||||
- **`schemaVersion`** *int*
|
- **`schemaVersion`** *int*
|
||||||
|
|
||||||
SchemaVersion is the image manifest schema that this image follows.
|
SchemaVersion is the image manifest schema that this image follows.
|
||||||
|
|
||||||
>**Note**:the length of `history` must be equal to the length of `fsLayers` and
|
>**Note**:the length of `history` must be equal to the length of `fsLayers` and
|
||||||
>entries in each are correlated by index.
|
>entries in each are correlated by index.
|
||||||
|
|
||||||
## Signed Manifests
|
## Signed Manifests
|
||||||
|
|
||||||
Signed manifests provides an envelope for a signed image manifest. A signed
|
Signed manifests provides an envelope for a signed image manifest. A signed
|
||||||
manifest consists of an image manifest along with an additional field
|
manifest consists of an image manifest along with an additional field
|
||||||
containing the signature of the manifest.
|
containing the signature of the manifest.
|
||||||
|
|
||||||
The docker client can verify signed manifests and displays a message to the user.
|
The docker client can verify signed manifests and displays a message to the user.
|
||||||
|
@ -88,10 +92,10 @@ The docker client can verify signed manifests and displays a message to the user
|
||||||
### Signing Manifests
|
### Signing Manifests
|
||||||
|
|
||||||
Image manifests can be signed in two different ways: with a *libtrust* private
|
Image manifests can be signed in two different ways: with a *libtrust* private
|
||||||
key or an x509 certificate chain. When signing with an x509 certificate chain,
|
key or an x509 certificate chain. When signing with an x509 certificate chain,
|
||||||
the public key of the first element in the chain must be the public key
|
the public key of the first element in the chain must be the public key
|
||||||
corresponding with the sign key.
|
corresponding with the sign key.
|
||||||
|
|
||||||
### Signed Manifest Field Description
|
### Signed Manifest Field Description
|
||||||
|
|
||||||
Signed manifests include an image manifest and a list of signatures generated
|
Signed manifests include an image manifest and a list of signatures generated
|
||||||
|
@ -99,7 +103,7 @@ by *libtrust*. A signature consists of the following fields:
|
||||||
|
|
||||||
|
|
||||||
- **`header`** *[JOSE](http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2)*
|
- **`header`** *[JOSE](http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2)*
|
||||||
|
|
||||||
A [JSON Web Signature](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html)
|
A [JSON Web Signature](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html)
|
||||||
|
|
||||||
- **`signature`** *string*
|
- **`signature`** *string*
|
||||||
|
@ -107,9 +111,9 @@ by *libtrust*. A signature consists of the following fields:
|
||||||
A signature for the image manifest, signed by a *libtrust* private key
|
A signature for the image manifest, signed by a *libtrust* private key
|
||||||
|
|
||||||
- **`protected`** *string*
|
- **`protected`** *string*
|
||||||
|
|
||||||
The signed protected header
|
The signed protected header
|
||||||
|
|
||||||
## Example Manifest
|
## Example Manifest
|
||||||
|
|
||||||
*Example showing the official 'hello-world' image manifest.*
|
*Example showing the official 'hello-world' image manifest.*
|
||||||
|
@ -159,5 +163,5 @@ by *libtrust*. A signature consists of the following fields:
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
<!--[metadata]>
|
<!--[metadata]>
|
||||||
+++
|
+++
|
||||||
draft = true
|
title = "Image Manifest V 2, Schema 2 "
|
||||||
|
description = "image manifest for the Registry."
|
||||||
|
keywords = ["registry, on-prem, images, tags, repository, distribution, api, advanced, manifest"]
|
||||||
|
[menu.main]
|
||||||
|
parent="smn_registry_ref"
|
||||||
+++
|
+++
|
||||||
<![end-metadata]-->
|
<![end-metadata]-->
|
||||||
|
|
||||||
|
@ -10,7 +14,7 @@ This document outlines the format of of the V2 image manifest, schema version 2.
|
||||||
The original (and provisional) image manifest for V2 (schema 1), was introduced
|
The original (and provisional) image manifest for V2 (schema 1), was introduced
|
||||||
in the Docker daemon in the [v1.3.0
|
in the Docker daemon in the [v1.3.0
|
||||||
release](https://github.com/docker/docker/commit/9f482a66ab37ec396ac61ed0c00d59122ac07453)
|
release](https://github.com/docker/docker/commit/9f482a66ab37ec396ac61ed0c00d59122ac07453)
|
||||||
and is specified in the [schema 1 manifest definition](./manifest-v2-1.md)
|
and is specified in the [schema 1 manifest definition](manifest-v2-1.md)
|
||||||
|
|
||||||
This second schema version has two primary goals. The first is to allow
|
This second schema version has two primary goals. The first is to allow
|
||||||
multi-architecture images, through a "fat manifest" which references image
|
multi-architecture images, through a "fat manifest" which references image
|
||||||
|
@ -40,7 +44,7 @@ image manifest based on the Content-Type returned in the HTTP response.
|
||||||
## *Manifest List* Field Descriptions
|
## *Manifest List* Field Descriptions
|
||||||
|
|
||||||
- **`schemaVersion`** *int*
|
- **`schemaVersion`** *int*
|
||||||
|
|
||||||
This field specifies the image manifest schema version as an integer. This
|
This field specifies the image manifest schema version as an integer. This
|
||||||
schema uses the version `2`.
|
schema uses the version `2`.
|
||||||
|
|
||||||
|
@ -54,21 +58,21 @@ image manifest based on the Content-Type returned in the HTTP response.
|
||||||
The manifests field contains a list of manifests for specific platforms.
|
The manifests field contains a list of manifests for specific platforms.
|
||||||
|
|
||||||
Fields of a object in the manifests list are:
|
Fields of a object in the manifests list are:
|
||||||
|
|
||||||
- **`mediaType`** *string*
|
- **`mediaType`** *string*
|
||||||
|
|
||||||
The MIME type of the referenced object. This will generally be
|
The MIME type of the referenced object. This will generally be
|
||||||
`application/vnd.docker.image.manifest.v2+json`, but it could also
|
`application/vnd.docker.image.manifest.v2+json`, but it could also
|
||||||
be `application/vnd.docker.image.manifest.v1+json` if the manifest
|
be `application/vnd.docker.image.manifest.v1+json` if the manifest
|
||||||
list references a legacy schema-1 manifest.
|
list references a legacy schema-1 manifest.
|
||||||
|
|
||||||
- **`size`** *int*
|
- **`size`** *int*
|
||||||
|
|
||||||
The size in bytes of the object. This field exists so that a client
|
The size in bytes of the object. This field exists so that a client
|
||||||
will have an expected size for the content before validating. If the
|
will have an expected size for the content before validating. If the
|
||||||
length of the retrieved content does not match the specified length,
|
length of the retrieved content does not match the specified length,
|
||||||
the content should not be trusted.
|
the content should not be trusted.
|
||||||
|
|
||||||
- **`digest`** *string*
|
- **`digest`** *string*
|
||||||
|
|
||||||
The digest of the content, as defined by the
|
The digest of the content, as defined by the
|
||||||
|
@ -153,7 +157,7 @@ image. It's the direct replacement for the schema-1 manifest.
|
||||||
## *Image Manifest* Field Descriptions
|
## *Image Manifest* Field Descriptions
|
||||||
|
|
||||||
- **`schemaVersion`** *int*
|
- **`schemaVersion`** *int*
|
||||||
|
|
||||||
This field specifies the image manifest schema version as an integer. This
|
This field specifies the image manifest schema version as an integer. This
|
||||||
schema uses version `2`.
|
schema uses version `2`.
|
||||||
|
|
||||||
|
@ -171,19 +175,19 @@ image. It's the direct replacement for the schema-1 manifest.
|
||||||
daemon side.
|
daemon side.
|
||||||
|
|
||||||
Fields of a config object are:
|
Fields of a config object are:
|
||||||
|
|
||||||
- **`mediaType`** *string*
|
- **`mediaType`** *string*
|
||||||
|
|
||||||
The MIME type of the referenced object. This should generally be
|
The MIME type of the referenced object. This should generally be
|
||||||
`application/vnd.docker.container.image.v1+json`.
|
`application/vnd.docker.container.image.v1+json`.
|
||||||
|
|
||||||
- **`size`** *int*
|
- **`size`** *int*
|
||||||
|
|
||||||
The size in bytes of the object. This field exists so that a client
|
The size in bytes of the object. This field exists so that a client
|
||||||
will have an expected size for the content before validating. If the
|
will have an expected size for the content before validating. If the
|
||||||
length of the retrieved content does not match the specified length,
|
length of the retrieved content does not match the specified length,
|
||||||
the content should not be trusted.
|
the content should not be trusted.
|
||||||
|
|
||||||
- **`digest`** *string*
|
- **`digest`** *string*
|
||||||
|
|
||||||
The digest of the content, as defined by the
|
The digest of the content, as defined by the
|
||||||
|
@ -194,19 +198,19 @@ image. It's the direct replacement for the schema-1 manifest.
|
||||||
The layer list is ordered starting from the base image (opposite order of schema1).
|
The layer list is ordered starting from the base image (opposite order of schema1).
|
||||||
|
|
||||||
Fields of an item in the layers list are:
|
Fields of an item in the layers list are:
|
||||||
|
|
||||||
- **`mediaType`** *string*
|
- **`mediaType`** *string*
|
||||||
|
|
||||||
The MIME type of the referenced object. This should
|
The MIME type of the referenced object. This should
|
||||||
generally be `application/vnd.docker.image.rootfs.diff.tar.gzip`.
|
generally be `application/vnd.docker.image.rootfs.diff.tar.gzip`.
|
||||||
|
|
||||||
- **`size`** *int*
|
- **`size`** *int*
|
||||||
|
|
||||||
The size in bytes of the object. This field exists so that a client
|
The size in bytes of the object. This field exists so that a client
|
||||||
will have an expected size for the content before validating. If the
|
will have an expected size for the content before validating. If the
|
||||||
length of the retrieved content does not match the specified length,
|
length of the retrieved content does not match the specified length,
|
||||||
the content should not be trusted.
|
the content should not be trusted.
|
||||||
|
|
||||||
- **`digest`** *string*
|
- **`digest`** *string*
|
||||||
|
|
||||||
The digest of the content, as defined by the
|
The digest of the content, as defined by the
|
||||||
|
|
Loading…
Reference in a new issue