web-dev-qa-db-fra.com

Pourquoi ARG dans un DOCKERFILE n'est pas recommandé pour transmettre des secrets?

Dans http://docs.docker.com/engine/reference/builder/#arg , il recommande que les secrets ne soient pas transmis via ARGS.

Remarque: Il n'est pas recommandé d'utiliser des variables au moment de la construction pour transmettre des secrets comme les clés github, les informations d'identification de l'utilisateur, etc.

À quel moment les secrets transmis par les variables de construction sont-ils en danger?

26
Roger Lam

Mise à jour d'août 2018:

Vous avez maintenant docker build --secret id=mysecret,src=/secret/file.
Voir " moyen sûr d'utiliser l'argument de construction dans Docker ".

Mise à jour janvier 2017:

Docker (swarm) 1.13 a docker secret .

Cependant, comme commenté par Steve Hoffman (bacoboy) :

[...] La commande secrète n'aide que les utilisateurs de swarm n'est pas une solution plus générale (comme ils l'ont fait avec l'attachement de volumes persistants).
.
.

Vraiment, comment les secrets sont transmis tombe en dehors de l'espace de docker run.
AWS fait ce genre de chose avec des rôles et des stratégies pour accorder/refuser des autorisations plus un SDK.
Chef le fait en utilisant des databags chiffrés et un "bootstrapping" crypto pour l'authentification.
K8S a sa propre version de ce qui vient d'être publié en 1.13.
Je suis sûr que mesos ajoutera une implémentation similaire avec le temps.

Ces implémentations semblent se répartir en 2 camps.

  • passer le secret via le montage de volume fourni par la "plate-forme" ou (chef/docker secret/k8s
  • transmettre des informations d'identification pour parler à un service externe pour obtenir des informations au démarrage (iam/credstash/etc)

Réponse originale: novembre 2015

Cela a été introduit dans commit 54240f8 (docker 1.9, nov.2015), de PR 15182 ,

L'environnement de génération est ajouté à la chaîne de commande du continuateur intermédiaire pour faciliter les recherches de cache.
Il aide également à renforcer la traçabilité. Mais cela rend également la fonctionnalité moins sécurisée du point de vue du passage des secrets de génération.

numéro 1349 réitère:

Variables d'environnement au moment de la construction : Les variables d'environnement au moment de la construction n'ont pas été conçues pour gérer les secrets. Faute d'autres options, les gens prévoient de les utiliser à cette fin. Pour éviter de donner l'impression qu'elles conviennent aux secrets, il a été décidé de ne pas chiffrer délibérément ces variables dans le processus.

Comme mentionné dans 9176commentaires :

les variables env sont la mauvaise façon de transmettre des secrets. Nous ne devrions pas essayer de réinventer la roue et de fournir un mécanisme de distribution de sécurité paralysé dès la sortie de la boîte.

Lorsque vous stockez vos clés secrètes dans l'environnement, vous êtes susceptible de les exposer accidentellement - exactement ce que nous voulons éviter:

  • Étant donné que l'environnement est implicitement disponible pour le processus, il est extrêmement difficile, voire impossible, de suivre l'accès et la façon dont le contenu est exposé
  • Il est incroyablement courant que des applications saisissent tout l'environnement et l'impriment, car elles peuvent être utiles pour le débogage, ou même pour les envoyer dans le cadre d'un rapport d'erreur. Tellement de secrets sont divulgués à PagerDuty qu'ils ont un processus interne bien graissé pour les éliminer de leur infrastructure.
  • Les variables d'environnement sont transmises aux processus enfants, ce qui permet un accès involontaire et rompt le principe du moindre privilège. Imaginez que dans le cadre de votre application, vous appelez un outil tiers pour effectuer une action, tout à coup, cet outil tiers a accès à votre environnement, et Dieu sait ce qu'il en fera.
  • Il est très courant pour les applications qui plantent de stocker les variables d'environnement dans des fichiers journaux pour un débogage ultérieur. Cela signifie des secrets en texte brut sur le disque.
  • Mettre des secrets dans les variables env se transforme rapidement en connaissances tribales. Les nouveaux ingénieurs ne savent pas qu'ils sont là et ne savent pas qu'ils doivent être prudents lors de la manipulation des variables d'environnement (les filtrer en sous-processus, etc.).

Dans l'ensemble, les secrets dans les variables env enfreignent le principe de la moindre surprise, sont une mauvaise pratique et entraîneront une fuite éventuelle de secrets.

31
VonC

La raison simple est que la valeur du secret est visible par toute personne possédant l'image en exécutant simplement history dessus.

Prenez cet exemple de fichier docker:

FROM Alpine

ARG secret

RUN echo "${secret}"

(Agréable et simple, juste pour illustrer comment vous pourriez utiliser un secret.)

puis nous le construisons $ docker build --build-arg secret=S3CR3T - < Dockerfile

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM Alpine
 ---> 13e1761bf172
Step 2 : ARG secret
 ---> Running in 695b7a931445
 ---> 5414c15a1cb6
Removing intermediate container 695b7a931445
Step 3 : RUN echo "${secret}"
 ---> Running in c90cf0d1414b
s3cr3t
 ---> f2bcff49ac09
Removing intermediate container c90cf0d1414b
Successfully built f2bcff49ac09

Et un exemple de comment récupérer le "secret" (recherchez |1 secret= sur la première ligne):

$ docker history f2bcff49ac09
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
f2bcff49ac09        8 seconds ago       |1 secret=S3CR3T /bin/sh -c echo "${secret}"    0 B
5414c15a1cb6        8 seconds ago       /bin/sh -c #(nop) ARG secret                    0 B
13e1761bf172        6 months ago        /bin/sh -c #(nop) ADD file:614a9122187935fccf   4.797 MB

C'est le cas si vous avez construit l'image localement ou si vous l'avez extraite d'un registre.

Si votre objectif est de garder le secret de génération hors du conteneur en cours d'exécution, alors utiliser ARG vous aide - considérez ceci:

$ docker run --rm -ti f2bcff49ac09 sh
/ # env
HOSTNAME=7bc772fd0f56
SHLVL=1
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
$ # Note no secret in the above output
9
Ash Berlin-Taylor

Je pense que la nouvelle (17.05) fonctionnalité Docker Builds à plusieurs étapes ( https://docs.docker.com/engine/userguide/eng-image/multistage-build/ ) atténue ces préoccupations (valides) à propos de simplement utiliser --build-arg.

FROM mybuildertools
ADD my-git-creds /root/.ssh
RUN git clone [email protected]:example/foo /src
FROM mybuildertools
COPY --from=0 /src /src
RUN ...build /src with no git credentials ending up in final image...

Malheureusement, il ne semble pas être un moyen facile d'autoriser les reconstructions ultérieures (par exemple, les modifications de l'étape de construction dans le Dockerfile) à moins que vous n'ayez le répertoire "my-git-creds".

3
jamshid

J'ai écrit https://github.com/abourget/secrets-bridge pour résoudre le problème des secrets de construction.

Il crée une configuration jetable que vous pouvez passer comme argument de construction, pendant le processus de construction, il se connecte à l'hôte et récupère les secrets, les utilise, puis vous pouvez tuer le pont hôte. Même si les build-args sont enregistrés quelque part, ils deviennent inutiles au moment où le serveur se ferme.

Le serveur prend en charge le transfert d'agent SSH, tunnelé via une communication WebSocket TLS. Cela fonctionne aussi sur Windows!

J'espère que cela t'aides.

2
abourget