So sichern Sie den TCP-Socket von Docker mit TLS

0
226

Dockers API ist standardmäßig komplett ungeschützt, mit Ausnahme von Dateisystemberechtigungen auf seinem Unix-Socket. Sie sollten TLS einrichten, wenn Sie die Docker-API über TCP verfügbar machen, damit Docker Engine und Ihre Clients sich gegenseitig verifizieren können’ Identität. Andernfalls könnte jeder mit Zugriff auf den TCP-Port Ihre Docker-Container durchsuchen, neue starten und Aktionen als Root auf Ihrem System ausführen.

Konfiguriertes TLS erfordert, dass Clients ein gültiges Zertifikat vorlegen, das signiert ist von der Zertifizierungsstelle des Servers. Damit es funktioniert, müssen Sie SSL-Zertifikate erstellen und dann Docker Engine so einrichten, dass TLS-Verbindungen erforderlich sind. Docker-CLI-Clients müssen auch so eingestellt werden, dass sie einen TLS-Server erwarten.

Freigeben des TCP-Sockets

Sie können den TCP-Socket von Docker verfügbar machen, indem Sie das Flag -H verwenden, um beim Starten des Dockerd-Prozesses einen zusätzlichen Endpunkt zu definieren. Dieses Flag kann mehrmals wiederholt werden; In diesem Beispiel sind sowohl der Unix-Socket als auch der TCP-Socket verfügbar:

/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

Port 2375 wird üblicherweise für unverschlüsselte Docker-Verbindungen verwendet. Port 2376 sollte stattdessen verwendet werden, sobald TLS eingerichtet wurde.

Sie können Docker so konfigurieren, dass diese Flags automatisch verwendet werden, indem Sie Ihre Docker-Dienstdefinition ändern. Fügen Sie in /etc/systemd/system/docker.service.d/override.conf eine Überschreibung hinzu, die die ExecStart-Zeile ändert:

[Service] ExecStart=/usr/bin/dockerd -H …

Reload systemd, um die Änderung zu übernehmen:

sudo systemctl daemon-reload

Creating Your Certificate Authority

Beginnen Sie mit dem Erstellen einer Zertifizierungsstelle (CA) für Ihre TLS-Konfiguration. Sie verwenden diese CA, um Ihre Zertifikate zu signieren. der Server wird die Kommunikation mit Clients verweigern, die ein Zertifikat von einer anderen CA vorlegen.

Werbung

Verwenden Sie OpenSSL, um private und öffentliche CA-Schlüssel auf dem Computer zu generieren, der Ihren Docker-Server hostet:

# Generiere den privaten Schlüssel openssl genrsa -aes256 -out ca-private.pem 4096 # Generiere einen öffentlichen Schlüssel aus dem privaten Schlüssel openssl req -new -x509 -days 365 -key ca-private.pem -sha256 -out ca-public.pem

Sie werden aufgefordert, eine Passphrase, E-Mail-Adresse, Ländervorwahl, Bundesland- und Städtenamen sowie den Namen der Organisation anzugeben, die in Ihren öffentlichen Schlüssel eingefügt werden sollen. Geben Sie die Informationen in Ihr Terminal ein und drücken Sie nach jeder Zeile die Eingabetaste, um vorwärts zu gehen und den Schlüssel zu erstellen.

Erzeugen eines Serverschlüssels und Zertifikatsignieranforderung

Erstellen Sie als Nächstes einen Serverschlüssel und eine Zertifikatsignieranforderung:

# Generieren des Serverschlüssels openssl genrsa -out server-key.pem 4096 # Generieren einer Zertifikatssignieranforderung openssl req -subj “/CN=example.com” -sha256 -new -key server-key.pm -out request.csr < p>

Der Certificate Signing Request (CSR) enthält alle Informationen, die zum Erstellen eines signierten Zertifikat. Es ist wichtig zu überprüfen, ob der allgemeine Name in der CSR für Ihren Server korrekt ist. Dies wird oben im CN-Feld als example.com angegeben; Sie sollten ihn auf den vollqualifizierten Domänennamen (FQDN) für Ihren Server einstellen.

 

 

Zertifikatserweiterungen einrichten

Die Verwendung dieses CSR würde Verbindungen zu den Server über seinen FQDN. Sie müssen Zertifikatserweiterungen angeben, wenn Sie eine weitere Domäne hinzufügen oder eine IP-Adresse verwenden möchten. Erstellen Sie eine Erweiterungsdatei mit den Feldern subjectAltName und extendedKeyUsage, um dies einzurichten:

echo subjectAltName = DNS:sub.example.com;IP=192.168.0.1 >> extfile.cnf echo extendedKeyUsage = serverAuth >> extFile.cnf Advertisement

Dieses Beispiel würde zusätzlich Verbindungen über sub.example.com und 192.168.0.1 zulassen.

Generieren eines signierten Zertifikats< /h2>

Jetzt können Sie alle Komponenten kombinieren und ein signiertes Zertifikat generieren:

openssl x509 -req -days 365 -sha256 -in request.csr -CA ca-public. pem -CAkey ca-private.pem -CAcreateserial -extfile extfile.cnf -out certificate.pem

Dies nimmt die Zertifikatsignierungsanforderung entgegen, fügt Ihre Erweiterungsdatei hinzu und verwendet die Schlüssel Ihrer CA, um ein signiertes OpenSSL-Zertifikat zu erstellen. Sie müssen die Passphrase der Zertifizierungsstelle angeben, um den Vorgang abzuschließen.

Dieses Zertifikat läuft nach einem Jahr ab. Sie können das Flag -days anpassen, um eine Nutzungsdauer für Ihre Anforderungen zu erhalten. Sie sollten veranlassen, dass Sie ein Ersatzzertifikat erstellen, bevor dieses abläuft.

Generieren eines Client-Zertifikats

Als nächstes sollten Sie ein weiteres Zertifikat für Ihre Docker-Clients generieren. Dieses muss von derselben CA wie das Serverzertifikat signiert sein. Verwenden Sie eine Erweiterungsdatei mit extendedKeyUsage = clientAuth, um dieses Zertifikat für die Verwendung in einem Client-Szenario vorzubereiten.

# Clientschlüssel generieren openssl genrsa -out client-key.pem 4096 # Erstellen einer Zertifikatssignieranforderung openssl req -subj '/CN=client' -new -key client-key.pem -out client-request.csr # Vervollständigen Sie die signieren echo extendedKeyUsage = clientAuth >> extfile-client.cnf openssl x509 -req -days 365 -sha256 -in client-request.csr -CA ca-public.pem -CAkey ca-private.pem -CAcreateserial -extfile extfile-client.cnf -out client-certificate.pem

Vorbereitung zum Konfigurieren von Docker

Kopieren Sie Ihre Dateien ca-public.pem, certificate.pem und server-key.pem in ein neues Verzeichnis, auf das Sie in Ihrer Docker-Konfiguration verweisen können. Kopieren Sie anschließend die Dateien ca-public.pem, client-certificate.pem und client-key.pem auf den Computer, von dem aus Sie eine Verbindung herstellen.

Werbung

Sie können die . löschen Zertifikatsignierungsanforderung und Erweiterungsdateien in Ihrem Arbeitsverzeichnis. Achten Sie darauf, Ihre privaten Schlüssel nicht zu verlieren, da diese nicht wiederherstellbar sind. Ohne sie können Sie keine Zertifikate validieren oder Verlängerungen generieren.

Konfigurieren des Docker-Daemons

Jetzt können Sie den Docker-Daemon mit TLS-Flags starten, die auf Ihr generiertes Zertifikat und Ihre Schlüssel verweisen. Die Parameter –tlscacert, –tlscert und –tlskey geben Pfade zu den entsprechenden oben generierten OpenSSL-Ressourcen an.

/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 –tlsverify –tlscacert=ca-public.pem –tlscert=certificate.pem –tlskey=server-key.pem

Das Hinzufügen des Flags –tlsverify ermöglicht die Erzwingung von TLS-Verbindungen. Clients ohne übereinstimmendes Zertifikat werden vom Zugriff auf den TCP-Socket von Docker blockiert.

Konfigurieren des Docker-Clients

TLS aktivieren auf des Clients, indem Sie TLS-Flags bereitstellen, wenn Sie den Docker-Befehl verwenden. Sie müssen auch das Flag -H hinzufügen, um die Remote-Docker-Socket-Adresse anzugeben, zu der eine Verbindung hergestellt werden soll. Aus Sicht des Clients bedeutet –tlsverify, dass der Befehl nur eine Verbindung zu Servern mit einem TLS-Zertifikat herstellt, das von derselben Zertifizierungsstelle wie sein eigenes signiert wurde.

docker -H tcp://0.0.0.0:2376 –tlsverify –tlscacert=ca-public.pem –tlscert=client-certificate.pem –tlskey=client-key.pem ps < p>Die Bereitstellung dieser Flags bei jeder Verwendung der CLI wiederholt sich sehr schnell. Wenn Sie hauptsächlich mit demselben TLS-geschützten Host arbeiten, legen Sie die Umgebungsvariablen DOCKER_HOST und DOCKER_TLS_VERIFY in Ihrem Shell-Profil fest. Kopieren Sie Ihre Zertifikatsdateien nach ca, cert und key in Ihr ~/.docker-Verzeichnis. Diese entsprechen den –tls-Flags von Docker und definieren ein Standardzertifikat für den Client.

export DOCKER_HOST=tcp://0.0.0.0:2376 export DOCKER_TLS_VERIFY=1

Sie können die Arbeit mit mehreren vereinfachen Hosts, die eine Mischung aus lokalen, Remote-, ungesicherten und TLS-Verbindungen verwenden, indem Sie Docker-Kontexte einrichten. Mit dieser Funktion können Sie mithilfe von Docker-CLI-Befehlen zwischen Zielen wechseln.

Werbung

Der Docker-Client unterstützt auch alternative Überprüfungsmodi. Die Verwendung einer Mischung aus tls-, tlscacert-, tlscert-, tlskey- und tlsverify-Flags aktiviert unterschiedliche TLS-Erzwingungsstufen.

Wenn nur tls festgelegt ist, authentifiziert Docker den Server mithilfe des standardmäßigen CA-Pools. Das Hinzufügen der Flags tlscacert und tlsverify ohne einen Clientschlüssel erzwingt, dass der Server die angegebene Zertifizierungsstelle ohne weitere Prüfungen verwendet. Wenn tlscacert und tlsverify weggelassen werden, aber die anderen drei Schlüssel eingeschlossen werden, wird das Zertifikat des Clients überprüft, ohne die CA des Servers zu authentifizieren.

Schlussfolgerung

Wenn Sie den TCP-Socket von Docker mit TLS-Zertifikaten schützen, können Sie die API sicherer verfügbar machen, indem Sie Verbindungen von nicht autorisierten Clients verhindern. Akteure, die Ihr Netzwerk portieren, werden daran gehindert, sich mit Docker zu verbinden. Dadurch erhalten Sie eine Schutzschicht, die verhindert, dass Ihr Computer mit Root-Rechten kompromittiert wird.

Sobald Sie Ihre Zertifikate generiert haben, können Sie Sie können sie verwenden, um sich mit der Docker-CLI oder Ihren eigenen HTTP-Clients zu authentifizieren. Curl akzeptiert sie beispielsweise als –cert-, –key- und –cacert-Flags.

TLS ist nur eine Komponente einer gesicherten Docker-API-Instanz. Es bietet Verschlüsselung und die Gewissheit, dass Clients vertrauenswürdig sind, ist jedoch kein granularer Zugriffskontrollmechanismus.

Wenn Sie einschränken möchten, was einzelne Clients tun dürfen, sollten Sie ein Docker Engine-Autorisierungs-Plug-in einrichten. Plugins können einen externen Dienst kontaktieren, um festzustellen, ob eine bestimmte API-Anfrage fortgesetzt werden darf. Alternativ können Sie einen Reverse-Proxy vor Ihrem TCP-Socket verwenden, um die Zugriffskontrolle zu erzwingen, bevor Anfragen Docker erreichen.