Machine: How do I pull from a private self-signed Docker registry without TLS verification errors?

Created on 17 Sep 2015  路  18Comments  路  Source: docker/machine

Host OS: OS X 10.10.5
Docker-Machine: 0.4.1
Docker: 1.8.1

My team is running a private Docker registry with a self-signed SSL certificate. I added the certificate to my root store in OS X and I can connect to with Google Chrome without any TLS verification issues. However, when I try to perform a docker pull from that registry I get a x509: certificate signed by unknown authority. I restarted my docker-machine after adding that certificate to my OS X root store. I would've expected that having the certificate in my root store would've been sufficient for TLS verification. There also doesn't seem to be any documentation as to how to add that certificate in the docker-machine VM as a trusted one. I also do not have access to the private key for the certificate.

areidentity

Most helpful comment

+1
I'd love to be able to add a --engine-registry-cert option to the docker-machine create command.

All 18 comments

The VM does not have any way of knowing about the OSX root store as far as I'm aware.

Would this work for you: https://github.com/docker/machine/issues/1803 ?

It's fine if the VM doesn't pick up those certs as long there is documentation around how to get certs into the VM.

The instructions outlined in that issue don't work for me. Specifically I get a Permission denied error when attempting to scp the certificate into the VM when I have read access to the file on the host. I tried following the instructions that issue references (scp-ing into tmp, then ssh-ing in and copying it into the certs directory, then restarting the vm), I re-env'd to set the appropriate environment variables for the restarted VM but I'm still seeing x509: certificate signed by unknown authority. I've confirmed the certificate is present in /var/lib/boot2docker/certs after rebooting.

I found the simplest way was to append it to /etc/ssl/certs/ca-certificates.crt

The docs fro setting up self-signed certs mention that you should add the cert to /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
I ssh'd into the machine and did that; private registry is working. Would it be feasible to add a command (or an option) to do this?
link to the docs

I ssh'd into the machine and did that; private registry is working. Would it be feasible to add a command (or an option) to do this?

I'm interested -- possibly a --engine-registry-cert which would add the cert to the proper place during provisioning.

+1

I need to manually copy the cert to the right place every time the VM is restarted so this would be a great help.

+1. Docker-machine is a nightmare to use with a private docker repo. Restarting the VM appears to require the reinstallation of the cert via SCP and SSH (see earlier workaround). Can we have a fix for this? How are people working around this?

Also, when using docker-machine inspect I see a lot of AuthOptions configuration bindings. Does anybody know where these are documented? Can these be magic runes be configured in some way such that with a public certificate that resides on my host (i.e MacOS in my case) the docker instances running inside the vm will be able to leverage the cert and successfully authenticate with the private docker registry?

In the meantime, you can create your docker-machine with the --engine-insecure-registry flag.
Note that you have to add the flag before you specify the name of your machine. i.e. docker-machine create -d virtualbox --engine-insecure-registry myregistry:5000 dev

Here's one example of a script to trust custom CAs in the created VM for reference: https://gist.github.com/metcalfc/50060709ee9d22ec620e

I do want to support this first-class eventually with something like https://github.com/docker/machine/issues/2247

Taken from https://github.com/docker/docker/issues/9118 :

I made it (doing docker login https://the-domain:5043 on my Mac) working by using the --insecure-registry option. In Docker daemon machine I had to append following to /var/lib/boot2docker/profile

EXTRA_ARGS="$EXTRA_ARGS --insecure-registry https://the-domain:5043"

Unlike suggested by Docker daemon, it didn't work without https written in that line.

+1
I'd love to be able to add a --engine-registry-cert option to the docker-machine create command.

+1 for 鈥攅ngine-registry-cert option.

+1
It is difficult to work with docker machine without a option like this.

+1 for 鈥攅ngine-registry-cert

Moreover, the /etc/docker/certs.d/myregistry:5000/myregistry.crt persists across docker-machine reload for me, however it would be really great to have that option)
Regarding --insecure-registry option, unfortunately this approach doesn't support basic authentication

On Ubuntu. If you experience error:

  • x509: cannot validate certificate for [IP address or domain name] because it doesn't contain any IP SANs

On the Docker registry the certificate had to be compiled with the subjectAltName as described here:
https://docs.docker.com/engine/security/https/

Here is the code for convenience:

$ echo subjectAltName = IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.pem -extfile extfile.cnf

Note, I was able to check the subject alternative name is present in the certificate using the following command:

openssl x509 -in certificate.crt -text -noout

However, on Ubuntu 14 client (i.e. Docker Engine)
This error was followed suit by

x509: certificate signed by unknown authority

For people using Ubuntu 14.
The config file that is used for the Docker engine (that I want to use to connect to the Docker Registry): /etc/default/docker

in there, you need to specify the docker options:

DOCKER_OPTS="--insecure-registry myinsecure.com:5000" 

Then restart the daemon (add sudo if you user is not allowed to start a docker service):

$ [sudo] service docker restart

The value does not need to be a domain name, it simply has to match what you certificate is registered with; I have an IP address with a port and this works... (i.e. e.g. 100.100.100.100:100)

All this took me a day, so, I am posting this hoping that it will be useful to other people...

Was this page helpful?
0 / 5 - 0 ratings