Tempo machen: Ein dedizierter Docker-Server beschleunigt Integrationstests

Seite 2: Docker HTTPS Endpoint aktivieren

Inhaltsverzeichnis

Der Docker Daemon unterstützt verschiedene Sockets, um per Docker Engine API auf die Docker Engine zuzugreifen. Standardmäßig kommuniziert der Docker Client auf dem lokalen Unix IPC Socket unix:///var/run/docker.sock mit dem Docker Daemon – alternativ lässt sich auch ein reguläres TCP Socket verwenden.

Grundsätzlich genügt es, den Docker Daemon dockerd auf den TCP Port 2375 zu binden:

/usr/bin/dockerd -H=0.0.0.0:2375

Dieser Ansatz ist jedoch zu unsicher, da er einen unverschlüsselten und unautorisierten Zugriff auf den Docker Host und damit letztlich auf den root-Account des Betriebssystems erlaubt. Entwicklerinnen und Entwickler sollten den Zugriff daher per TLS-Client-Zertifikat absichern. Dazu sind auf dem Server die in Listing 2 aufgeführten OpenSSL-Befehle auszuführen, um Private-Keys und Zertifikate zu erstellen:

# Run as root
sudo -i

# Resolve hostname and IP addresses for server certificate.
MY_HOSTNAME=`hostname`  && \
MY_PRIVATE_IP=`hostname -i` && \
MY_PUBLIC_IP=`curl -s ifconfig.me/ip`  && \
echo "MY_HOSTNAME=$MY_HOSTNAME"  && \
echo "MY_PRIVATE_IP=$MY_PRIVATE_IP" && \
echo "MY_PUBLIC_IP=$MY_PUBLIC_IP"

# Create CA key and certificate
mkdir -p /etc/docker/certs && cd /etc/docker/certs && \
openssl rand -base64 32 > ca-passphrase.txt && \
openssl genrsa -aes256 -passout file:ca-passphrase.txt -out ca-key.pem 4096 && \
openssl req -new -x509 -days 1095 -key ca-key.pem -passin file:ca-passphrase.txt -sha256 -out ca.pem -subj "/C=DE/O=private/CN=$MY_HOSTNAME"

# Create server key and a signed certificate for hostname and IPs
echo subjectAltName = DNS:$MY_HOSTNAME,IP:$MY_PRIVATE_IP,IP:$MY_PUBLIC_IP,IP:127.0.0.1 > extfile.cnf && \
echo extendedKeyUsage = serverAuth >> extfile.cnf && \
openssl genrsa -out server-key.pem 4096 && \
openssl req -subj "/CN=$MY_HOSTNAME" -sha256 -new -key server-key.pem -out server.csr && \
openssl x509 -req -days 1095 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -passin file:ca-passphrase.txt -CAcreateserial -out server-cert.pem -extfile extfile.cnf

# Create client key and certificate
cd /etc/docker/certs && \
openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile-client.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -passin file:ca-passphrase.txt -CAcreateserial -out cert.pem -extfile extfile-client.cnf
chmod 644 key.pem

Listing 2: TLS-Absicherung per OpenSSL

Anschließend lässt sich TCP für den Docker Daemon aktivieren – in Ubuntu üblicherweise in systemd. Nach dem Start von

sudo systemctl edit docker.service

lässt sich im geöffneten Editor folgender Eintrag setzen:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H=fd:// -H=unix:///var/run/docker.sock --tlsverify --tlscacert=/etc/docker/certs/ca.pem --tlscert=/etc/docker/certs/server-cert.pem --tlskey=/etc/docker/certs/server-key.pem -H=0.0.0.0:2376

Nach einem Neustart mit

sudo systemctl daemon-reload && \

sudo systemctl restart docker.service

akzeptiert der Docker Daemon zertifizierte Connections auf dem Port 2376.

docker --tlsverify --tlscacert=/etc/docker/certs/ca.pem --tlscert=/etc/docker/certs/cert.pem --tlskey=/etc/docker/certs/key.pem -H=$MY_HOSTNAME:2376 system info

Achtung: Auch wenn der Zugriff auf den Docker-Host nun gesichert erfolgt, sind die durch Container geöffneten Ports gegebenenfalls öffentlich erreichbar. Der Server sollte daher in jedem Fall hinter einer Firewall liegen beziehungsweise nur über ein VPN erreichbar sein.