Remote access to Docker with TLS
17 May 2014By default Docker is available only on UNIX socket. Because UNIX sockets cannot be forwarded through SSH, you generally had 3 options:
- Hack nginx to forward traffic to Docker
- Use SSH and socat to tunnel connection
- Make Docker daemon listen on exposed port
1st solution is really cumbersome to setup. 2nd requires socat installed on both server and client. 3rd is not secure and anyone can connect or intercept Docker traffic as connection is not encrypted.
The situation was hopeless until Docker implemented TLS auth in 0.10.
I present few simple steps to setup it:
I. Generate your certificates
You need to generate 3 kinds of certificates:
- CA certificate used for generating client and server certs
- Client certificate used by remote Docker client
- Server certificate used by Docker daemon on server
I wrote a little Ruby script that generates all three certificates for you. All you need to do is clone this repository and run following commands:
$ gem install certificate_authority
$ ruby certgen.rb example.com
CA certificates are in ~/.docker/ca
Client certificates are in ~/.docker
Server certificates are in ~/.docker/example.com
Certificates should be now available under ~/.docker
path.
II. Copy server certificates to remote location
The script generated keys and certificates required by Docker daemon ~/.docker/example.com
(example.com is your domain name).
Copy them on your server to ~/.docker
directory:
rsync -ave ssh ~/.docker/example.com/ root@example.com:~/.docker/
III. Configure Docker on remote location
Docker daemon since version 0.10 supports --tlsverify
mode that enforces encrypted and authenticated remote connections.
I assume you’re using Ubuntu 12.04 LTS with Docker already installed and running. Instructions for other distros may be little different.
All you need to do is add following line to /etc/default/docker
:
DOCKER_OPTS="--tlsverify -H=unix:///var/run/docker.sock -H=0.0.0.0:4243 --tlscacert=/root/.docker/ca.pem --tlscert=/root/.docker/cert.pem --tlskey=/root/.docker/key.pem"
And restart Docker daemon with:
service docker restart
If something went wrong Docker daemon won’t start again. You can debug it by browsing logs under /var/log/upstart/docker.log
.
That’s it!
You can connect to remote Docker instance using --tlsverify
flag:
docker --tlsverify -H tcp://example.com:4243 images
It will use certificates stored in ~/.docker
. To use different ones, you can use --tls*
options listed in docker --help
and documentation.
The official guide of TLS setup can be found on Docker site.