J'ai une application qui exécute diverses choses amusantes avec Git (comme exécuter git clone & git push) et j'essaie de la docker.
Je rencontre un problème, cependant, où je dois pouvoir ajouter une clé SSH au conteneur pour que l'utilisateur du conteneur puisse l'utiliser.
J'ai essayé de le copier /root/.ssh/
, de le changer $HOME
, de créer un wrapper git ssh, et toujours pas de chance.
Voici le Dockerfile pour référence:
#DOCKER-VERSION 0.3.4
from ubuntu:12.04
RUN apt-get update
RUN apt-get install python-software-properties python g++ make git-core openssh-server -y
RUN add-apt-repository ppa:chris-lea/node.js
RUN echo "deb http://archive.ubuntu.com/ubuntu precise universe" >> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install nodejs -y
ADD . /src
ADD ../../home/ubuntu/.ssh/id_rsa /root/.ssh/id_rsa
RUN cd /src; npm install
EXPOSE 808:808
CMD [ "node", "/src/app.js"]
app.js
exécute les commandes git comme git pull
Réponses:
C'est un problème plus difficile si vous devez utiliser SSH au moment de la construction. Par exemple, si vous utilisez
git clone
, ou dans mon caspip
etnpm
pour télécharger à partir d'un référentiel privé.La solution que j'ai trouvée est d'ajouter vos clés à l'aide du
--build-arg
drapeau. Ensuite, vous pouvez utiliser la nouvelle--squash
commande expérimentale (ajoutée 1.13) pour fusionner les couches afin que les clés ne soient plus disponibles après leur suppression. Voici ma solution:Commande Build
Dockerfile
Mise à jour: si vous utilisez Docker 1.13 et que vous disposez de fonctionnalités expérimentales, vous pouvez ajouter
--squash
à la commande build qui fusionnera les couches, supprimant les clés SSH et les masquantdocker history
.la source
id_rsa.pub
fichier car il n'est pas nécessaire.$(openssl rsa -in ~/.ssh/id_rsa)
placeIl s'avère que lors de l'utilisation d'Ubuntu, le ssh_config n'est pas correct. Vous devez ajouter
à votre Dockerfile afin qu'il reconnaisse votre clé ssh.
la source
RUN echo " Host example.com" >> /root/.ssh/config RUN echo " User <someusername>" >> /root/.ssh/config
La clé ssh reste stockée dans l'image, même si vous supprimez la clé dans une commande de calque après l'avoir ajoutée (voir les commentaires dans cet article ).
Dans mon cas, c'est ok, c'est donc ce que j'utilise:
la source
Si vous utilisez Docker Composer, un choix simple consiste à transférer l'agent SSH comme ça:
la source
SSH_AUTH_SOCK
est une variable qui contient un chemin vers un agent sshSSH_AUTH_SOCK
blog.joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add$SSH_AUTH_SOCK
, vous devez monter ce chemin -/run/host-services/ssh-auth.sock
.En développant la réponse de Peter Grainger, j'ai pu utiliser la version multi-étapes disponible depuis Docker 17.05. La page officielle indique:
Garder cela à l'esprit ici est mon exemple d'
Dockerfile
inclure trois étapes de construction. Il est destiné à créer une image de production de l'application Web cliente..dockerignore
répète le contenu du.gitignore
fichier (il empêche les répertoiresnode_modules
résultantsdist
du projet d'être copiés):Exemple de commande pour construire une image:
Si votre clé SSH privée n'a pas de phrase secrète, spécifiez simplement un
SSH_KEY_PASSPHRASE
argument vide .Voilà comment cela fonctionne:
1). Sur la première étape uniquement
package.json
, lesyarn.lock
fichiers et la clé SSH privée sont copiés dans la première image intermédiaire nomméesources
. Afin d'éviter d'autres invites de phrase secrète de clé SSH, il est automatiquement ajouté àssh-agent
. Enfin, layarn
commande installe toutes les dépendances requises de NPM et clone les référentiels git privés de Bitbucket sur SSH.2). La deuxième étape construit et réduit le code source de l'application Web et le place dans le
dist
répertoire de la prochaine image intermédiaire nomméeproduction
. Notez que le code source de installénode_modules
est copié à partir de l'image nomméesources
produite sur la première étape par cette ligne:Il pourrait également s'agir de la ligne suivante:
Nous n'avons ici que le
node_modules
répertoire de la première image intermédiaire, nonSSH_KEY
et desSSH_KEY_PASSPHRASE
arguments. Tout le reste requis pour la construction est copié à partir de notre répertoire de projet.3). À la troisième étape, nous réduisons la taille de l'image finale qui sera étiquetée
ezze/geoport:0.6.0
en incluant uniquement ledist
répertoire de la deuxième image intermédiaire nomméeproduction
et en installant Node Express pour démarrer un serveur Web.La liste des images donne une sortie comme celle-ci:
où les images non étiquetées correspondent aux première et deuxième étapes de construction intermédiaires.
Si vous courez
vous ne verrez aucune mention de
SSH_KEY
etSSH_KEY_PASSPHRASE
dans l'image finale.la source
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
mais quand je vérifie dans un autre RUN ou même dans le même RUN commande en faisant unssh-add -l
il me dit que "L'agent n'a pas d'identité". Commencer à arracher mes cheveux, des pensées?Afin de vous injecter la clé ssh, au sein d'un container, vous avez plusieurs solutions:
En utilisant un Dockerfile avec l'
ADD
instruction, vous pouvez l'injecter pendant votre processus de constructionFaire simplement quelque chose comme
cat id_rsa | docker run -i <image> sh -c 'cat > /root/.ssh/id_rsa'
Utilisation de la
docker cp
commande qui vous permet d'injecter des fichiers pendant l'exécution d'un conteneur.la source
apt-get install openssh-server
et en mettant ma clé dans /root/.ssh/id_rsa et ça a bien fonctionné. Quelle image utilisez-vous?Une solution multiplateforme consiste à utiliser un montage de liaison pour partager le
.ssh
dossier de l'hôte dans le conteneur:Semblable à l'agent qui transfère cette approche, les clés publiques seront accessibles au conteneur. Un autre avantage est qu'il fonctionne également avec un utilisateur non root et vous permettra de vous connecter à GitHub. Une mise en garde à prendre en compte, cependant, est que tout le contenu (y compris les clés privées) du
.ssh
dossier sera partagé, de sorte que cette approche n'est souhaitable que pour le développement et uniquement pour les images de conteneurs de confiance.la source
docker build
seulement pendantdocker run
docker-compose up
de mon Windows 10 local. Comment dois-je utiliser votre solution dans ce scénario?Les conteneurs Docker doivent être considérés comme des «services» qui leur sont propres. Pour séparer les préoccupations, vous devez séparer les fonctionnalités:
1) Les données doivent être dans un conteneur de données: utilisez un volume lié pour cloner le référentiel dans. Ce conteneur de données peut ensuite être lié au service qui en a besoin.
2) Utilisez un conteneur pour exécuter la tâche de clonage git, (c'est-à-dire qu'il ne s'agit que du clonage) reliant le conteneur de données à celui-ci lorsque vous l'exécutez.
3) Même chose pour la clé ssh: mettez-le comme un volume (comme suggéré ci-dessus) et liez-le au service de clonage git lorsque vous en avez besoin
De cette façon, la tâche de clonage et la clé sont éphémères et ne sont actives qu'en cas de besoin.
Maintenant, si votre application elle-même est une interface git, vous voudrez peut-être envisager les API REST github ou bitbucket directement pour faire votre travail: c'est pour cela qu'elles ont été conçues.
la source
Cette ligne est un problème:
Lorsque vous spécifiez les fichiers que vous souhaitez copier dans l'image, vous ne pouvez utiliser que des chemins relatifs - par rapport au répertoire où se trouve votre Dockerfile. Vous devriez donc plutôt utiliser:
Et placez le fichier id_rsa dans le même répertoire que votre Dockerfile.
Consultez ceci pour plus de détails: http://docs.docker.io/reference/builder/#add
la source
docker cp
le met simplement dans le conteneur et non l'image, non?Nous avons eu un problème similaire lors de l'installation de npm au moment de la construction du docker.
Inspiré de la solution de Daniel van Flymen et la combinant avec la réécriture d'URL git , nous avons trouvé une méthode un peu plus simple pour authentifier l'installation de npm à partir de dépôts github privés - nous avons utilisé des jetons oauth2 au lieu des clés.
Dans notre cas, les dépendances npm ont été spécifiées comme "git + https://github.com/ ..."
Pour l'authentification dans le conteneur, les URL doivent être réécrites pour être adaptées à l'authentification ssh (ssh: //[email protected]/) ou à l'authentification par jeton (https: // $ {GITHUB_TOKEN} @ github.com /)
Commande Build:
Malheureusement, je suis sur Docker 1.9, donc l'option --squash n'est pas encore là, il faut éventuellement l'ajouter
Dockerfile:
la source
Transférez le socket d'authentification ssh vers le conteneur:
Votre script pourra effectuer un
git clone
.Extra: Si vous souhaitez que les fichiers clonés appartiennent à un utilisateur spécifique, vous devez utiliser
chown
car l'utilisation d'un autre utilisateur que root dans le conteneurgit
échouera.Vous pouvez faire cette publication dans l'environnement du conteneur quelques variables supplémentaires:
Après avoir cloné, vous devez exécuter
chown $OWNER_USER:$OWNER_GROUP -R <source_folder>
pour définir la propriété appropriée avant de quitter le conteneur afin que les fichiers soient accessibles par un utilisateur non root en dehors du conteneur.la source
-u root:$(id -u $USER)
au moins les fichiers appartenant au même groupe principal que votre utilisateur, ce qui devrait les rendre au moins lisibles à moinssudo
que quelque chose ne les crée avec des0600
autorisations.-u root:$(id -u $USER)
devrait l'être-g
./tmp/ssh_auth.sock: No such file or directory
maintenant c'est/tmp/ssh-vid8Zzi8UILE/agent.46016
sur ma machine hôte/tmp
intérieur de votre conteneur. Ou une faute de frappe sur la commande docker run. Assurez-vous que l'instruction de liaison est correcte-v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock
: l'ordre est important et le point-virgule est également important. Veuillez consulter la documentation de Docker pour obtenir de l'aide.Comme eczajk l'a déjà fait remarquer dans la réponse de Daniel van Flymen, il ne semble pas sûr de retirer les clés et de les utiliser
--squash
, car elles seront toujours visibles dans l'historique (docker history --no-trunc
).Au lieu de cela, avec Docker 18.09, vous pouvez désormais utiliser la fonction "build secrets". Dans mon cas, j'ai cloné un dépôt git privé en utilisant la clé SSH de mon hôte avec les éléments suivants dans mon Dockerfile:
Pour pouvoir l'utiliser, vous devez activer le nouveau backend BuildKit avant de lancer
docker build
:Et vous devez ajouter le
--ssh default
paramètre àdocker build
.Plus d'informations à ce sujet ici: https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066
la source
ssh-add ~/.ssh/id_rsa
et 2) ajouter l'hôte git à known_hosts, c'est-à-dire pour bitbucket:RUN ssh-keyscan -H bitbucket.org >> ~/.ssh/known_hosts
Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access and the repository exists.
cela malgré le passage du--ssh default
drapeau dans ma génération de docker et l'utilisation--mount=type=ssh
de la commande d'exécution où jegit clone
. Je suis en mesure de cloner le même dépôt sans problème sur la machine de génération. Il échoue simplement dans le conteneur de construction de docker. Je soupçonne que la version mac de Docker ne fait pas passer le client ssh.Ce problème est vraiment ennuyeux. Comme vous ne pouvez pas ajouter / copier de fichier en dehors du contexte dockerfile, ce qui signifie qu'il est impossible de simplement lier ~ / .ssh / id_rsa dans /root/.ssh/id_rsa de l'image, et quand vous avez définitivement besoin d'une clé pour faire quelque chose de sshed comme git clone à partir d'un lien de dépôt privé ..., lors de la construction de votre image docker.
Quoi qu'il en soit, j'ai trouvé une solution de contournement, pas si convaincante, mais j'ai travaillé pour moi.
dans votre dockerfile:
un script à faire en une seule séance:
chaque fois que vous devez exécuter un conteneur à partir de cette image avec des exigences ssh, ajoutez simplement -v pour la commande run, comme:
docker run -v ~ / .ssh / id_rsa: /root/.ssh/id_rsa --nom de commande d'image de conteneur
Cette solution n'entraîne aucune clé privée à la fois dans la source de votre projet et dans l'image docker intégrée, donc plus de problème de sécurité à craindre.
la source
docker cp
? Il est utilisé pour «copier des fichiers / dossiers entre un conteneur et votre hôte».docker cp
pourrait faire l'affaire. Cependant, dans cette situation même, j'avais besoin de ssh_key pendant la construction de l'image, et il n'y a pas de conteneur à ce moment ... mettra à jour mon expression peu claire, merci quand même.J'ai rencontré le même problème aujourd'hui et une version légèrement modifiée avec les messages précédents, j'ai trouvé cette approche plus utile pour moi
(Notez que le drapeau en lecture seule pour que le conteneur ne gâche pas ma clé ssh dans tous les cas.)
À l'intérieur du conteneur, je peux maintenant exécuter:
Je n'ai donc pas cette
Bad owner or permissions on /root/.ssh/..
erreur qui a été notée par @krossla source
ssh-agent bash -c "ssh-add..."
. Je peux ensuite passer ce droit dans Docker Run. Tous les exemples précédents que j'ai trouvés utiliséseval ssh-agent
, suivis de ssh-add et je n'ai pas pu trouver un moyen de passer celaeval
via la commande docker run.'vous pouvez laisser sélectivement les serveurs distants accéder à votre agent ssh local comme s'il s'exécutait sur le serveur'
https://developer.github.com/guides/using-ssh-agent-forwarding/
la source
Vous pouvez également lier votre répertoire .ssh entre l'hôte et le conteneur, je ne sais pas si cette méthode a des implications en termes de sécurité mais c'est peut-être la méthode la plus simple. Quelque chose comme ça devrait fonctionner:
N'oubliez pas que docker fonctionne avec sudo (sauf si vous ne le faites pas), si tel est le cas, vous utiliserez les clés ssh racine.
la source
Bad owner or permissions on /root/.ssh/config
.docker run
, mais pas pendantdocker build
.À partir de
docker API 1.39+
(Vérifier la version de l'API avecdocker version
), la version--ssh
Docker permet l' option avec un socket d'agent ou des clés pour permettre au moteur Docker de transférer les connexions de l'agent SSH.Commande Build
Dockerfile
Plus d'informations:
la source
could not parse ssh: [default=~/.ssh/id_rsa]: stat ~/.ssh/id_rsa: no such file or directory
. Utilisez le chemin complet s'il ne fonctionne pas.Si vous ne vous souciez pas de la sécurité de vos clés SSH, il existe de nombreuses bonnes réponses ici. Si vous le faites, la meilleure réponse que j'ai trouvée provient d'un lien dans un commentaire ci-dessus vers ce commentaire GitHub par diegocsandrim . Pour que les autres soient plus susceptibles de le voir, et juste au cas où le dépôt disparaîtrait, voici une version éditée de cette réponse:
La plupart des solutions finissent ici par laisser la clé privée dans l'image. C'est mauvais, car toute personne ayant accès à l'image a accès à votre clé privée. Comme nous ne savons pas assez sur le comportement de
squash
, cela peut toujours être le cas même si vous supprimez la clé et écrasez ce calque.Nous générons une URL de pré-signature pour accéder à la clé avec aws s3 cli, et limitons l'accès pendant environ 5 minutes, nous enregistrons cette URL de pré-signature dans un fichier dans le répertoire repo, puis dans dockerfile nous l'ajoutons à l'image.
Dans dockerfile, nous avons une commande RUN qui effectue toutes ces étapes: utilisez l'URL pré-chant pour obtenir la clé ssh, exécutez npm install et supprimez la clé ssh.
En faisant cela dans une seule commande, la clé ssh ne serait stockée dans aucune couche, mais l'URL de pré-signature sera stockée, et ce n'est pas un problème car l'URL ne sera pas valide après 5 minutes.
Le script de construction ressemble à ceci:
Dockerfile ressemble à ceci:
la source
Dans les versions ultérieures de docker (17.05), vous pouvez utiliser des versions à plusieurs étapes . Quelle est l'option la plus sûre car les versions précédentes ne peuvent être utilisées que par la génération suivante et sont ensuite détruites
Voir la réponse à ma question stackoverflow pour plus d'informations
la source
Un aperçu concis des défis de SSH à l'intérieur des conteneurs Docker est détaillé ici . Pour vous connecter à des télécommandes de confiance à l'intérieur d'un conteneur sans divulguer de secrets, il existe plusieurs façons:
~/.ssh
au conteneur. (Développement uniquement, potentiellement non sécurisé)Au-delà de cela, il est également possible d'utiliser un magasin de clés fonctionnant dans un conteneur Docker séparé accessible lors de l'exécution lors de l'utilisation de Compose. L'inconvénient ici est une complexité supplémentaire due à la machinerie requise pour créer et gérer un magasin de clés tel que Vault by HashiCorp .
Pour une utilisation de la clé SSH dans un conteneur Docker autonome, consultez les méthodes liées ci-dessus et considérez les inconvénients de chacune en fonction de vos besoins spécifiques. Si, cependant, vous exécutez à l'intérieur de Compose et que vous souhaitez partager une clé d'une application au moment de l'exécution (reflétant les aspects pratiques de l'OP), essayez ceci:
docker-compose.env
fichier et ajoutez-le à votre.gitignore
fichier.docker-compose.yml
et ajoutezenv_file
pour le service nécessitant la clé.process.node.DEPLOYER_RSA_PUBKEY
dans le cas d'une application Node.js.L'approche ci-dessus est idéale pour le développement et les tests et, bien qu'elle puisse satisfaire les exigences de production, en production, il vaut mieux utiliser l'une des autres méthodes identifiées ci-dessus.
Ressources supplémentaires:
la source
Vous pouvez utiliser la construction en plusieurs étapes pour créer des conteneurs Voici l'approche que vous pouvez adopter: -
Étape 1 Construire une image avec ssh
Étape 2: construisez votre conteneur
ajoutez l'attribut env dans votre fichier de composition:
puis passez les arguments du script de construction comme ceci:
Et retirez le conteneur intermédiaire pour plus de sécurité. Cela vous aidera à applaudir.
la source
Un moyen simple et sécurisé pour y parvenir sans enregistrer votre clé dans une couche d'image Docker ou passer par la gymnastique ssh_agent est:
Dans l'une des étapes de votre
Dockerfile
, créez un.ssh
répertoire en ajoutant:RUN mkdir -p /root/.ssh
En dessous, cela indique que vous souhaitez monter le répertoire ssh en tant que volume:
VOLUME [ "/root/.ssh" ]
Assurez-vous que votre conteneur
ssh_config
sait où trouver les clés publiques en ajoutant cette ligne:RUN echo " IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config
Exposez le
.ssh
répertoire de votre utilisateur local au conteneur lors de l'exécution:docker run -v ~/.ssh:/root/.ssh -it image_name
Ou dans votre
dockerCompose.yml
ajouter ceci sous la clé de volume du service:- "~/.ssh:/root/.ssh"
Votre finale
Dockerfile
devrait contenir quelque chose comme:la source
J'essaie de résoudre le problème dans l'autre sens: en ajoutant une clé publique ssh à une image. Mais dans mes essais, j'ai découvert que "docker cp" est destiné à la copie D'un conteneur vers un hôte. Le point 3 de la réponse de creak semble dire que vous pouvez utiliser docker cp pour injecter des fichiers dans un conteneur. Voir https://docs.docker.com/engine/reference/commandline/cp/
extrait
la source
Vous pouvez passer les clés autorisées dans votre conteneur à l'aide d'un dossier partagé et définir des autorisations à l'aide d'un fichier docker comme celui-ci:
Et votre docker run contient quelque chose comme ce qui suit pour partager un répertoire d'authentification sur l'hôte (contenant les authorised_keys) avec le conteneur, puis ouvrez le port ssh qui sera accessible via le port 7001 sur l'hôte.
Vous voudrez peut-être regarder https://github.com/jpetazzo/nsenter qui semble être une autre façon d'ouvrir un shell sur un conteneur et d'exécuter des commandes dans un conteneur.
la source
Tard dans la soirée, certes, que diriez-vous de cela qui rendra vos clés de système d'exploitation hôte disponibles pour rooter à l'intérieur du conteneur, à la volée:
Je ne suis pas en faveur de l'utilisation de Dockerfile pour installer des clés car les itérations de votre conteneur peuvent laisser des clés privées derrière.
la source
J'essayais de comprendre comment ajouter des clés de signature à un conteneur à utiliser pendant l'exécution (pas de génération) et suis tombé sur cette question. Les secrets de Docker semblent être la solution pour mon cas d'utilisation, et puisque personne ne l'a encore mentionné, je vais l'ajouter.
la source
Dans mon cas, j'ai eu un problème avec nodejs et 'npm i' à partir d'un référentiel distant. J'ai corrigé l'ajout de l'utilisateur 'node' au conteneur nodejs et 700 à ~ / .ssh dans le conteneur.
Dockerfile:
run.sh:
docker-compose.yml:
après cela, il a commencé à travailler
la source
Manière la plus simple, obtenez un compte de tableau de bord et utilisez: ssh-import-id
la source
ssh-import-id
il semble qu'il importe uniquement les clés publiques.Dans un conteneur Docker en cours d'exécution, vous pouvez émettre ssh-keygen avec l'option docker -i (interactive). Cela transmettra les invites du conteneur pour créer la clé à l'intérieur du conteneur Docker.
la source
Pour debian / root / authorized_keys:
la source