Protéger le socket du démon Docker
Par défaut, Docker s'exécute via un socket UNIX non-réseau. Il peut également optionnellement communiquer en utilisant SSH ou un socket TLS (HTTPS).
Utiliser SSH pour protéger le socket du démon Docker
NoteLe
USERNAME
donné doit avoir les permissions pour accéder au socket docker sur la machine distante. Référez-vous à gérer Docker en tant qu'utilisateur non-root pour apprendre comment donner à un utilisateur non-root l'accès au socket docker.
L'exemple suivant crée un
docker context
pour se connecter avec un démon dockerd
distant sur host1.example.com
en utilisant SSH, et
en tant qu'utilisateur docker-user
sur la machine distante :
$ docker context create \
--docker host=ssh://[email protected] \
--description="Moteur distant" \
my-remote-engine
my-remote-engine
Contexte "my-remote-engine" créé avec succès
Après avoir créé le contexte, utilisez docker context use
pour commuter la CLI docker
pour l'utiliser, et pour se connecter au moteur distant :
$ docker context use my-remote-engine
my-remote-engine
Le contexte actuel est maintenant "my-remote-engine"
$ docker info
<affiche la sortie du moteur distant>
Utilisez le contexte default
pour revenir au démon par défaut (local) :
$ docker context use default
default
Le contexte actuel est maintenant "default"
Alternativement, utilisez la variable d'environnement DOCKER_HOST
pour commuter temporairement
la CLI docker
pour se connecter à l'hôte distant en utilisant SSH. Cela ne nécessite pas
de créer un contexte, et peut être utile pour créer une connexion ad-hoc avec un
moteur différent :
$ export DOCKER_HOST=ssh://[email protected]
$ docker info
<affiche la sortie du moteur distant>
Conseils SSH
Pour la meilleure expérience utilisateur avec SSH, configurez ~/.ssh/config
comme suit pour permettre
la réutilisation d'une connexion SSH pour plusieurs invocations de la CLI docker
:
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist yes
Utiliser TLS (HTTPS) pour protéger le socket du démon Docker
Si vous avez besoin que Docker soit accessible via HTTP plutôt que SSH de manière sécurisée,
vous pouvez activer TLS (HTTPS) en spécifiant le flag tlsverify
et en pointant le flag
tlscacert
de Docker vers un certificat CA de confiance.
En mode démon, il n'autorise que les connexions depuis des clients authentifiés par un certificat signé par cette CA. En mode client, il ne se connecte qu'aux serveurs avec un certificat signé par cette CA.
ImportantUtiliser TLS et gérer une CA est un sujet avancé. Familiarisez-vous avec OpenSSL, x509, et TLS avant de l'utiliser en production.
Créer une CA, des clés serveur et client avec OpenSSL
NoteRemplacez toutes les instances de
$HOST
dans l'exemple suivant par le nom DNS de l'hôte de votre démon Docker.
D'abord, sur la machine hôte du démon Docker, générez les clés privées et publiques de la CA :
$ openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
..............................................................................++
........++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:[email protected]
Maintenant que vous avez une CA, vous pouvez créer une clé serveur et une demande de signature de certificat (CSR). Assurez-vous que "Common Name" correspond au nom d'hôte que vous utilisez pour vous connecter à Docker :
NoteRemplacez toutes les instances de
$HOST
dans l'exemple suivant par le nom DNS de l'hôte de votre démon Docker.
$ openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....................................................................++
.................................................................................................++
e is 65537 (0x10001)
$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
Ensuite, nous allons signer la clé publique avec notre CA :
Puisque les connexions TLS peuvent être faites via l'adresse IP ainsi que le nom DNS, les adresses IP
doivent être spécifiées lors de la création du certificat. Par exemple, pour permettre les connexions
en utilisant 10.10.10.20
et 127.0.0.1
:
$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
Définissez les attributs d'usage étendu de la clé du démon Docker pour être utilisés uniquement pour l'authentification du serveur :
$ echo extendedKeyUsage = serverAuth >> extfile.cnf
Maintenant, générez le certificat signé :
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
Les plugins d'autorisation offrent plus de contrôle fin pour compléter l'authentification du TLS mutuel. En plus d'autres informations décrites dans le document ci-dessus, les plugins d'autorisation s'exécutant sur un démon Docker reçoivent les informations de certificat pour les clients Docker qui se connectent.
Pour l'authentification client, créez une clé client et une demande de signature de certificat :
NotePour simplifier les prochaines étapes, vous pouvez effectuer cette étape sur la machine hôte du démon Docker également.
$ openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
.........................................................++
................++
e is 65537 (0x10001)
$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr
Pour rendre la clé appropriée pour l'authentification client, créez un nouveau fichier de configuration d'extensions :
$ echo extendedKeyUsage = clientAuth > extfile-client.cnf
Maintenant, générez le certificat signé :
$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out cert.pem -extfile extfile-client.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
Après avoir généré cert.pem
et server-cert.pem
vous pouvez supprimer en toute sécurité les
deux demandes de signature de certificat et les fichiers de configuration d'extensions :
$ rm -v client.csr server.csr extfile.cnf extfile-client.cnf
Avec un umask
par défaut de 022, vos clés secrètes sont lisibles par tous et
inscriptibles pour vous et votre groupe.
Pour protéger vos clés contre des dommages accidentels, supprimez leurs permissions d'écriture. Pour les rendre lisibles seulement par vous, changez les modes de fichier comme suit :
$ chmod -v 0400 ca-key.pem key.pem server-key.pem
Les certificats peuvent être lisibles par tous, mais vous pourriez vouloir supprimer l'accès en écriture pour prévenir des dommages accidentels :
$ chmod -v 0444 ca.pem server-cert.pem cert.pem
Maintenant vous pouvez faire en sorte que le démon Docker n'accepte que les connexions des clients fournissant un certificat de confiance de votre CA :
$ dockerd \
--tlsverify \
--tlscacert=ca.pem \
--tlscert=server-cert.pem \
--tlskey=server-key.pem \
-H=0.0.0.0:2376
Pour vous connecter à Docker et valider son certificat, fournissez vos clés client, certificats et CA de confiance :
TipCette étape devrait être exécutée sur votre machine client Docker. En tant que tel, vous devez copier votre certificat CA, votre certificat serveur, et votre certificat client vers cette machine.
NoteRemplacez toutes les instances de
$HOST
dans l'exemple suivant par le nom DNS de l'hôte de votre démon Docker.
$ docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=$HOST:2376 version
NoteDocker sur TLS devrait s'exécuter sur le port TCP 2376.
WarningComme montré dans l'exemple ci-dessus, vous n'avez pas besoin d'exécuter le client
docker
avecsudo
ou le groupedocker
lorsque vous utilisez l'authentification par certificat. Cela signifie que quiconque avec les clés peut donner n'importe quelles instructions à votre démon Docker, leur donnant un accès root à la machine hébergeant le démon. Gardez ces clés comme vous garderiez un mot de passe root !
Sécurisé par défaut
Si vous voulez sécuriser vos connexions client Docker par défaut, vous pouvez déplacer
les fichiers vers le répertoire .docker
dans votre répertoire home --- et définir les
variables DOCKER_HOST
et DOCKER_TLS_VERIFY
également (au lieu de passer
-H=tcp://$HOST:2376
et --tlsverify
à chaque appel).
$ mkdir -pv ~/.docker
$ cp -v {ca,cert,key}.pem ~/.docker
$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
Docker se connecte maintenant de manière sécurisée par défaut :
$ docker ps
Autres modes
Si vous ne voulez pas avoir une authentification bidirectionnelle complète, vous pouvez exécuter Docker dans divers autres modes en mélangeant les flags.
Modes démon
tlsverify
,tlscacert
,tlscert
,tlskey
définis : Authentifier les clientstls
,tlscert
,tlskey
: Ne pas authentifier les clients
Modes client
tls
: Authentifier le serveur basé sur le pool de CA public/par défauttlsverify
,tlscacert
: Authentifier le serveur basé sur la CA donnéetls
,tlscert
,tlskey
: Authentifier avec le certificat client, ne pas authentifier le serveur basé sur la CA donnéetlsverify
,tlscacert
,tlscert
,tlskey
: Authentifier avec le certificat client et authentifier le serveur basé sur la CA donnée
Si trouvé, le client envoie son certificat client, donc vous n'avez besoin que de
déposer vos clés dans ~/.docker/{ca,cert,key}.pem
. Alternativement,
si vous voulez stocker vos clés dans un autre emplacement, vous pouvez spécifier cet
emplacement en utilisant la variable d'environnement DOCKER_CERT_PATH
.
$ export DOCKER_CERT_PATH=~/.docker/zone1/
$ docker --tlsverify ps
Se connecter au port Docker sécurisé en utilisant curl
Pour utiliser curl
pour faire des requêtes API de test, vous devez utiliser trois flags de ligne de commande
supplémentaires :
$ curl https://$HOST:2376/images/json \
--cert ~/.docker/cert.pem \
--key ~/.docker/key.pem \
--cacert ~/.docker/ca.pem