Comment sécuriser le socket TCP de Docker avec TLS

0
193

L'API Docker n'est pas 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 se vérifier les uns les autres’ identité. 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.

Le TLS configuré exigera des clients qu'ils présentent un certificat valide et signé. par l'autorité de certification du serveur. Pour que cela fonctionne, 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.

Exposition du socket TCP

Vous pouvez exposer le socket TCP de Docker en utilisant l'indicateur -H pour définir un point de terminaison supplémentaire lors du démarrage du processus dockerd. 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 cryptées. Le port 2376 doit être utilisé à la place une fois TLS configuré.

Vous pouvez configurer Docker pour utiliser ces indicateurs automatiquement en modifiant votre définition de service Docker. Ajoutez un override dans /etc/systemd/system/docker.service.d/override.conf qui modifie la ligne ExecStart :

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

Reload systemd pour appliquer le changement :

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 CA.

Publicité

Utilisez OpenSSL pour générer des clés CA privées et publiques sur la machine hébergeant votre serveur Docker :

# Générer la clé privée openssl genrsa -aes256 -out ca-private.pem 4096 # Générer une clé publique à partir de la clé privée openssl req -new -x509 -days 365 -key ca-private.pem -sha256 -out ca-public.pem

Vous serez invité à fournir une phrase secrète, une adresse e-mail, un code de pays, des noms d'état et de ville et le nom de l'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 Certificate Signing Request

Créez ensuite une clé de serveur et une demande de signature de certificat :

# Générer la clé du serveur openssl genrsa -out server-key.pem 4096 # Générer une demande de signature de certificat openssl req -subj “/CN=example.com” -sha256 -new -key server-key.pm -out request.csr < p>

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 champ CN comme example.com ci-dessus ; vous devez le définir sur le nom de domaine complet (FQDN) pour 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 les champs subjectAltName et extendedKeyUsage pour configurer cela :

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

Cet exemple autoriserait en outre les connexions via sub.example.com et 192.168.0.1 .

Génération d'un certificat signé< /h2>

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.

< p>Ce certificat expire au bout d'un an. Vous pouvez ajuster l'indicateur -days 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 l'expiration de celui-ci.

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. Utilisez un fichier d'extensions avec extendedKeyUsage = clientAuth pour préparer ce certificat à utiliser dans un scénario client.

# Générer une clé client openssl genrsa -out client-key.pem 4096 # Créer une demande de signature de certificat openssl req -subj '/CN=client' -new -key client-key.pem -out client-request.csr # Compléter le signature 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 vos fichiers ca-public.pem, certificate.pem et server-key.pem dans un nouveau répertoire prêt à être référencé dans votre configuration Docker. Ensuite, copiez les fichiers ca-public.pem, client-certificate.pem et client-key.pem sur la machine à partir de laquelle vous vous connecterez.

Publicité

Vous pouvez supprimer le demande de signature de certificat et fichiers d'extension dans votre répertoire de travail. Veillez à ne pas perdre vos clés privées car elles ne sont pas ré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 référençant votre certificat et vos clés générés. Les paramètres –tlscacert, –tlscert et –tlskey 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

L'ajout de l'indicateur –tlsverify permet l'application des connexions TLS. Les clients sans certificat correspondant ne pourront pas accéder au socket TCP de Docker.

Configuration du client Docker

Activer TLS sur le client en fournissant des indicateurs TLS lorsque vous utilisez la commande docker. Vous devez également ajouter l'indicateur -H pour spécifier l'adresse de socket Docker distante à laquelle vous 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 < p>Fournir ces indicateurs à chaque fois que vous utilisez la CLI devient très rapidement répétitif. Si vous travaillez principalement avec le même hôte protégé par TLS, définissez les variables d'environnement DOCKER_HOST et DOCKER_TLS_VERIFY dans votre profil shell. Copiez vos fichiers de certificats dans ca, cert et key dans votre répertoire ~/.docker. Ceux-ci correspondent aux indicateurs Docker’s –tls et définissent 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 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.

Publicité

Le client Docker prend également en charge des modes de vérification alternatifs. L'utilisation d'un mélange d'indicateurs tls, tlscacert, tlscert, tlskey et tlsverify active différents niveaux d'application de TLS.

Avec juste tls défini, Docker authentifiera le serveur à l'aide du pool de CA par défaut. L'ajout des indicateurs tlscacert et tlsverify sans clé client obligera le serveur à utiliser l'autorité de certification donnée sans aucune autre vérification. Omettre tlscacert et tlsverify mais inclure les 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, vous offrant 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 avec la CLI Docker ou vos propres clients HTTP. Curl les acceptera en tant qu'indicateurs –cert, –key et –cacert, par exemple.

TLS n'est qu'un composant d'une instance d'API Docker sécurisée. Il fournit un cryptage et l'assurance que les clients sont dignes de confiance, mais ne constitue 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 requête API particulière est autorisée à se poursuivre. Comme alternative, vous pouvez utiliser un proxy inverse devant votre socket TCP pour appliquer le contrôle d'accès avant que les demandes n'atteignent Docker.