Encrypt the docker remote API via TLS for Ubuntu and CentOS [Introduction] The Docker daemon can listen to Docker Remote API requests via three types of Socket: unix, tcp and fd. By default, a unix domain socket (or IPC socket) is created at /var/run/docker.sock, requiring either root permission, or docker group membership. Port 2375 is conventionally used for un-encrypted communition with Docker daemon remotely, where docker server can be accessed by any docker client via tcp socket in local area network. You can listen to port 2375 on all network interfaces with -H tcp://0.0.0.0:2375, where 0.0.0.0 means any available IP address on host, and tcp://0.0.0.0:2375 indicates that port 2375 is listened on any IP of daemon host. If we want to make docker server open on the Internet via TCP port, and only trusted clients have the right to access the docker server in a safe manner, port 2376 for encrypted communication with the daemon should be listened. It can be achieved to create certificate and distribute it to the trusted clients. Through creating self-signed certificate, and using --tlsverify command when running Docker daemon, Docker daemon opens the TLS authentication. Thus only the clients with related private key files can have access to the Docker daemon's server. As long as the key files for encryption are secure between docker server and client, the Docker daemon can keep secure. In summary, Firstly we should create docker server certificate and related key files, which are distributed to the trusted clients. Then the clients with related key files can access docker server. [Steps] 1.0. Create a CA, server and client keys with OpenSSL. OpenSSL is used to generate certificate, and can be installed as follows. apt-get install openssl openssl-devel 1.1 First generate CA private and public keys. openssl genrsa -aes256 -out ca-key.pem 4096 openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem You are about to be asked to enter information that will be incorporated into your certificate request, where the instance of $HOST should be replaced with the DNS name of your Docker daemon's host, here the DNS name of my Docker daemon is ly. Common Name (e.g. server FQDN or YOUR name) []:$HOST 1.2 Now we have a CA (ca-key.pem and ca.pem), you can create a server key and certificate signing request. openssl genrsa -out server-key.pem 4096 openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr 1.3 Sign the public key with our CA. TLS connections can be made via IP address as well as DNS name, they need to be specified when creating the certificate. echo subjectAltName = IP:172.16.10.121,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 1.4 For client authentication, create a client key and certificate signing request. openssl genrsa -out key.pem 4096 openssl req -subj '/CN=client' -new -key key.pem -out client.csr 1.5 To make the key suitable for client authentication, create an extensions config file. echo extendedKeyUsage = clientAuth > extfile.cnf 1.6 Sign the public key and after generating cert.pem and server-cert.pem, two certificate signing requests can be removed. openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \ -CAcreateserial -out cert.pem -extfile extfile.cnf 1.7 In order to protect your keys from accidental damage, you may change file modes to be only readable. chmod -v 0400 ca-key.pem key.pem server-key.pem chmod -v 0444 ca.pem server-cert.pem cert.pem 1.8 Build docker server dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \ -H=0.0.0.0:2376 Then, it can be seen from the command 'netstat -ntlp' that port 2376 has been listened and the Docker daemon only accept connections from clients providing a certificate trusted by our CA. 1.9 Distribute the keys to the client scp /etc/docker/ca.pem wwl@172.16.10.121:/etc/docker scp /etc/docker/cert.pem wwl@172.16.10.121:/etc/docker scp /etc/docker/key.pem wwl@172.16.10.121:/etc/docker Where, wwl and 172.16.10.121 is the username and IP of the client respectively. And the password of the client is needed when you distribute the keys to the client. 1.10 To access Docker daemon from the client via keys. docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \ -H=$HOST:2376 version Then we can operate docker in the Docker daemon from the client vis keys, for example: 1) create container from the client docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 run -d \ -it --name w1 grafana/grafana 2) list containers from the client docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 pa -a 3) stop/start containers from the client docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 stop w1 docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 start w1