Securely setup Docker on linux server

Airplane arriving at Boston Logan

This tutorial demonstrates how to setup docker by using tls certs, and the client can connect with the ssl certs securely.

Install Docker

sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo apt-key fingerprint 0EBFCD88

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs) stable"

sudo apt update && sudo apt-get install docker-ce docker-ce-cli containerd.io

Permission setup

sudo groupadd docker

sudo usermod -aG docker $USER

Change the docker image store directory

in /etc/docker/daemon.json
{
    "data-root": "/YOU-DATA-FOLDER",
    "storage-driver": "overlay"
}

Secure the docker daemon socket

on server side

After installed the docker on Ubuntu, you can check that the docker process runs through a Unix socket locally by running the command:

$ ps -ef | grep docker
root 10760     1  0 21:23 ?  00:00:03 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

The docker service config file define like this:

$ less /lib/systemd/system/docker.service
[Service]
...
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

You can make some configuration changes to have docker communicate via an HTTP socket:

$ sudo vim /lib/systemd/system/docker.service
[Service]
...
ExecStart=/usr/bin/dockerd

Create new file /etc/docker/daemon.json

{
    "tlsverify": true,
    "tlscacert": "/etc/docker/staging.ttllawfirm.memodir.com/ca.pem",
    "tlscert"  : "/etc/docker/staging.ttllawfirm.memodir.com/server-cert.pem",
    "tlskey"   : "/etc/docker/staging.ttllawfirm.memodir.com/server-key.pem",
    "hosts"    : ["fd://", "tcp://0.0.0.0:2376"],
}

restart the service:

sudo systemctl daemon-reload
sudo service docker restart

on client side:

mkdir ~/.docker/staging.ttlawfirm.memodir.com
cp ca.pem cert.pem key.pem ~/.docker/staging.ttllawfirm.memodir.com

vim ~/.docker/env.staging.ttllawfirm.memodir.com
# add the following env vars
export DOCKER_HOST=tcp://staging.ttllawfirm.memodir.com:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=~/.docker/staging.ttllawfirm.memodir.com/

On the client side, activate the config by:

source ~/.docker/env.staging.ttllawfirm.memodir.com

The docker client can access server:

$ docker -H=$HOST:2376 version

!Remember open 2376 port on the cloud server!

When you connect to your docker server via the plain TCP, you are risking the serious security issues. Because any one can manipulate your docker engine without any authentication, even docker engine is running with the root privilege.

If you really need your docker server to be accessed through the network, you need take care of the security by enabling TLS, after speficy the tlsverify flag and config the trusted CA certification, the docker server in daemon mode only allows the connection from client authenticated by the certificate signed by that trusted CA certification.