Docker TLS encrypted connection

Securing your Docker connection with SSL certificates Posted by Joost Faassen on 2016-04-09

This is a short summary of Protect the Docker daemon socket from the official Docker documentation

Observations:

Conventions

Create a CA

You'll first need to create a CA (Certificate Authority) for your Docker servers and clients. A CA (in short) is simply a top-level certificate that will be used to sign all CSR's, and is trusted by all servers and clients.

Create a directory for your CA:

mkdir ~/dockerca
cd ~/dockerca

Generate the private key for your CA ca.key:

openssl genrsa -aes256 -out ca.key 4096

You'll be asked to enter a passphrase. This is required.

Create a public key ca.pem for your CA, based on it's private key ca.key:

openssl req -new -x509 -days 365 -key ca.key -sha256 -out ca.pem

You'll be asked several questions (like Country, State/Province, Locality/City, Organization Name and Unit, Email).

You can either choose to accept the defaults, leave them empty, or enter any value applicable to you. These values will be embedded in the public key, but are not relevant for TLS to work correctly.

EXCEPT for one value Common Name, enter the public hostname for which you want your Docker daemon to be accessible.

Create a key and CSR for your Docker server

Replace the example docker1.example.com below for your own servername. IMPORTANT Make sure they match the hostname you will use to connect to your Docker daemon.

openssl genrsa -out docker1.example.com.key 4096
openssl req -subj "/CN=docker1.example.com" -sha256 -new -key docker1.example.com.key -out docker1.example.com.csr

Sign the server CSR with your CA

First, create a new extfile.cnf containing the IP addresses of your Docker server:

echo subjectAltName = IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf

Next, we'll sign the CSR using the CA:

openssl x509 -req -days 365 -sha256 -in docker1.example.com.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out docker1.example.com.pem -extfile extfile.cnf

Configure the daemon to use TLS (Ubuntu)

On the Docker host, create a new directory called /etc/docker/ssl, and put the following files in there:

Edit /etc/default/docker, and add the following parameters to DOCKER_OPTS

DOCKER_OPTS="--tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/docker1.example.com.pem --tlskey=/etc/docker/ssl/docker1.example.com.key -H=0.0.0.0:2376"

Then restart the docker service:

service docker restart

Create a client key-pair:

Generate a client key and csr:

openssl genrsa -out client.key 4096
openssl req -subj '/CN=client' -new -key client.key -out client.csr
echo extendedKeyUsage = clientAuth > extfile.cnf

Sign the client CSR with your CA

openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client.pem -extfile extfile.cnf

Connect:

docker --tlsverify --tlscacert=ca.pem --tlscert=client.pem --tlskey=client.key -H=docker1.example.com:2376 version

Automatically connect using TLS

You can create a ~/.docker directory on your client machine, and copy certificates there following a strict filename convention:

mkdir -pv ~/.docker
cp ca.pem ~/.docker/ca.pem
cp client.pem ~/.docker/cert.pem
cp client.key ~/.docker/key.pem

Then set the DOCKER_HOST and DOCKER_TLS_VERIFY environment variables:

export DOCKER_HOST=tcp://docker1.example.com:2376 DOCKER_TLS_VERIFY=1

You can now simply run:

docker version