Adding (self signed) certificates

Hi,

I’d like to share an idea to configure the Daemon with own or self signed certificates.

Most forum posts more or less state that we currently cannot use self signed certificates (see Running an insecure registry --insecure-registry or Private docker registry with self signed certificate). I wonder if it would make sense to manually copy them into the Hyper-V VM like this:

  1. (on your host)
    move the certificates to a directory somewhere in /Users/.... We’ll be able to copy files from there into the VM as it will already be mounted by Docker.
  2. (on your host) attach to the TTY:
    screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
  3. (inside the vm) copy the certificates into the vm:
    mkdir -p /etc/docker/certs.d/mydomain.com:5000 && cp /Users/.../certs/domain.crt /etc/docker/certs.d/mydomain.com/ca.crt
  4. (inside the vm) restart Docker:
    service docker restart

AFAIK changes inside the VM will be removed when restarting the Docker.app. But would the idea work in general? I only had some minutes to give it a try, but only with CN=docker.local, which didn’t work, since it doesn’t seem to be resolved from inside the VM.

Any feedback is appreciated!

13 Likes

I run a private registry with a self-signed root CA that uses S3 as the storage backend with the default of doing a redirect enabled.

In addition to doing the above steps I also had to symlink the ca-certificates.crt file into the directory created in step 3 so that the default trusted certs are also available due to the redirect to the storage backend that occurs. Without this, the layers won’t actually download but retry for a few times and then move on to the next layer until all the layers have been tried and the pull will fail indicating it can’t find the image in the registry.

Here’s the command I used to fix this:

ln -s /etc/ssl/certs/ca-certificates.crt /etc/docker/certs.d/mydomain.com:5000/ca-certificates.crt

3 Likes

Hi,

I did so as Tobias suggested and I could push an image to a private TLS enabled registry.
Yes, after restarting Docker for Mac Beta I need to do the above steps again.

Thanks for the idea.

Oliver

2 Likes

When I try this I get prompted for a “docker login” and a password and I cannot get any further without the correct combination. Any idea what that is?

OS X: version 10.11.2 (build: 15C50)
Docker.app: version v1.11.0-beta9

User: root
Password none.

1 Like

I can confirm that this work around works. It would be great if this could be streamlined better or at least persisted between restarts

It can be streamlined a little bit by using a container with volumes/mounts to /User and /etc. Inside that container you can perform the cp command. You still need to reload the deamon afterwards, which means you still have to attach to the VM via screen :-/

Like mentioned above: you can use a container to copy from your host system into the Docker VM. This is how it worked for me: https://github.com/gesellix/inject-docker-certs

The linked project gives you:

  • a simple script to generate CA and server certificates
  • a docker image to perform the copy from your host into the VM

Interesting fact: I didn’t need to restart the Docker daemon anymore, so I’m not sure if that’s an improvement of the recently updated beta.

1 Like

I’ve tried to add the root certificate and the intermediate one, but it didn’t work, any ideas

@eslam do you have details?
The root certificate should be appended to /etc/ssl/certs/ca-certificates.crt, similar to what @metafour mentioned above. The intermediate cert should also be included in the certificate file you put into Docker’s .../certs.d/.../ directory.
What exactly didn’t work? Any error message?

Nice one! Thanks for sharing.

I can confirm that this workaround works on Docker for Mac:
Version 1.11.1-beta11 (build: 6974)
OS X El Capitan 10.11.4

I have two CA certs - one root and one intermediate CA for issuing the registry cert.

I had to put the root CA cert and the intermediate CA cert in the same file (the root first, if that makes a difference):
/etc/docker/certs.d/mydomain.com/ca.crt

1 Like

I’ve managed to get it working by just appending the root certificate and the intermediates to the end of /etc/ssl/certs/ca-certificates.crt file.

The only issue I’m trying to workaround is that this file is volatile, everytime I restart docker my appended content will be removed.

Any ideas

The only issue I’m trying to workaround is that this file is volatile, everytime I restart docker my appended content will be removed.

@eslam AFAIK that’s a constraint which cannot be solved at the moment. The maintainers know about that issue, but are probably working on getting other mainstream features completed. I guess that’s ok for a beta, and the containerized solution is a single command you could probably automate somehow - maybe there’s a OS X feature to automatically start another command after an application has been started?

In docker-toolbox, I used to add all the self-singed certificates in /var/lib/boot2docker/certs of the docker-machine I have and restart the docker-machine.
This doesn’t work for the current docker for mac.
However, I’ve kept my certificates and a small script “to append certificates and restart docker service” in /var/lib/boot2docker/certs dir.
I’ve restarted docker many times, certs and my script still there.
The weird issue is that I’ve to restart docker service, whereas I’m using the latest beta version 1.11.1

Thanks for documenting this – wanted to confirm that this works for me. Connecting to the Docker for Mac VM and being able to append my root certificate to /etc/ssl/certs/ca-certificates.crt worked like a charm!

Hope that the story for adding trusted certificates to Docker improves in the final release!

1 Like

I also found I didn’t need to restart the service… in fact when I’d try to restart it it would never succeed.

I ended up coming up with this bash script to automate the cert installation:

#!/bin/bash

# This assumes the cert is in the same directory as the script
source="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# You'll want to update this to reflect your repo's host and port
destination=/etc/docker/certs.d/example.net:1234

# Send a new line to wake it up, then login as root with a blank password
cat <<HERE > ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

root

HERE

# Give it a second to get logged in, copy the cert and log back out
cat <<HERE > ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
mkdir -p $destination
cp $source/My_Cert.crt $destination
exit

HERE
2 Likes

Do you mean the restart doesn’t work?

correct, it would never start back up.

This solution worked for me: https://github.com/klippx/inject-docker-certs

2 Likes