Can an insecure docker registry be given a CA signed certificate so that clients automatically trust it?

1.3k views Asked by At

Currently, I have set up a registry in the following manner:

docker run -d \
  -p 10.0.1.4:443:5000 \
  --name registry \
  -v `pwd`/certs/:/certs \
  -v `pwd`/registry:/var/lib/registry \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/certificate.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/private.key \
  registry:latest

Using Docker version 17.06.2-ce, build cec0b72

I have obtained my certificate.crt, private.key, and ca_bundle.crt from Let's Encrypt. And I have been able to establish https connections when using these certs on a nginx server, without having to explicitly trust the certificates on the client machine/browser.

Is it possible to setup a user experience with a docker registry similar to that of a CA certified website being accessed via https, where the browser/machine trusts the root CA and those along the chain, including my certificates?

Note:

I can of course specify the certificate in the clients docker files as described in this tutorial: https://docs.docker.com/registry/insecure/#use-self-signed-certificates . However, this is not an adequate solution for my needs.

Output of curl -v https://docks.behar.cloud/v2/:

*   Trying 10.0.1.4...
* TCP_NODELAY set
* Connected to docks.behar.cloud (10.0.1.4) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: docks.behar.cloud
* Server certificate: Let's Encrypt Authority X3
* Server certificate: DST Root CA X3
> GET /v2/ HTTP/1.1
> Host: docks.behar.cloud
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Length: 2
< Content-Type: application/json; charset=utf-8
< Docker-Distribution-Api-Version: registry/2.0
< X-Content-Type-Options: nosniff
< Date: Sun, 10 Sep 2017 23:05:01 GMT
< 
* Connection #0 to host docks.behar.cloud left intact

Short answer: Yes. My issue was caused by my os not having a build in trust of the root certificates from which my SSL certificate was signed by. This is likely due to the age of my os. See the answer from Matt for more information.

2

There are 2 answers

5
Matt On BEST ANSWER

Docker will normally use the the OS provided CA bundle, so certificates signed by trusted roots should work without extra config.

Let's Encrypt certificates are cross signed by an IdentTrust root certificate (DST Root CA X3) so most CA bundles should already trust their certificates. The Lets Encrypt root cert (ISRG Root X1) is also distributed but will not be as widespread due to it being more recent.

Docker 1.13+ will use the host systems CA bundle to verify certificates. Prior to 1.13 this may not happen if you have installed a custom root cert. So if you use curl without any TLS warning then docker commands should also work the same.

2
GHETTO.CHiLD On

To have DTR recognize the certificates you need to edit the configuration file so that you specify your certs correctly. DTR accepts and has special parameters for LetsEncrypt Certs. They also have specific requirements for them. You will need to make a configuration file and mount the appropriate directories and then there should be no further issues with insecure-registry errors and unrecognized certs.

...
http:
  addr: localhost:5000
  prefix: /my/nested/registry/
  host: https://myregistryaddress.org:5000
  secret: asecretforlocaldevelopment
  relativeurls: false
  tls:
    certificate: /path/to/x509/public
    key: /path/to/x509/private
    clientcas:
      - /path/to/ca.pem
      - /path/to/another/ca.pem
    letsencrypt:
      cachefile: /path/to/cache-file
      email: [email protected]
    ...