Add script to enable Docker Remote API by updating Docker Daemon configuration
authorhelenyao <yaohelan@huawei.com>
Fri, 11 Nov 2016 02:08:02 +0000 (21:08 -0500)
committerhelenyao <yaohelan@huawei.com>
Fri, 11 Nov 2016 03:24:24 +0000 (22:24 -0500)
JIRA: FUNCTEST-520

This script will be used once the docker slicing decide is made.
Currently, the script has been tested on Ubuntu 14.04 and 16.04
and CentOS 7.2. A document about how to enable TLS is included
when taking security into account.

Change-Id: I4e5e58ed68d75528bf8497aba118f9dbb51dddad
Signed-off-by: helenyao <yaohelan@huawei.com>
docker/docker_remote_api/docs/TLS-intro.rst [new file with mode: 0644]
docker/docker_remote_api/enable_remote_api.sh [new file with mode: 0644]

diff --git a/docker/docker_remote_api/docs/TLS-intro.rst b/docker/docker_remote_api/docs/TLS-intro.rst
new file mode 100644 (file)
index 0000000..934f99a
--- /dev/null
@@ -0,0 +1,107 @@
+Encrypt the docker remote API via TLS for Ubuntu and CentOS\r
+\r
+[Introduction]\r
+The Docker daemon can listen to Docker Remote API requests via three types of\r
+Socket: unix, tcp and fd. By default, a unix domain socket (or IPC socket) is\r
+created at /var/run/docker.sock, requiring either root permission, or docker\r
+group membership.\r
+\r
+Port 2375 is conventionally used for un-encrypted communition with Docker daemon\r
+remotely, where docker server can be accessed by any docker client via tcp socket\r
+in local area network. You can listen to port 2375 on all network interfaces with\r
+-H tcp://0.0.0.0:2375, where 0.0.0.0 means any available IP address on host, and\r
+tcp://0.0.0.0:2375 indicates that port 2375 is listened on any IP of daemon host.\r
+If we want to make docker server open on the Internet via TCP port, and only trusted\r
+clients have the right to access the docker server in a safe manner, port 2376 for\r
+encrypted communication with the daemon should be listened. It can be achieved to\r
+create certificate and distribute it to the trusted clients.\r
+\r
+Through creating self-signed certificate, and using --tlsverify command when running\r
+Docker daemon, Docker daemon opens the TLS authentication. Thus only the clients\r
+with related private key files can have access to the Docker daemon's server. As\r
+long as the key files for encryption are secure between docker server and client,\r
+the Docker daemon can keep secure.\r
+In summary,\r
+Firstly we should create docker server certificate and related key files, which\r
+are distributed to the trusted clients.\r
+Then the clients with related key files can access docker server.\r
+\r
+[Steps]\r
+1.0. Create a CA, server and client keys with OpenSSL.\r
+    OpenSSL is used to generate certificate, and can be installed as follows.\r
+    apt-get install openssl openssl-devel\r
+\r
+1.1 First generate CA private and public keys.\r
+    openssl genrsa -aes256 -out ca-key.pem 4096\r
+    openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem\r
+\r
+    You are about to be asked to enter information that will be incorporated\r
+    into your certificate request, where the instance of $HOST should be replaced\r
+    with the DNS name of your Docker daemon's host, here the DNS name of my Docker\r
+    daemon is ly.\r
+       Common Name (e.g. server FQDN or YOUR name) []:$HOST\r
+\r
+1.2 Now we have a CA (ca-key.pem and ca.pem), you can create a server key and\r
+certificate signing request.\r
+    openssl genrsa -out server-key.pem 4096\r
+    openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr\r
+\r
+1.3 Sign the public key with our CA.\r
+    TLS connections can be made via IP address as well as DNS name, they need to be\r
+    specified when creating the certificate.\r
+\r
+    echo subjectAltName = IP:172.16.10.121,IP:127.0.0.1 > extfile.cnf\r
+    openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \\r
+    -CAcreateserial -out server-cert.pem -extfile extfile.cnf\r
+\r
+1.4 For client authentication, create a client key and certificate signing request.\r
+    openssl genrsa -out key.pem 4096\r
+    openssl req -subj '/CN=client' -new -key key.pem -out client.csr\r
+\r
+1.5 To make the key suitable for client authentication, create an extensions config file.\r
+    echo extendedKeyUsage = clientAuth > extfile.cnf\r
+\r
+1.6 Sign the public key and after generating cert.pem and server-cert.pem, two certificate\r
+    signing requests can be removed.\r
+    openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \\r
+    -CAcreateserial -out cert.pem -extfile extfile.cnf\r
+\r
+1.7 In order to protect your keys from accidental damage, you may change file modes to\r
+    be only readable.\r
+    chmod -v 0400 ca-key.pem key.pem server-key.pem\r
+    chmod -v 0444 ca.pem server-cert.pem cert.pem\r
+\r
+1.8 Build docker server\r
+    dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \\r
+    -H=0.0.0.0:2376\r
+    Then, it can be seen from the command 'netstat -ntlp' that port 2376 has been listened\r
+    and the Docker daemon only accept connections from clients providing a certificate\r
+    trusted by our CA.\r
+\r
+1.9 Distribute the keys to the client\r
+    scp /etc/docker/ca.pem wwl@172.16.10.121:/etc/docker\r
+    scp /etc/docker/cert.pem wwl@172.16.10.121:/etc/docker\r
+    scp /etc/docker/key.pem wwl@172.16.10.121:/etc/docker\r
+    Where, wwl and 172.16.10.121 is the username and IP of the client respectively.\r
+    And the password of the client is needed when you distribute the keys to the client.\r
+\r
+1.10 To access Docker daemon from the client via keys.\r
+    docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \\r
+    -H=$HOST:2376 version\r
+\r
+    Then we can operate docker in the Docker daemon from the client vis keys, for example:\r
+    1) create container from the client\r
+    docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 run -d \\r
+    -it --name w1 grafana/grafana\r
+    2) list containers from the client\r
+    docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 pa -a\r
+    3) stop/start containers from the client\r
+    docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 stop w1\r
+    docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 start w1\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/docker/docker_remote_api/enable_remote_api.sh b/docker/docker_remote_api/enable_remote_api.sh
new file mode 100644 (file)
index 0000000..6867eed
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/bash\r
+# SPDX-license-identifier: Apache-2.0\r
+\r
+# ******************************\r
+# Script to update the docker host configuration\r
+# to enable Docker Remote API\r
+# ******************************\r
+\r
+if [ -f /etc/lsb-release ]; then\r
+    #tested on ubuntu 14.04 and 16.04\r
+    if grep -q "#DOCKER_OPTS=" "/etc/default/docker"; then\r
+        cp /etc/default/docker /etc/default/docker.bak\r
+        sed -i 's/^#DOCKER_OPTS.*$/DOCKER_OPTS=\"-H unix:\/\/\/var\/run\/docker.sock -H tcp:\/\/0.0.0.0:2375\"/g' /etc/default/docker\r
+    else\r
+        echo DOCKER_OPTS=\"-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375\" >> /etc/default/docker\r
+    fi\r
+    service docker restart\r
+    #docker start $(docker ps -aq)\r
+elif [ -f /etc/system-release ]; then\r
+        #tested on centos 7.2\r
+    if grep -q "ExecStart=\/usr\/bin\/docker-current daemon" "/lib/systemd/system/docker.service"; then\r
+            cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak\r
+            sed -i 's/^ExecStart=.*$/ExecStart=\/usr\/bin\/docker daemon -H tcp:\/\/0.0.0.0:2375 -H unix:\/\/\/var\/run\/docker.sock  \\/g' /lib/systemd/system/docker.service\r
+            systemctl daemon-reload\r
+            systemctl restart docker\r
+        else\r
+            echo "to be implemented"\r
+    fi\r
+else\r
+    echo "OS is not supported"\r
+fi\r
+\r
+# Issue Note for Ubuntu\r
+# 1. If the configuration of the file /etc/default/docker does not take effect after restarting docker service,\r
+#    you may try to modify /lib/systemd/system/docker.service\r
+#    commands:\r
+#    cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak\r
+#    sed -i '/^ExecStart/i\EnvironmentFile=-/etc/default/docker' /lib/systemd/system/docker.service\r
+#    sed -i '/ExecStart=\/usr\/bin\/dockerd/{;s/$/ \$DOCKER_OPTS/}' /lib/systemd/system/docker.service\r
+#    systemctl daemon-reload\r
+#    service docker restart\r
+# 2. Systemd is a system and session manager for Linux, where systemctl is one tool for systemd to view and control systemd.\r
+#    If the file /lib/systemd/system/docker.service is modified, systemd has to be reloaded to scan new or changed units.\r
+#    1) systemd and related packages are available on the PPA. To use the PPA, first add it to your software sources list as follows.\r
+#       add-apt-repository ppa:pitti/systemd\r
+#       apt-get update\r
+#    2) system can be installed from the PPS as follows.\r
+#       apt-get install systemd libpam-systemd systemd-ui\r
+\r
+\r
+\r