Tempo machen: Ein dedizierter Docker-Server beschleunigt Integrationstests
Seite 2: Docker HTTPS Endpoint aktivieren
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.