Updated per conversation with Richard
Removing draft Richard's comments and some fixes Signed-off-by: Mary Anthony <mary@docker.com>master
							parent
							
								
									c6f63e298e
								
							
						
					
					
						commit
						6bce49d51d
					
				|  | @ -8,83 +8,104 @@ keywords = ["registry, on-prem, images, tags, repository, distribution, insecure | |||
| 
 | ||||
| # 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 | ||||
| 
 | ||||
| > **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. | ||||
| 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`) | ||||
| 2. restart your Docker daemon: on ubuntu, this is usually `service docker stop && service docker start` | ||||
| 1. Open the `/etc/default/docker` file or `/etc/sysconfig/docker` for editing. | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
| > **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 \ | ||||
|       -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \ | ||||
|       -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 docker and trying to pull from a registry that is not using TLS will result in the following message: | ||||
| Failing to configure the Engine daemon and trying to pull from a registry that is not using | ||||
| TLS will results in the following message: | ||||
| 
 | ||||
| ``` | ||||
| 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.  | ||||
| If this private registry supports only HTTP or HTTPS with an unknown CA certificate,please add  | ||||
| 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 | ||||
| `--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; | ||||
| 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: | ||||
| 
 | ||||
|     cp certs/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt | ||||
|     update-ca-certificates | ||||
| ```bash | ||||
| $ cp certs/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt | ||||
| update-ca-certificates | ||||
| ``` | ||||
| 
 | ||||
| ... and on Red Hat (and its derivatives) with: | ||||
| 
 | ||||
|     cp certs/domain.crt /etc/pki/ca-trust/source/anchors/myregistrydomain.com.crt | ||||
|     update-ca-trust | ||||
| ```bash | ||||
| 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: | ||||
| 
 | ||||
|     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). | ||||
|  |  | |||
|  | @ -1,10 +1,14 @@ | |||
| <!--[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]--> | ||||
| 
 | ||||
| # 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 | ||||
| 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.* | ||||
| 
 | ||||
| References:  | ||||
|   | ||||
|  - [Proposal: JSON Registry API V2.1](https://github.com/docker/docker/issues/9015)  | ||||
| References: | ||||
| 
 | ||||
|  - [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) | ||||
| 
 | ||||
| ## *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 | ||||
| 
 | ||||
| - **`tag`** *string* | ||||
| 	 | ||||
| 
 | ||||
| 	tag is the tag of the image | ||||
| 	 | ||||
| 
 | ||||
| - **`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 | ||||
|     | ||||
| 
 | ||||
| - **`fsLayers`** *array* | ||||
|     | ||||
| 
 | ||||
|    fsLayers is a list of filesystem layer blob sums contained in this image. | ||||
|     | ||||
| 
 | ||||
|    An fsLayer is a struct consisting of the following fields | ||||
|       - **`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. | ||||
|   | ||||
|     | ||||
| 
 | ||||
| 
 | ||||
| - **`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. | ||||
|     | ||||
| 
 | ||||
|    history is a struct consisting of the following fields | ||||
|    - **`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. | ||||
|        | ||||
| 
 | ||||
| - **`schemaVersion`** *int* | ||||
| 	 | ||||
| 
 | ||||
|    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. | ||||
| 
 | ||||
| ## Signed Manifests | ||||
| 
 | ||||
| Signed manifests provides an envelope for a signed image manifest.  A signed  | ||||
| manifest consists of an image manifest along with an additional field  | ||||
| Signed manifests provides an envelope for a signed image manifest.  A signed | ||||
| manifest consists of an image manifest along with an additional field | ||||
| containing the signature of the manifest. | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
| 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,  | ||||
|  the public key of the first element in the chain must be the public key  | ||||
|  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 | ||||
|  corresponding with the sign key. | ||||
|     | ||||
| 
 | ||||
| ### Signed Manifest Field Description | ||||
| 
 | ||||
| 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)* | ||||
|     | ||||
| 
 | ||||
|    A [JSON Web Signature](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html) | ||||
| 
 | ||||
| - **`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 | ||||
| 
 | ||||
| - **`protected`** *string* | ||||
| 	 | ||||
| 
 | ||||
| 	The signed protected header | ||||
| 	 | ||||
| 
 | ||||
| ## Example 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]> | ||||
| +++ | ||||
| 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]--> | ||||
| 
 | ||||
|  | @ -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 | ||||
| in the Docker daemon in the [v1.3.0 | ||||
| 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 | ||||
| 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 | ||||
| 
 | ||||
| - **`schemaVersion`** *int* | ||||
| 	 | ||||
| 
 | ||||
|   This field specifies the image manifest schema version as an integer. This | ||||
|   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. | ||||
| 
 | ||||
|     Fields of a object in the manifests list are: | ||||
|      | ||||
| 
 | ||||
|     - **`mediaType`** *string* | ||||
|      | ||||
| 
 | ||||
|         The MIME type of the referenced object. This will generally be | ||||
|         `application/vnd.docker.image.manifest.v2+json`, but it could also | ||||
|         be `application/vnd.docker.image.manifest.v1+json` if the manifest | ||||
|         list references a legacy schema-1 manifest. | ||||
|      | ||||
| 
 | ||||
|     - **`size`** *int* | ||||
|      | ||||
| 
 | ||||
|         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 | ||||
|         length of the retrieved content does not match the specified length, | ||||
|         the content should not be trusted. | ||||
|      | ||||
| 
 | ||||
|     - **`digest`** *string* | ||||
| 
 | ||||
|         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 | ||||
| 
 | ||||
| - **`schemaVersion`** *int* | ||||
| 	 | ||||
| 
 | ||||
|   This field specifies the image manifest schema version as an integer. This | ||||
|   schema uses version `2`. | ||||
| 
 | ||||
|  | @ -171,19 +175,19 @@ image. It's the direct replacement for the schema-1 manifest. | |||
|     daemon side. | ||||
| 
 | ||||
|     Fields of a config object are: | ||||
|      | ||||
| 
 | ||||
|     - **`mediaType`** *string* | ||||
|      | ||||
| 
 | ||||
|         The MIME type of the referenced object. This should generally be | ||||
|         `application/vnd.docker.container.image.v1+json`. | ||||
|      | ||||
| 
 | ||||
|     - **`size`** *int* | ||||
|      | ||||
| 
 | ||||
|         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 | ||||
|         length of the retrieved content does not match the specified length, | ||||
|         the content should not be trusted. | ||||
|      | ||||
| 
 | ||||
|     - **`digest`** *string* | ||||
| 
 | ||||
|         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). | ||||
| 
 | ||||
|     Fields of an item in the layers list are: | ||||
|      | ||||
| 
 | ||||
|     - **`mediaType`** *string* | ||||
|      | ||||
| 
 | ||||
|         The MIME type of the referenced object. This should | ||||
|         generally be `application/vnd.docker.image.rootfs.diff.tar.gzip`. | ||||
|      | ||||
| 
 | ||||
|     - **`size`** *int* | ||||
|      | ||||
| 
 | ||||
|         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 | ||||
|         length of the retrieved content does not match the specified length, | ||||
|         the content should not be trusted. | ||||
|      | ||||
| 
 | ||||
|     - **`digest`** *string* | ||||
| 
 | ||||
|         The digest of the content, as defined by the | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue