L'API de Docker est complètement non protégée par défaut, à l'exception des autorisations de système de fichiers sur son socket Unix. Vous devez configurer TLS lors de l'exposition de l'API Docker sur TCP afin que Docker Engine et vos clients puissent vérifier l'identité de chacun. Sinon, toute personne ayant accès au port TCP pourrait parcourir vos conteneurs Docker, en démarrer de nouveaux et exécuter des actions en tant que root
sur votre système.
TLS configuré exigera que les clients présentent un certificat valide signé par l'autorité de certification du serveur. Pour le faire fonctionner, vous devez créer des certificats SSL, puis configurer Docker Engine pour exiger des connexions TLS. Les clients Docker CLI doivent également être ajustés pour s'attendre à un serveur TLS.
Exposer le socket TCP
Vous pouvez exposer le socket TCP de Docker en utilisant le -H
drapeau pour définir un point de terminaison supplémentaire lors du démarrage du dockerd
processus. Ce drapeau peut être répété plusieurs fois; dans cet exemple, le socket Unix et le socket TCP seront disponibles :
/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
Le port 2375 est classiquement utilisé pour les connexions Docker non chiffrées. Le port 2376 doit être utilisé à la place une fois que TLS a été configuré.
Vous pouvez configurer Docker pour qu'il utilise ces indicateurs automatiquement en modifiant la définition de votre service Docker. Ajouter un remplacement dans /etc/systemd/system/docker.service.d/override.conf
qui change le ExecStart
ligne :
[Service] ExecStart=/usr/bin/dockerd -H ...
Rechargez systemd pour appliquer la modification :
sudo systemctl daemon-reload
Création de votre autorité de certification
Commencez par créer une autorité de certification (CA) pour votre configuration TLS. Vous utiliserez cette autorité de certification pour signer vos certificats ; le serveur refusera de communiquer avec les clients qui présentent un certificat d'une autre autorité de certification.
Utilisez OpenSSL pour générer des clés CA privées et publiques sur la machine hébergeant votre serveur Docker :
# Generate the private key openssl genrsa -aes256 -out ca-private.pem 4096 # Generate a public key from the private key openssl req -new -x509 -days 365 -key ca-private.pem -sha256 -out ca-public.pem
Vous serez invité à fournir une phrase de passe, une adresse e-mail, un code de pays, des noms d'état et de ville et un nom d'organisation à inclure avec votre clé publique. Entrez les informations dans votre terminal, en appuyant sur Entrée après chaque ligne pour avancer et créer la clé.
Génération d'une clé de serveur et d'une demande de signature de certificat
Créez ensuite une clé de serveur et une demande de signature de certificat :
# Generate the server key openssl genrsa -out server-key.pem 4096 # Generate a certificate signing request openssl req -subj "/CN=example.com" -sha256 -new -key server-key.pm -out request.csr
La demande de signature de certificat (CSR) contient toutes les informations nécessaires pour produire un certificat signé. Il est important de vérifier que le nom commun dans le CSR est correct pour votre serveur. Ceci est spécifié dans le CN
champ comme example.com
au dessus de; vous devez le définir sur le nom de domaine complet (FQDN) de votre serveur.
Configuration des extensions de certificat
L'utilisation de ce CSR permettrait les connexions au serveur via son FQDN. Vous devez spécifier des extensions de certificat si vous souhaitez ajouter un autre domaine ou utiliser une adresse IP. Créez un fichier d'extensions avec subjectAltName
et extendedKeyUsage
champs pour le configurer :
echo subjectAltName = DNS:sub.example.com;IP=192.168.0.1 >> extfile.cnf echo extendedKeyUsage = serverAuth >> extFile.cnf
Cet exemple autoriserait en outre les connexions via sub.example.com
et 192.168.0.1
.
Génération d'un certificat signé
Vous êtes maintenant prêt à combiner tous les composants et à générer un certificat signé :
openssl x509 -req -days 365 -sha256 -in request.csr -CA ca-public.pem -CAkey ca-private.pem -CAcreateserial -extfile extfile.cnf -out certificate.pem
Cela prend la demande de signature de certificat, ajoute votre fichier d'extension et utilise les clés de votre autorité de certification pour produire un certificat OpenSSL signé. Vous devrez fournir la phrase secrète de l'autorité de certification pour terminer le processus.
Ce certificat est configuré pour expirer après un an. Vous pouvez ajuster les -days
flag pour obtenir une durée de vie utile pour vos besoins. Vous devez prendre des dispositions pour générer un certificat de remplacement avant que celui-ci n'expire.
Génération d'un certificat client
Ensuite, vous devez générer un autre certificat que vos clients Docker pourront utiliser. Celui-ci doit être signé par la même autorité de certification que le certificat du serveur. Utiliser un fichier d'extensions avec extendedKeyUsage = clientAuth
pour préparer ce certificat à utiliser dans un scénario client.
# Generate a client key openssl genrsa -out client-key.pem 4096 # Create a certificate signing request openssl req -subj '/CN=client' -new -key client-key.pem -out client-request.csr # Complete the signing 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
Préparation à la configuration de Docker
Copiez votre ca-public.pem
, certificate.pem
, et server-key.pem
fichiers dans un nouveau répertoire prêt à être référencé dans votre configuration Docker. Ensuite, copiez le ca-public.pem
, client-certificate.pem
, et client-key.pem
fichiers sur la machine à partir de laquelle vous vous connecterez.
Vous pouvez supprimer la demande de signature de certificat et les fichiers d'extension dans votre répertoire de travail. Attention à ne pas perdre vos clés privées car elles sont irrécupérables. Sans eux, vous ne pourrez pas valider les certificats ou générer des renouvellements.
Configuration du démon Docker
Vous pouvez maintenant démarrer le démon Docker avec des indicateurs TLS faisant référence à votre certificat et à vos clés générés. Le --tlscacert
, --tlscert
, et --tlskey
les paramètres spécifient les chemins vers les ressources OpenSSL respectives générées ci-dessus.
/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
Ajout du --tlsverify
L'indicateur active l'application des connexions TLS. Les clients sans certificat correspondant ne pourront pas accéder au socket TCP de Docker.
Configuration du client Docker
Activez TLS sur le client en fournissant des drapeaux TLS lorsque vous utilisez le docker
commande. Vous devez également ajouter le -H
flag pour spécifier l'adresse de socket Docker distante à laquelle se connecter. Du point de vue du client, --tlsverify
signifie que la commande ne se connectera qu'aux serveurs avec un certificat TLS signé par la même autorité de certification que la sienne.
docker -H tcp://0.0.0.0:2376 --tlsverify --tlscacert=ca-public.pem --tlscert=client-certificate.pem --tlskey=client-key.pem ps
La fourniture de ces drapeaux chaque fois que vous utilisez la CLI devient très rapidement répétitive. Si vous travaillez principalement avec le même hôte protégé par TLS, définissez le DOCKER_HOST
et DOCKER_TLS_VERIFY
variables d'environnement dans votre profil shell. Copiez vos fichiers de certificats dans ca
, cert
, et key
dans votre ~/.docker
annuaire. Ceux-ci correspondent au --tls
de Docker flags et définissez un certificat par défaut pour le client.
export DOCKER_HOST=tcp://0.0.0.0:2376 export DOCKER_TLS_VERIFY=1
Vous pouvez simplifier le travail avec plusieurs hôtes en utilisant un mélange de connexions locales, distantes, non sécurisées et TLS en configurant des contextes Docker. Cette fonctionnalité vous permet de basculer entre les cibles à l'aide des commandes Docker CLI.
Le client Docker prend également en charge d'autres modes de vérification. Utilisation d'un mélange de tls
, tlscacert
, tlscert
, tlskey
, et tlsverify
flags active différents niveaux d'application TLS.
Avec juste tls
défini, Docker authentifiera le serveur à l'aide du pool d'autorités de certification par défaut. Ajout du tlscacert
et tlsverify
les drapeaux sans clé client obligeront le serveur à utiliser l'autorité de certification donnée sans aucune autre vérification. Omission de tlscacert
et tlsverify
mais l'inclusion des trois autres clés vérifiera le certificat du client sans authentifier l'autorité de certification du serveur.
Conclusion
La protection du socket TCP de Docker avec des certificats TLS vous permet d'exposer l'API de manière plus sûre en empêchant les connexions de clients non autorisés. Les acteurs qui analysent les ports de votre réseau ne pourront pas se connecter à Docker, ce qui vous offre une couche de protection qui empêche votre machine d'être compromise avec des privilèges de niveau racine.
Une fois que vous avez généré vos certificats, vous pouvez les utiliser pour vous authentifier auprès de la CLI Docker ou de vos propres clients HTTP. Curl les acceptera comme --cert
, --key
, et --cacert
drapeaux, par exemple.
TLS n'est qu'un composant d'une instance d'API Docker sécurisée. Il fournit un cryptage et une assurance que les clients sont fiables, mais n'est pas un mécanisme de contrôle d'accès granulaire.
Si vous souhaitez limiter ce que les clients individuels sont autorisés à faire, vous devez configurer un plug-in d'autorisation Docker Engine. Les plugins peuvent contacter un service externe pour déterminer si une demande d'API particulière est autorisée à continuer. Comme alternative, vous pouvez utiliser un proxy inverse devant votre socket TCP pour appliquer le contrôle d'accès avant que les requêtes n'atteignent Docker.