Moby: SSH-Schlüsselagenten in Container weiterleiten

Erstellt am 13. Juni 2014  ·  190Kommentare  ·  Quelle: moby/moby

Es wäre schön, während eines run oder build einen SSH-Schlüsselagenten in einen Container weiterleiten zu können.
Häufig müssen wir Quellcode erstellen, der in einem privaten Repository vorhanden ist, in dem der Zugriff durch einen SSH-Schlüssel gesteuert wird.

Das Hinzufügen der Schlüsseldatei zum Container ist eine schlechte Idee, da:

  1. Du hast gerade die Kontrolle über deinen SSH-Schlüssel verloren
  2. Ihr Schlüssel muss möglicherweise über eine Passphrase entsperrt werden
  3. Ihr Schlüssel befindet sich möglicherweise überhaupt nicht in einer Datei und ist nur über den Schlüsselagenten zugänglich.

Sie könnten so etwas tun:

# docker run -t -i -v "$SSH_AUTH_SOCK:/tmp/ssh_auth_sock" -e "SSH_AUTH_SOCK=/tmp/ssh_auth_sock" fedora ssh-add -l
2048 82:58:b6:82:c8:89:da:45:ea:9a:1a:13:9c:c3:f9:52 phemmer<strong i="15">@whistler</strong> (RSA)

Aber:

  1. Dies funktioniert nur für docker run , nicht für build .
  2. Dies funktioniert nur, wenn der Docker-Daemon auf demselben Host wie der Client ausgeführt wird.

Die ideale Lösung besteht darin, dass der Client den Schlüsselagenten-Socket so weiterleitet, wie es ssh kann.
Die Schwierigkeit dabei besteht jedoch darin, dass die Remote-API-Build- und Attach-Aufrufe erforderlich sind, um das Proxying einer beliebigen Anzahl von Socket-Streams zu unterstützen. Es reicht nicht aus, nur einen einzigen 2-Wege-Stream zu erstellen, da der ssh-Schlüsselagent ein Unix-Domain-Socket ist und mehrere gleichzeitige Verbindungen haben kann.

aresecurity exintermediate kinfeature

Hilfreichster Kommentar

@kienpham2000 , warum würde diese Lösung den Schlüssel nicht in der Bildebene behalten? Die Aktionen zum Kopieren und Entfernen des Schlüssels werden in getrennten Befehlen ausgeführt, daher gibt es eine Ebene, die den Schlüssel enthalten sollte.
Unser Team hat Ihre Lösung bis gestern verwendet, aber wir haben eine verbesserte Lösung gefunden:

  • Wir generieren eine Pre-Sign-URL, um mit aws s3 cli auf den Schlüssel zuzugreifen, und begrenzen den Zugriff für ca. 5 Minuten. Wir speichern diese Pre-Sign-URL in einer Datei im Repo-Verzeichnis und fügen sie dann in Dockerfile dem Bild hinzu.
  • In dockerfile haben wir einen RUN-Befehl, der all diese Schritte ausführt: Verwenden Sie die Pre-Sing-URL, um den ssh-Schlüssel zu erhalten, führen Sie npm install aus und entfernen Sie den ssh-Schlüssel.
    Wenn Sie dies in einem einzigen Befehl tun, wird der ssh-Schlüssel in keiner Schicht gespeichert, sondern die Pre-Sign-URL wird gespeichert, und dies ist kein Problem, da die URL nach 5 Minuten nicht mehr gültig ist.

Das Build-Skript sieht so aus:

# build.sh
aws s3 presign s3://my_bucket/my_key --expires-in 300 > ./pre_sign_url
docker build -t my-service .

Dockerfile sieht so aus:

FROM node

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    ssh -o StrictHostKeyChecking=no [email protected] || true && \
    npm install --production && \
    rm ./my_key && \
    rm -rf ~/.ssh/*

ENTRYPOINT ["npm", "run"]

CMD ["start"]

Alle 190 Kommentare

Ich frage mich, ob #6075 dir das gibt, was du brauchst

Ein Geheimbehälter macht es vielleicht ein bisschen sicherer, aber alle genannten Punkte gelten trotzdem.

+1 Ich würde diese Funktion auch nützlich finden. Insbesondere beim Bauen von Containern, die beispielsweise Software aus privaten Git-Repos benötigen. Ich möchte lieber keinen Repo-Schlüssel in den Container freigeben und möchte stattdessen in der Lage sein, den "Docker-Build ..." auf eine andere Weise zu verwenden, um Zugriff auf die entsperrten SSH-Schlüssel zu erhalten, möglicherweise über eine laufende ssh -Agent.

+1. Ich fange gerade an, mit Docker nass zu werden, und dies war die erste Barriere, die ich traf. Ich habe eine Weile versucht, VOLUME zu verwenden, um die Authentifizierungssocke zu mounten, bevor mir klar wurde, dass Docker ein Host-Volume während eines Builds nicht mounten kann / wird.

Ich möchte nicht, dass Kopien eines passwortlosen SSH-Schlüssels herumliegen und die Mechanik, einen in einen Container zu kopieren und ihn dann während des Builds zu löschen, fühlt sich falsch an. Ich arbeite innerhalb von EC2 und habe nicht einmal ein gutes Gefühl, meine privaten Schlüssel dort oben zu kopieren (passwortlos oder nicht).

Mein Anwendungsfall ist das Erstellen eines Erlang-Projekts mit Rebar. Natürlich _könnte_ ich das erste Repo klonen und es mit einer Dockerfile zum Image HINZUFÜGEN, aber das funktioniert nicht mit privaten Abhängigkeiten, die das Projekt hat. Ich denke, ich könnte das Projekt einfach auf dem Hostcomputer erstellen und das Ergebnis zum neuen Docker-Image HINZUFÜGEN, aber ich würde es gerne in der Sandbox Docker erstellen.

Hier sind einige andere Leute, die den gleichen Anwendungsfall haben: https://twitter.com/damncabbage/status/453347012184784896

Bitte umarmen Sie SSH_AUTH_SOCK, es ist sehr nützlich.

Danke

Bearbeiten: Jetzt, da ich mehr über die Funktionsweise von Docker (FS-Schichten) weiß, ist es unmöglich, das zu tun, was ich in Bezug auf das Hinzufügen eines SSH-Schlüssels während eines Builds und das spätere Löschen beschrieben habe. Der Schlüssel wird in einigen FS-Schichten noch vorhanden sein.

+1, die Verwendung von SSH_AUTH_SOCK wird sehr nützlich sein!

Ich verwende SSH-Schlüssel, um mich bei Github zu authentifizieren, egal ob es sich um ein privates oder ein öffentliches Repository handelt.

Das bedeutet, dass meine git clone Befehle wie folgt aussehen: git clone [email protected]:razic/my-repo.git .

Ich kann mein Host-Verzeichnis ~/.ssh in meine Container einbinden, während ein docker run und ssh alles gut ist. Ich kann meine ~/.ssh während eines docker build mounten.

:+1: für die SSH-Weiterleitung während des Builds.

Soweit ich weiß, ist dies der falsche Weg. Der richtige Weg ist, ein Docker-Image in der Entwicklungsmaschine zu erstellen und es dann auf den Docker-Server zu kopieren.

@SevaUA - nein das stimmt nicht. Diese Anfrage ist auf eine Einschränkung bei der Ausführung von docker build... . Sie können eine Variable nicht wie bei einem docker run ... in diese Phase exportieren. Der Befehl run ermöglicht den Export von Variablen in den Docker-Container während der Ausführung, während der Build dies nicht zulässt. Diese Einschränkung ist teilweise beabsichtigt und basiert auf der Funktionsweise von Dockerd beim Erstellen von Containern. Aber es gibt Möglichkeiten, dies zu umgehen, und der beschriebene Anwendungsfall ist gültig. Diese Anfrage versucht also, diese Fähigkeit in gewisser Weise in Build zu implementieren.

Ich mag die Idee von #6697 (geheimer Speicher/Tresor), und das könnte dafür funktionieren, sobald es zusammengeführt ist. Aber wenn das nicht funktioniert, ist eine Alternative, transparentes Man-in-the-Middle-Proxy-SSH-Zeug zu machen außerhalb des Docker-Daemons, Abfangen des Docker-Daemon-Datenverkehrs (nicht intern). Alternativ könnten alle git+ssh-Anfragen an einen lokal definierten Host gerichtet sein, der transparent github oder was auch immer Sie letztendlich erreichen möchten, proxies.

Diese Idee wurde bereits angesprochen (siehe Kommentar 2). Es löst das Problem nicht.

+1 für SSH-Weiterleitung während Builds.

+1 für SSH-Agentenweiterleitung auf docker build

+1 für ssh-Weiterleitung während des Builds für npm install oder ähnliches.

Hat jemand die ssh-Weiterleitung während der Ausführung unter OSX zum Laufen gebracht? Ich habe hier eine Frage gestellt: http://stackoverflow.com/questions/27036936/using-ssh-agent-with-docker/27044586?noredirect=1#comment42633776_27044586 es sieht so aus, als wäre dies mit OSX nicht möglich ...

+1 =(

Überqueren Sie auch diese Straßensperre. Der Versuch, npm install auszuführen, zeigte auf ein privates Repo. einstellung sieht so aus:
host -> vagrant -> docker kann SSH-Agenten weiterleiten host -> vagrant -! docker

+1
Klicken Sie einfach darauf, während Sie versuchen, herauszufinden, wie Sie den ssh-Agenten während des 'Docker-Builds' zum Laufen bringen.

+1 wie die vorherigen Jungs. Scheint die beste Lösung für dieses Problem zu sein, wenn Sie beim Erstellen des Docker-Images auf ein oder mehrere private Git-Repositorys zugreifen müssen (denken Sie beispielsweise an bundle install und npm install ).

Ich kann mein Hostverzeichnis ~/.ssh während eines Docker-Laufs in meine Container einbinden und ssh ist in Ordnung.

@razic Können Sie Laufen bringen? Denn als ich das zuvor versuchte, beschwerte es sich über "Schlechte Besitzer oder Berechtigungen"

Es sei denn, Sie stellen sicher, dass alle Container mit einem bestimmten Benutzer oder Berechtigungen ausgeführt werden, die Ihnen dies ermöglichen?

+1 für SSH_AUTH_SOCK

@tonivdv sehen Sie sich den Befehl docker run im ersten Kommentar zu diesem Problem an. Es bindet den Pfad, auf den sich SSH_AUTH_SOCK bezieht, in /tmp/ssh_auth_sock innerhalb des Containers ein und setzt dann SSH_AUTH_SOCK im Container auf diesen Pfad.

@md5 Ich gehe davon aus, dass @tonivdv so über das Mounten sprechen: -v ~/.ssh:/root/.ssh:ro , aber wenn Sie dies tun, sind die .ssh-Dateien nicht im Besitz von Root und bestehen daher die Sicherheitsprüfungen nicht.

@KyleJamesWalker yup, das verstehe ich von @razic und das war vor einiger Zeit einer meiner Versuche. Als ich also las, dass @razic es funktioniert, habe ich mich gefragt, wie :)

@tonivdv Ich würde auch gerne wissen, ob es möglich ist, ich konnte beim letzten Versuch jedoch nichts finden.

+1 Ich bin daran interessiert, mit Docker Einweg-Entwicklungsumgebungen zu erstellen, aber ich kann es nicht ganz zum Laufen bringen. Dies würde in dieser Hinsicht sehr helfen.

Für alle, die nach einer vorübergehenden Lösung suchen, habe ich einen Fix, den ich verwende, der Dinge mit Brute Forces einsetzt:

https://github.com/atrauzzi/docker-laravel/blob/master/images/php-cli/entrypoint.sh

Es ist keineswegs eine wünschenswerte Lösung, da es ein ganzes Einstiegspunktskript erfordert, aber es funktioniert.

@atrauzzi interessanter Ansatz. Für unsere dev env bauen wir ein Basis-Image und kopieren den ssh-Schlüssel direkt hinein. Es hat den Vorteil, dass es nicht bei jedem Durchlauf bereitgestellt werden muss. Und jedes Bild, das standardmäßig von diesem Magier erbt, enthält auch den Schlüssel. Mit unserer Art können Sie es jedoch offensichtlich nicht öffentlich teilen ;p

+1 das wäre toll

@tonivdv Der Container, für den das Skript bestimmt ist, wird häufig erstellt und zerstört, da er nur ein Host für CLI-Tools ist. Es steht Ihnen natürlich frei, die Operation nur einmal durchzuführen. Aber wenn jemand seine Einstellungen ändert und einen Befehl über den Container erneut ausführt, muss es jedes Mal eine neue Kopie sein.

@atrauzzi Ich verstehe. Ihr Ansatz sollte von Docker-Images übernommen werden, die möglicherweise einen privaten SSH-Schlüssel erfordern. Beispielsweise sollte ein Composer-Image Ihr Einstiegspunkt-Skript bei privaten Repos enthalten. Zumindest bis Docker mit einer nativen Lösung kommt.

:+1: für ssh-Weiterleitung über build

Auch hier ein Muss!

@atrauzzi Ich verwende derzeit einen anderen Ansatz, der mir sehr gefällt. Es erstellt einen Datenvolumen-Container mit dem SSH-Zeug darin. Wenn Sie Ihre SSH-Schlüssel in einen anderen Container verwenden möchten, kann ich das einfach mit dem folgenden Befehl verwenden:

docker run -ti --volumes-from ssh-data ...

Auf diese Weise müssen Sie nicht jedes Bild mit einem Einstiegspunkt versehen und es kann mit allen Bildern arbeiten.

Um diesen Container zu erstellen, gehe ich wie folgt vor:

docker run \
  --name ssh-data \
  -v /root/.ssh \
  -v ${USER_PRIVATE_KEY}:/root/.ssh/id_rsa \
  busybox \
  sh -c 'chown -R root:root ~/.ssh && chmod -R 400 ~/.ssh'

Hoffe das kann anderen helfen :)

Beifall

@tonivdv - Ich habe meinen Ansatz gewählt, denn wenn jemand SSH-Einstellungen hinzufügen oder aktualisieren muss, müssen sie erneut importiert werden. Der spezifische Container, den ich verwende, ist einer, der für die Ausführung einzelner Befehle erstellt wird, sodass bei jeder Ausführung eine Kopie erstellt wird, um sicherzustellen, dass er auf dem neuesten Stand ist.

@atrauzzi Ja, ich verstehe. Davon abgesehen liegt es am Benutzer, seinen SSH-Volume-Container korrekt zu verwalten. Er kann bei Bedarf sogar andere verwenden. Und optional kann es im laufenden Betrieb mit einem Skript generiert werden. Aber ich glaube nicht, dass es die eine und einzige gute Lösung gibt. Es hängt alles von den Bedürfnissen ab. Ich wollte es nur teilen, damit andere die Lösung basierend auf ihren Bedürfnissen auswählen können. Ich hoffe, bald darüber bloggen zu können, und ich freue mich auch auf Ihre Lösung! Beifall

Ich würde es nicht zur Anforderung machen, dass Leute, die Ihre Container ausführen, einen Nur-Daten-Container voller SSH-Schlüssel verwalten. Scheint beteiligt zu sein.

@atrauzzi Es stimmt, dass der Volume-Container vorhanden sein muss, aber auf Ihre Weise muss der Benutzer seinen ssh-Schlüssel freigeben, wenn er auch ausgeführt wird, oder? Abgesehen von der Notwendigkeit eines ssh-Volume-Containers besteht der einzige Unterschied zwischen beiden Lösungen aus betriebswirtschaftlicher Sicht darin:

docker run ... --volumes-from ssh-data ... php-cli ...

und

docker run ... -v ~/.ssh:/path/.host-ssh ... php-cli ..

Rechts? Oder übersehe ich noch was :)

Aber ich verstehe vollkommen, warum du es auf deine Art machst. Wenn Sie jedoch zB ein Composer-Image von jemand anderem verwenden möchten, funktioniert der Volume-from-Weg sofort. Zumindest vermeidet es, mit dem "Entrypoint-Hack" ein eigenes Image zu erstellen.

Wie gesagt, beides ist ein Workaround und beide haben Vor- und Nachteile.

Beifall

Es wäre wirklich toll, vom Docker-Team ein Update zum Status dieser Funktion zu erhalten. Insbesondere die SSH-Authentifizierung von docker build .

Dies nähert sich bereits 1 Jahr. Irgendwie überraschend, wenn man bedenkt, wie praktisch praktische Anwendungsfälle dafür sind. Derzeit generieren wir Bilder dynamisch, indem wir laufende Container festschreiben. Wir können kein Dockerfile im Repository unserer Anwendung haben. Dies unterbricht den Fluss für praktisch alles. Ich kann meine Anwendung nicht wirklich mit Docker-Diensten wie Compose oder Swarm verwenden, bis dies behoben ist.

Ein Update wäre super dankbar. Bitte und Dankeschön.

/cc @phemmer

Es ist nicht so, dass wir diese Funktion oder ähnliches nicht wollen, ich sehe wirklich einen Anwendungsfall für so etwas oder Geheimnisse im Build. Wir brauchen nur einen Vorschlag von jemandem, der zur Implementierung bereit ist, und dann, wenn die Implementierung des Vorschlags genehmigt wird.
Auch spreche ich im Namen von mir nicht alle Betreuer.

@jfrazelle

Ich weiß, ihr ignoriert uns nicht :)

Der Status ist also:

Es ist etwas, das wir in Betracht ziehen würden, es umzusetzen, wenn es einen akzeptierten Vorschlag gibt
und Engineering-Bandbreite.

Klingt das für Sie richtig?

Gibt es derzeit auch offene Vorschläge, die sich mit diesem Problem befassen?

Am Dienstag, den 7. April 2015, schrieb Jessie Frazelle [email protected] :

Es ist nicht so, dass wir diese Funktion nicht wollen oder so, ich sehe wirklich einen Nutzen
Fall für so etwas oder Geheimnisse im Build bräuchten wir nur einen
Vorschlag von jemandem, der zur Umsetzung bereit ist, und dann, falls genehmigt, die
Umsetzung des Vorschlags.
Auch spreche ich im Namen von mir nicht alle Betreuer.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90737847.

Es ist etwas, das wir in Betracht ziehen würden, es umzusetzen, wenn es einen akzeptierten Vorschlag gibt
und Engineering-Bandbreite.

ja

Und ich glaube, dafür gibt es keine offenen Vorschläge.

Am Di, 7. April 2015 um 14:36 ​​Uhr, Zachary Adam Kaplan <
[email protected]> schrieb:

@jfrazelle

Ich weiß, ihr ignoriert uns nicht :)

Der Status ist also:

Es ist etwas, das wir in Betracht ziehen würden, es umzusetzen, wenn es einen akzeptierten Vorschlag gibt
und Engineering-Bandbreite.

Klingt das für Sie richtig?

Gibt es derzeit auch offene Vorschläge, die sich mit diesem Problem befassen?

Am Dienstag, 7. April 2015, Jessie Frazelle [email protected]
schrieb:

Es ist nicht so, dass wir diese Funktion nicht wollen oder so, ich sehe wirklich einen Nutzen
Fall für so etwas oder Geheimnisse im Build bräuchten wir nur einen
Vorschlag von jemandem, der zur Umsetzung bereit ist, und dann, falls genehmigt, die
Umsetzung des Vorschlags.
Auch spreche ich im Namen von mir nicht alle Betreuer.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90737847.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90738913.

Ich weiß nicht, ob ich die Dinge zu stark vereinfache, aber hier ist mein Vorschlag:

SSHAGENT: forward # wird standardmäßig ignoriert

Wenn gesetzt, werden der Socket und die zugehörigen Umgebungsvariablen während des Builds mit dem Container verbunden, wo sie verwendet werden können. Die mechanischen Teile davon existieren bereits und funktionieren, es ist nur eine Frage, sie in docker build .

Ich habe keine Erfahrung mit der Arbeit mit der Docker-Codebasis, aber das ist mir wichtig genug, dass ich es in Betracht ziehen würde, es zu übernehmen.

Toll. Wo erfahre ich, wie ich einen Vorschlag einreiche? Gibt es ein
bestimmte Richtlinie oder sollte ich einfach ein Problem eröffnen?

Am Dienstag, den 7. April 2015, schrieb Jessie Frazelle [email protected] :

Es ist etwas, das wir in Betracht ziehen würden, es zu implementieren, wenn es akzeptiert wird
Vorschlag
und Engineering-Bandbreite.

ja

Und ich glaube, dafür gibt es keine offenen Vorschläge.

Am Di, 7. April 2015 um 14:36 ​​Uhr, Zachary Adam Kaplan <
[email protected]
<_e i="18">

@jfrazelle

Ich weiß, ihr ignoriert uns nicht :)

Der Status ist also:

Es ist etwas, das wir in Betracht ziehen würden, es zu implementieren, wenn es akzeptiert wird
Vorschlag
und Engineering-Bandbreite.

Klingt das für Sie richtig?

Gibt es derzeit auch offene Vorschläge, die sich mit diesem Problem befassen?

Am Dienstag, 7. April 2015, Jessie Frazelle < [email protected]
<_e i="31"/> schrieb:

Es ist nicht so, dass wir diese Funktion nicht wollen oder so, ich sehe wirklich ein
benutzen
Fall für so etwas oder Geheimnisse im Build bräuchten wir nur einen
Vorschlag von jemandem, der zur Umsetzung bereit ist, und dann, falls genehmigt, die
Umsetzung des Vorschlags.
Auch spreche ich im Namen von mir nicht alle Betreuer.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90737847.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90738913.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90739596.

Ich meine wie ein Designvorschlag
https://docs.docker.com/project/advanced-contributing/#design -proposal

Am Di, 7. April 2015 um 14:39, Daniel Staudigel [email protected]
schrieb:

Ich weiß nicht, ob ich die Dinge zu stark vereinfache, aber hier ist mein Vorschlag:

SSHAGENT: forward # wird standardmäßig ignoriert

Wenn während des Builds gesetzt, sind der Socket und die zugehörigen Umgebungsvariablen
mit dem Container verbunden, wo sie verwendet werden können. Die mechanischen Teile
davon existieren bereits und funktionieren, es geht nur ums Anschließen
sie im Docker-Build.

Ich habe keine Erfahrung mit der Arbeit in der Docker-Codebasis, aber dies
ist mir wichtig genug, dass ich es in Erwägung ziehen würde.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90739803.

Dies ist eine wirklich hochrangige Idee, aber was wäre, wenn Docker, anstatt über die Docker-Remote-API anzuhängen, einen Init-Daemon mit einem gebündelten ssh-Daemon im Container ausführen würde?

Dies könnte verwendet werden, um eine Reihe von Problemen zu lösen.

  • Dieser Daemon wäre PID 1 und der Hauptcontainerprozess wäre PID 2. Dies würde alle Probleme lösen, bei denen PID 1 Signale ignoriert und Container nicht richtig heruntergefahren werden. (#3793)
  • Dies würde eine saubere Weiterleitung des SSH-Schlüsselagenten ermöglichen. (#6396)
  • Dieser Daemon könnte Namespaces offen halten (#12035)
  • Ein TTY würde vom Daemon erstellt (#11462)
  • ...und wahrscheinlich viele andere Probleme, die ich vergesse.

Vielleicht möchten Sie https://github.com/docker/docker/issues/11529 über das sehen
erster Aufzählungspunkt

Am Dienstag, 7. April 2015 um 14:46 Uhr, Patrick Hemmer [email protected]
schrieb:

Dies ist eine wirklich hochrangige Idee, aber was wäre, wenn, anstatt durchzuhängen?
die Docker-Remote-API, Docker führte einen Init-Daemon mit einem gebündelten ssh . aus
Dämon, im Container?

Dies könnte verwendet werden, um eine Reihe von Problemen zu lösen.

  • Dieser Daemon wäre PID 1 und der Hauptcontainerprozess wäre
    PID 2. Dies würde alle Probleme mit PID 1 lösen, die Signale ignorieren und
    Behälter schließen nicht richtig. (#3793
    https://github.com/docker/docker/issues/3793)
  • Dies würde eine saubere Weiterleitung des SSH-Schlüsselagenten ermöglichen. (#6396
    https://github.com/docker/docker/issues/6396)
  • Dieser Daemon könnte Namensräume offen halten (#12035
    https://github.com/docker/docker/issues/12035)
  • Ein TTY würde vom Daemon erstellt (#11462
    https://github.com/docker/docker/issues/11462)
  • ...und wahrscheinlich viele andere Probleme, die ich vergesse.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90741192.

11529 hat nichts mit dem PID-1-Problem zu tun.

Shoot Effing Copy Paste, jetzt muss ich den anderen wieder finden

Nein, es ist dieses, es behebt die PID 1-Zombie-Dinge, von denen ich dachte, dass Sie sich darauf beziehen, aber unabhängig davon habe ich nur gepostet, da es nur interessant ist

@phemmer Es hört sich so an, als hätten Sie das Fachwissen, um uns bei der Erstellung eines intelligenten Vorschlags für die Umsetzung zu unterstützen.

Es sieht auch aus wie @dts und ich bin bereit, Zeit damit zu verbringen, daran zu arbeiten.

@phemmer und @dts Gibt es eine Möglichkeit, diese Diskussion in einen etwas Echtzeit-Chat-Client zu bringen, um die Kommunikation zu erleichtern? Ich bin über Slack, Google Chat/Hangout, IRC erreichbar und lade bei Bedarf alles andere herunter.

@phemmer Es hört sich so an, als ob Sie die Expertise haben, uns bei der Erstellung eines intelligenten Vorschlags für die Umsetzung zu unterstützen

Leider nicht wirklich :-)
Ich kann Designideen wegwerfen, aber ich kenne nur kleine Teile der Docker-Codebasis. Diese Art der Änderung wird wahrscheinlich von großem Ausmaß sein.

Hier sind schon einige Vorschläge drin:

@phemmer vorgeschlagen

Was wäre, wenn Docker, anstatt eine Verbindung über die Docker-Remote-API herzustellen, einen Init-Daemon mit einem gebündelten ssh-Daemon im Container ausführen würde?

@dts vorgeschlagen

SSHAGENT: forward # wird standardmäßig ignoriert
Wenn gesetzt, werden der Socket und die zugehörigen Umgebungsvariablen während des Builds mit dem Container verbunden, wo sie verwendet werden können. Die mechanischen Teile davon sind bereits vorhanden und funktionieren, es geht nur darum, sie in Docker-Build zu verbinden.

@razic vorgeschlagen

Aktivieren Sie die Volume-Bindung für docker build .

Was wir an dieser Stelle wirklich brauchen, ist jemand, der einen von ihnen akzeptiert, damit wir anfangen können, daran zu arbeiten.

@jfrazelle Hast du eine Idee, wie wir zum nächsten Schritt kommen können? Wirklich, ich versuche nur, das zu erledigen. Es ist klar, dass das Interesse daran groß ist. Ich bin bereit, mich für das Feature einzusetzen und es bis zur Fertigstellung zu begleiten.

Ich kann für ein Slack/irc/Gchat/etc-Meeting zur Verfügung stehen, ich denke, dies wird die Dinge etwas erleichtern, zumindest um Anforderungen zu sammeln und eine vernünftige Vorgehensweise zu entscheiden.

@dts vorgeschlagen

SSHAGENT: forward # wird standardmäßig ignoriert

Dies ist nur eine Idee, wie es konsumiert werden würde, nicht implementiert. Der "init/ssh-Daemon" ist eine Idee, wie er implementiert werden könnte. Die beiden könnten beide existieren.

@razic vorgeschlagen

Aktivieren Sie die Volume-Bindung für die Docker-Ausführung.

Dies würde leider nicht funktionieren. Angenommen, dies bedeutet docker build und nicht docker run , das bereits Volume-Mounts unterstützt, der Client kann remote sein (boot2docker ist ein prominentes Beispiel). Volume-Bindungen funktionieren nur, wenn sich der Client auf demselben Host wie der Docker-Daemon befindet.

@razic bitte sehen Sie sich diesen Link zum Designvorschlag an ... das sind keine Vorschläge https://docs.docker.com/project/advanced-contributing/#design -proposal

@phemmer

Ich verstehe nicht genau, warum das nicht funktionieren kann. docker-compose arbeitet mit Volume-Mounts gegen einen swarm Cluster. Wenn sich die Datei/der Ordner nicht auf dem Hostsystem befindet, verhält sie sich genauso, als ob Sie -v mit einem nicht existierenden Pfad ausführen würden.

@jfrazelle Verstanden .

Wenn sich die Datei/der Ordner nicht auf dem Hostsystem befindet, verhält sie sich genauso, als ob Sie -v mit einem Pfad ausführen würden, der auf einem lokalen Docker nicht existiert.

Ich bin mir nicht sicher, ob ich Ihrem Punkt folgen kann. Wie hilft dieses Verhalten bei diesem Problem?
Wenn ein SSH-Schlüsselagent auf meinem lokalen Computer bei /tmp/ssh-UPg6h0 lauscht und Docker auf einem Remote-Computer ausgeführt wird und docker build aufgerufen wird, ist dieser lokale SSH-Schlüsselagent für den Docker-Daemon. Der Volume-Mount wird es nicht bekommen und die docker build Container haben keinen Zugriff auf den ssh-Schlüssel.

Von einer hohen Ebene aus sehe ich nur 2 Möglichkeiten, dies zu lösen:

1. Proxy für den SSH-Schlüssel-Agent-Socket:

Der Docker-Daemon erstellt einen Unix-Domain-Socket innerhalb des Containers und jedes Mal, wenn sich etwas damit verbindet, leitet er diese Verbindung zurück an den Client, der tatsächlich den docker build Befehl ausführt.

Dies kann schwierig zu implementieren sein, da es eine beliebige Anzahl von Verbindungen zu diesem Unix-Domain-Socket innerhalb des Containers geben kann. Dies würde bedeuten, dass der Docker-Daemon und der Client eine beliebige Anzahl von Verbindungen als Proxy bereitstellen müssen oder der Daemon in der Lage sein muss, das ssh-Agentenprotokoll zu sprechen und die Anfragen zu multiplexen.

Da die Docker-Remote-API jetzt jedoch Websockets unterstützt (das war zum Zeitpunkt der Erstellung dieses Problems nicht der Fall), ist dies möglicherweise nicht allzu schwer.

2. Starten Sie einen tatsächlichen SSH-Daemon

Anstatt den SSH-Agenten zu hacken, verwenden Sie eine tatsächliche SSH-Verbindung vom Client zum Container. Der Docker-Client hätte entweder einen SSH-Client eingebunden oder würde ssh im Remote-Container aufrufen.
Dies wäre eine viel größere Änderung, da sie die Art und Weise ersetzen würde, wie das Anbringen an Containern implementiert wird. Aber es würde Docker auch davon ersparen, sich darum kümmern zu müssen, und auf Standardprotokolle migrieren.
Dies hat auch das Potenzial, andere Probleme zu lösen (wie hier erwähnt).

Letztendlich also eine viel größere Änderung, aber möglicherweise eine angemessenere Lösung.
Obwohl realistisch, bezweifle ich, dass dies aufgrund des Umfangs passieren wird.

@phemmer

Ich bin mir nicht sicher, ob ich Ihrem Punkt folgen kann. Wie hilft dieses Verhalten bei diesem Problem?

Denn der häufigste Anwendungsfall dafür sind Leute, die Images mit Abhängigkeiten erstellen, die in privaten Repositorys gehostet werden, die eine SSH-Authentifizierung erfordern.

Sie erstellen das Image auf einem Computer, der über einen SSH-Schlüssel verfügt. So einfach.

Wenn ich einen SSH-Schlüsselagenten habe, der auf meinem lokalen Computer auf /tmp/ssh-UPg6h0 lauscht, und Docker auf einem Remote-Computer ausgeführt wird und Docker build aufrufe, ist dieser lokale SSH-Schlüsselagent für den Docker-Daemon nicht zugänglich.

Ich weiss. Wen interessiert das? Ich werde docker build auf einem Computer ausführen, der Zugriff auf den Authentifizierungssocket hat.

Was ich damit sagen will ist.... docker-compose erlaubt Ihnen den volume-Befehl für einen swarm Cluster zu verwenden, unabhängig davon, ob sich die Datei tatsächlich auf dem Host befindet oder nicht! .

Dasselbe sollten wir für Volume-Mounts in Docker-Builds tun.

| Datei ist auf dem System | Aktion |
| :-- | :-- |
| Ja | Halterung |
| Nein | Keine (eigentlich versucht es zu mounten, erstellt aber einen leeren Ordner, wenn die Datei/der Ordner nicht existiert. Sie können dies überprüfen, indem Sie docker run -v /DOES_NOT_EXIST:/DOES_NOT_EXIST ubuntu ls -la /DOES_NOT_EXIST ausführen) |

Eines der Konzepte hinter swarm besteht darin, das Multi-Host-Modell transparent zu machen.

Es ist gut, dass wir über Remote Docker nachdenken, aber das sollte eigentlich keine Rolle spielen.

Wir sollten einfach das Verhalten für das Volume Mounten für docker build genauso kopieren wie für docker run .

Von https://github.com/docker/compose/blob/master/SWARM.md :

Das Wichtigste, was Multi-Container-Apps daran hindert, nahtlos auf Swarm zu arbeiten, besteht darin, sie dazu zu bringen, miteinander zu kommunizieren: Die private Kommunikation zwischen Containern auf verschiedenen Hosts wurde nicht auf eine nicht hackige Weise gelöst.

Langfristig wird das Netzwerk so überarbeitet, dass es viel besser zum Multi-Host-Modell passt. Derzeit werden verknüpfte Container automatisch auf demselben Host geplant.

@phemmer Ich denke, die Leute denken wahrscheinlich über eine Lösung für das von Ihnen beschriebene Problem nach. Das von Ihnen beschriebene Problem klingt wie https://github.com/docker/docker/issues/7249, was separat ist.

Wenn wir meinen Ansatz verfolgen : https://github.com/ beginnen. docker/docker/issues/7249, wodurch das Verhalten dieser Funktion auf die Arbeit mit Remote-Docker-Daemons erweitert würde, die nicht über die lokale Datei verfügen.

@cpuguy83 Bevor ich einen Vorschlag erstelle, habe ich mir #7133 angesehen und festgestellt, dass es direkt in Verbindung steht.

Könnten Sie hier noch ein paar Worte hinzufügen? Bezieht sich #7133 tatsächlich auf meinen Vorschlag, dieses Problem zu beheben, nämlich docker build die Unterstützung von Volumes zu ermöglichen.

@razic Dies hängt mit der Tatsache zusammen, dass VOLUME /foo tatsächlich ein Volume erstellt und es während des Builds in den Container einhängt, was im Allgemeinen unerwünscht ist.

Ich würde auch sagen, dass ein Vorschlag, der auf der Verwendung von Bind-Mounts basiert, um Dateien in Build-Container zu bekommen, wahrscheinlich nicht funktionieren wird.
Siehe #6697

Das Ausführen von -v mit docker build kann einen anderen Codeausführungspfad haben.
Anstatt ein Volume zu erstellen und es während des Builds zu montieren, können wir die
aktuelles Verhalten, dass Volumes in Dockerfiles nicht referenziert werden. Und
Handeln Sie stattdessen nur auf -v, wenn es mit Argumenten für die CLI ausgeführt wird.

Am Mittwoch, den 8. April 2015, schrieb Brian Goff [email protected] :

@razic https://github.com/razic Es bezieht sich auf die Tatsache, dass VOLUME
/foo erstellt tatsächlich ein Volume und mountet es in den Container während
bauen, was im Allgemeinen unerwünscht ist.

Ich würde auch sagen, ein Vorschlag, der auf der Verwendung von Bind-Mounts basiert, um Dateien in
Container bauen wird wahrscheinlich nicht fliegen.
Siehe #6697 https://github.com/docker/docker/pull/6697


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment -90905722.

@ cpuguy83 Danke für die Klarstellung.

6697 Wird auch nicht fliegen, da es bereits geschlossen ist und #10310 praktisch ein Duplikat von #6697 ist.

+1, ich bin heute gerade darauf gestoßen, als ich versuchte, ein Image für eine Rails-App zu erstellen, die Bower verwendet, um die clientseitigen Abhängigkeiten zu installieren. Es passiert, dass eine der Abhängigkeiten auf [email protected]:angular/bower-angular-i18n.git und da git dort fehlschlägt, schlägt Bower fehl und auch die Image-Erstellung schlägt fehl.

Ich mag übrigens sehr, was Landstreicher macht. Mit einer einzigen forward_agent-Konfiguration in der Vagrantfile wird dies für vagabundierende Gäste gelöst. Könnte Docker so etwas implementieren?

Als zusätzlicher Hinweis, dies geschieht während der Erstellung des Bildes. Kennt jemand existierende Workarounds?

Meine Problemumgehung bestand darin, ein neues RSA-Schlüsselpaar zu generieren, den Pub-Schlüssel auf github einzurichten (den Fingerabdruck hinzuzufügen) und den privaten Schlüssel zum Docker-Image hinzuzufügen:

ADD keys/docker_rsa /srv/.ssh/id_rsa

Ich würde das gerne vermeiden, aber ich denke, das ist jetzt akzeptabel. Alle anderen Vorschläge geschätzt!

Ich bin mir nicht sicher, wer mehr Welpen getötet hat. Sie dafür, oder Docker dafür, dass Sie noch keinen besseren Weg finden.

Jedenfalls werde ich wahrscheinlich dieses Wochenende einen Vorschlag unterbreiten. @cpuguy83 hat Recht, dass die Leute zumindest darüber nachdenken und mögliche Lösungen diskutieren. An diesem Punkt geht es also nur darum, dass wir uns auf etwas einigen und jemanden dazu bringen, daran zu arbeiten. Ich bin total bereit, daran zu arbeiten, da es derzeit einer meiner größten Probleme mit Docker ist.

@razic Es ist ein ziemlich häufiger Anwendungsfall, also danke, dass Sie sich auch damit befasst haben. Was den Workaround angeht, es funktioniert. Möglicherweise könnte der Schlüssel nach der Verwendung aus dem Image entfernt werden, schließlich wird er nur verwendet, um den Code der Anwendung von github zu erhalten.

@fullofcaffeine Ich bin mir nicht 100% sicher, wie Docker intern funktioniert, aber ich denke, es sei denn, es wird in einem einzigen RUN-Befehl ausgeführt (was mit Ihrer Problemumgehung unmöglich ist), dann behält der Verlauf des Images den SSH-Schlüssel bei.

@razic guter Punkt.

Um diese Einschränkung zu umgehen, haben wir mit der Idee herumgespielt, die privaten Schlüssel (von einem lokalen HTTP-Server) herunterzuladen, einen Befehl auszuführen, der die Schlüssel erfordert, und die Schlüssel anschließend zu löschen.

Da wir all dies in einem einzigen RUN tun, wird nichts im Bild zwischengespeichert. So sieht es im Dockerfile aus:

RUN ONVAULT npm install --unsafe-perm

Unsere erste Implementierung um dieses Konzept herum ist verfügbar unter https://github.com/dockito/vault

Der einzige Nachteil besteht darin, dass der HTTP-Server ausgeführt werden muss, sodass kein Docker-Hub erstellt wird.

Lass mich wissen was du denkst :)

+1
würde dies gerne implementiert sehen, es würde helfen, Container für die Entwicklungsumgebung einzurichten

+1, brauche nur weitergeleiteten ssh-agent mit boot2dock

Wir haben einen 3-Schritte-Prozess durchgeführt, um diese Einschränkung zu umgehen:

  1. Docker-Container ohne SSH-erforderliche Abhängigkeiten erstellen, Quelle im letzten Schritt hinzufügen
  2. mounten Sie die Quelle über ein freigegebenes Volume, plus SSH_AUTH_SOCK über ein freigegebenes Volume und führen Sie den Build-Schritt aus, indem Sie die ssh-erfordernde Ausgabe (z. B. github hosted ruby ​​gems) zurück in das freigegebene Volume schreiben
  3. Führen Sie Docker-Build erneut aus, wodurch das Hinzufügen der Quelle erneut ausgelöst wird, da sich die Gems jetzt im Quellverzeichnis befinden

Das Ergebnis ist ein Docker-Image mit über SSH-auth gezogenen Abhängigkeiten, das nie einen SSH-Schlüssel enthielt.

Ich habe ein Skript erstellt, um die SSH-Agentenweiterleitung für docker run in einer boot2docker-Umgebung unter OSX mit minimalem Aufwand zu aktivieren. Ich weiß, dass es das Build-Problem nicht löst, aber für einige nützlich sein könnte:

https://gist.github.com/rcoup/53e8dee9f5ea27a51855

Funktioniert der Forward-ssh-Schlüsselagent mit Diensten wie dem Amazon EC 2 Container-Dienst? Mir scheint, dass dies eine bestimmte Software erfordert, die möglicherweise nicht auf allen Plattformen oder PaaS verfügbar ist, die Sie zum Bereitstellen Ihrer Container verwenden.

Eine allgemeinere, für alle geeignete Lösung ist erforderlich.

Derzeit verwende ich Umgebungsvariablen. Ein Bash-Skript ruft die Variable des privaten Schlüssels (und der bekannten Hosts) ab und gibt sie in die Dateien id_rsa und known_hosts aus. Es funktioniert, aber ich muss noch die Sicherheitsauswirkungen einer solchen Lösung bewerten.

FWIW, ich habe festgestellt, dass ein containerisierter SSH-Agent und die gemeinsame Nutzung von Volumes mit minimalem Goofery gut funktionieren:

https://github.com/whilp/ssh-agent

Wäre aber toll, dafür erstklassigen Support zu bekommen.

Es ist wichtig zu unterscheiden, was in _run_ und _build_ funktioniert. Die Lösung von @whilp funktioniert wunderbar in _run_, funktioniert jedoch nicht in _build_, da Sie während _build_ nicht auf die Volumes anderer Docker zugreifen können. Daher ist dieses Ticket immer noch eine schmerzende, offene Wunde.

@rvowles ja, zugestimmt. Ich habe etwas zusammengestellt, um Container über eine Folge von Run/Commit-Aufrufen zu generieren (dh ohne Dockerfiles); das war für meinen speziellen Anwendungsfall sinnvoll, aber eine allgemeine Unterstützung (einschließlich Build-Zeit) für so etwas wie die Agentenweiterleitung wäre sehr hilfreich.

Sind IPs zum Ausführen von Containern während des Builds in /etc/hosts enthalten? Wenn dies der Fall ist, könnte eine Lösung darin bestehen, einen Container zu starten, der die Schlüssel bereitgestellt hat, und dann während des Builds darauf zu rollen.

Es könnte Sie alle interessieren, dass ich über eine Möglichkeit gebloggt habe, Ihren SSH-Agenten während der docker build - http://aidanhs.com/blog/post/2015-10-07-dockerfiles-reproducibility- Tricks/#_streamlining_your_experience_using_an_ssh_agent

Sie müssen nur einen einzelnen Container starten. Nach dem Start sollte der SSH-Agentenzugriff mit nur 3 zusätzlichen Zeilen in Ihrem Dockerfile einwandfrei funktionieren - Sie müssen Ihre Schlüssel nicht mehr für den Container freigeben.

Einige Vorbehalte: Sie benötigen Docker >= 1.8, und es funktioniert nicht auf einem automatisierten Docker Hub-Build (offensichtlich). Bitte beachten Sie auch den Sicherheitshinweis! Fühlen Sie sich frei, Probleme im sshagent-github-Repository zu melden, auf das ich im Beitrag verlinke, wenn Sie Probleme haben.

Ich habe dieses Problem auch auf ähnliche Weise wie bei @aidanhs gelöst - indem
https://github.com/mdsol/docker-ssh-exec

Gab es Fortschritte, um dies zu ermöglichen? Ich kann das Verzeichnis ~/.ssh des Hosts nicht bind-mounten, da Berechtigungen und Besitz durcheinander geraten.

Wäre dies nicht lösbar, indem man Bindungsmounts erlaubt, bestimmte UID/GID und Berechtigungen zu erzwingen?

@atrauzzi bind-mounts kann uid/gid/permissions nicht erzwingen.
Kann dies über FUSE (zB bindfs) tun, aber nicht nur mit normalen Bind-Mounts.

@ cpuguy83 Das führt mich wirklich auf Straßen, mit denen ich mich nicht befassen möchte. Vor allem, wenn ich einen Windows-basierten Host verwende.

Gibt es hier keine benutzerfreundliche Option? Ich habe das Gefühl, dass es hier ein Problem gibt, das nur aufgeschoben wird.

@atrauzzi In der Tat ist es kein einfaches Problem, das kurzfristig (jedenfalls nicht nahtlos) gelöst werden kann.

+1 Dies ist ein großer Blocker für ein ansonsten einfaches Dockerfile der Node.js-App. Ich habe an vielen Node-Apps gearbeitet, und ich habe selten eine gesehen, die kein privates Github-Repository als NPM-Abhängigkeit hat.

Als Workaround @apeace könnten Sie versuchen, sie als Git-Submodule zu Ihrem Git- .git in jeder Datei. Im Docker-Build können sie einfach über das lokale Verzeichnis installiert werden. Wenn sie aus irgendeinem Grund vollwertige Git-Repos sein müssen, stellen Sie sicher, dass die Datei .git nicht im Docker-Build vorhanden ist, und fügen Sie .git/modules/<repo> als <path>/<repo>/.git . Dadurch wird sichergestellt, dass es sich um normale Repos handelt, als ob sie geklont wurden.

Danke für diesen Vorschlag @jakirkham , aber wir verwenden private Repos schon so lange als NPM-Abhängigkeit, dass ich den normalen npm install Workflow nicht unterbrechen möchte.

Im Moment haben wir eine Lösung, die funktioniert, aber einfach nur eklig ist. Wir haben:

  • Einen Github-Benutzer und ein Team erstellt, die schreibgeschützten Zugriff auf die Repositorys haben, die wir als NPM-Abhängigkeiten verwenden
  • Den privaten Schlüssel dieses Benutzers an unser Repository übergeben, in dem wir unser Dockerfile haben
  • Im Dockerfile machen wir statt RUN npm install RUN GIT_SSH='/code/.docker/git_ssh.sh' npm install

Wobei git_ssh.sh ein Skript wie dieses ist:

#!/bin/sh
ssh -o StrictHostKeyChecking=no -i /code/.docker/deploy_rsa "$@"

Es funktioniert, aber das Weiterleiten des ssh-Schlüsselagenten wäre so viel schöner und viel weniger Einrichtungsarbeit!

:+1:
Ich kann nicht glauben, dass diese Funktionsanforderung immer noch nicht implementiert ist, da hier viele Anwendungsfälle vorliegen, in denen Benutzer während der Buildzeit Zugriff von privaten Repos benötigen.

Ich versuche, Container für verschiedene Entwicklungsumgebungen für eingebettete Systeme zu erstellen, die Zugriff auf private Repositorys erfordern. Das Hinzufügen von Unterstützung für Host-SSH-Schlüssel wäre eine großartige Funktion. Die gängigsten Methoden, die auf SO und anderen Seiten fliegen, sind unsicher und solange es keine Unterstützung für diese Feature-Layer mit privaten Schlüsseln gibt, werden sie sich verbreiten.

:+1:

:+1: Brauche das schon ewig.

Hallo @apeace , ich weiß nicht, ob Sie es gesehen haben, aber ich habe zuvor unsere Problemumgehung für dieses Problem kommentiert.

Es ist eine Kombination aus einem Skript und einem Webserver. Was denkst du https://github.com/dockito/vault ?

@pirelenito wäre der Schlüssel dadurch nicht immer noch in einer Schicht des

@apeace Das ONVAULT Skript lädt die Schlüssel herunter, führt Ihren Befehl aus und löscht dann sofort die Schlüssel. Da dies alles im selben Befehl geschieht, enthält die letzte Ebene den Schlüssel nicht.

@apeace Bei Medidata verwenden wir ein kleines, von uns erstelltes Tool namens docker-ssh-exec . Es hinterlässt nur die Binärdatei docker-ssh-exec im resultierenden Build-Image – keine Geheimnisse. Und es erfordert nur eine Ein-Wort-Änderung in Dockerfile , also ist es sehr "geringfügig".

Aber wenn Sie _wirklich_ eine Docker-native-only-Lösung verwenden müssen, gibt es jetzt eine integrierte Möglichkeit, dies zu tun, wie im Blog-Beitrag des --build-arg zu verwenden, um kurzlebige Werte an den Build-Prozess zu übergeben. Sie sollten in der Lage sein, einen privaten SSH-Schlüssel als ARG , ihn in das Dateisystem zu schreiben, einen git checkout auszuführen und dann den Schlüssel zu _löschen_, alles im Rahmen von einem RUN Anweisung. (dies ist, was der docker-ssh-exec Client tut). Dies führt zu hässlichen Dockerfile , sollte jedoch keine externen Werkzeuge erfordern.

Hoffe das hilft.

@benton Wir haben eine ähnliche Lösung gefunden. :)

Danke @pirelenito und @benton , ich werde alle eure Vorschläge prüfen!

BEARBEITEN : Folgendes ist tatsächlich _NICHT_ sicher:

Für die Aufzeichnung, so checken Sie ein privates Repo von Github aus, ohne Ihren SSH-Schlüssel im resultierenden Image zu hinterlassen.

Ersetzen Sie zunächst user/repo-name im folgenden Dockerfile durch den Pfad zu Ihrem privaten Repository (achten Sie darauf, dass Sie das Präfix [email protected] beibehalten, damit ssh für den Checkout verwendet wird):

FROM ubuntu:latest

ARG SSH_KEY
ENV MY_REPO [email protected]:user/repo-name.git

RUN apt-get update && apt-get -y install openssh-client git-core &&\
    mkdir -p /root/.ssh && chmod 0700 /root/.ssh && \
    ssh-keyscan github.com >/root/.ssh/known_hosts

RUN echo "$SSH_KEY" >/root/.ssh/id_rsa &&\
    chmod 0600 /root/.ssh/id_rsa &&\
    git clone "${MY_REPO}" &&\
    rm -f /root/.ssh/id_rsa

Dann baue mit dem Befehl

docker build --tag=sshtest --build-arg SSH_KEY="$(cat ~/.ssh/path-to-private.key)" .

Übergeben Sie den richtigen Pfad zu Ihrem privaten SSH-Schlüssel.

^ mit Docker 1.9

@benton Vielleicht möchten Sie sich die Ausgabe von docker inspect sshtest und docker history sshtest genauer ansehen. Ich denke, Sie werden feststellen, dass Metadaten im endgültigen Bild Ihr Geheimnis haben, auch wenn sie nicht im Containerkontext selbst verfügbar sind ...

@ljrittle Gute VAR . Ich denke, hier ist noch ein externer Workaround erforderlich.

Ein Grund dafür, dass noch keine native Lösung entwickelt wurde, ist vielleicht, dass mehrere Problemumgehungen vorhanden sind. Aber ich stimme den meisten anderen hier zu, dass eine integrierte Lösung den Benutzern besser dienen würde und zur Docker-Philosophie "Batterien inklusive" passt.

Aus den Dokumenten...

Hinweis: Es wird nicht empfohlen, Build-Time-Variablen zum Übergeben von Geheimnissen wie Github-Schlüsseln, Benutzeranmeldeinformationen usw. zu verwenden.

( https://docs.docker.com/engine/reference/builder/#arg )

Ich glaube nicht, dass ein Pfad zu einer Datei darauf zutrifft, der Hinweis bezieht sich darauf, dass ein einfach sichtbares Passwort / Token in Ihrem Konsolenprotokoll angezeigt wird.

Ich folge @jcrombez nicht. Das Beispiel bestand darin, den ssh-Schlüssel als Variable über ARG . Es gilt also.

Beim Sicherheitsrisiko sieht das ganz anders aus:

docker build --tag=sshtest --build-arg SSH_KEY="$(cat ~/.ssh/path-to-private.key)" .

als das :

docker build --tag=sshtest --build-arg SSH_KEY="mykeyisthis" .

Wenn jemand Ihr Terminalprotokoll findet, sind die Folgen nicht die gleichen.
Aber ich bin kein Sicherheitsexperte, dies kann aus anderen Gründen, die mir nicht bekannt sind, immer noch gefährlich sein.

Auf der Kommandozeile, nehme ich an.

Wie @ljrittle jedoch betonte und @benton zugab, wird jede Art und Weise, in der Sie --build-arg / ARG , im Build festgeschrieben. Wenn Sie es überprüfen, werden Informationen über den Schlüssel angezeigt. Beide verlassen den Zustand im letzten Docker-Container und beide leiden an derselben Schwachstelle. Daher empfiehlt Docker, dies nicht zu tun.

_BENUTZER-UMFRAGE_

_Der beste Weg, um über Updates informiert zu werden, ist die Schaltfläche _Abonnieren_ auf dieser Seite._

Bitte verwenden Sie keine "+1"- oder "Das habe ich auch"-Kommentare zu Problemen. Wir automatisch
sammle diese Kommentare, um den Thread kurz zu halten.

Die unten aufgeführten Personen haben dieses Problem positiv bewertet, indem sie einen +1-Kommentar hinterlassen haben:

@fletcher91
@benlemasurier
@dmuso
@probepark
@saada
@ianAndrewClark
@jakirkham
@galindro
@luisguilherme
@akurkin
@allardhoeve
@SevaUA
@sankethkatta
@kouk
@cliffxuan
@kotlas92
@taion

_BENUTZER-UMFRAGE_

_Der beste Weg, um über Updates informiert zu werden, ist die Schaltfläche _Abonnieren_ auf dieser Seite._

Bitte verwenden Sie keine "+1"- oder "Das habe ich auch"-Kommentare zu Problemen. Wir automatisch
sammle diese Kommentare, um den Thread kurz zu halten.

Die unten aufgeführten Personen haben dieses Problem positiv bewertet, indem sie einen +1-Kommentar hinterlassen haben:

@parknicker
@dursk
@adambiggs

Beim Sicherheitsrisiko sieht das ganz anders aus:

docker build --tag=sshtest --build-arg SSH_KEY="$(cat ~/.ssh/path-to-private.key)" .

abgesehen von deiner Bash-Historie sind sie genau gleich; Es gibt viele Orte, an denen diese Informationen landen können.

Bedenken Sie beispielsweise, dass API-Anfragen auf dem Server protokolliert werden können;

Hier ist ein Daemon-Log für docker build --tag=sshtest --build-arg SSH_KEY="fooobar" .

DEBU[0090] Calling POST /v1.22/build
DEBU[0090] POST /v1.22/build?buildargs=%7B%22SSH_KEY%22%3A%22fooobar%22%7D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&memory=0&memswap=0&rm=1&shmsize=0&t=sshtest&ulimits=null
DEBU[0090] [BUILDER] Cache miss: &{[/bin/sh -c #(nop) ARG SSH_KEY]}
DEBU[0090] container mounted via layerStore: /var/lib/docker/aufs/mnt/de3530a82a1a141d77c445959e4780a7e1f36ee65de3bf9e2994611513790b8c
DEBU[0090] container mounted via layerStore: /var/lib/docker/aufs/mnt/de3530a82a1a141d77c445959e4780a7e1f36ee65de3bf9e2994611513790b8c
DEBU[0090] Skipping excluded path: .wh..wh.aufs
DEBU[0090] Skipping excluded path: .wh..wh.orph
DEBU[0090] Applied tar sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef to 91f79150f57d6945351b21c9d5519809e2d1584fd6e29a75349b5f1fe257777e, size: 0
INFO[0090] Layer sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef cleaned up

_BENUTZER-UMFRAGE_

_Der beste Weg, um über Updates informiert zu werden, ist die Schaltfläche _Abonnieren_ auf dieser Seite._

Bitte verwenden Sie keine "+1"- oder "Das habe ich auch"-Kommentare zu Problemen. Wir automatisch
sammle diese Kommentare, um den Thread kurz zu halten.

Die unten aufgeführten Personen haben dieses Problem positiv bewertet, indem sie einen +1-Kommentar hinterlassen haben:

@cj2

Ich versuche, eine einfache Ruby/Rack-Anwendung zu containerisieren. Die Gemfile verweist auf mehrere private Gems. In dem Moment, in dem bundle install startet und versucht, auf die privaten Repos zuzugreifen, erhalte ich diesen Fehler

Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Ich konnte es umgehen, aber nicht, ohne meinen privaten Schlüssel preiszugeben. Das geht nicht. Bitte aktivieren Sie die SSH-Authentifizierungsweiterleitung.

+1 für SSH-Weiterleitung während Builds. Kann go get deswegen nicht mit privaten Repos verwenden ;(

+1 für die sichere Aktivierung dieses Anwendungsfalls

_BENUTZER-UMFRAGE_

_Der beste Weg, um über Updates informiert zu werden, ist die Schaltfläche _Abonnieren_ auf dieser Seite._

Bitte verwenden Sie keine "+1"- oder "Das habe ich auch"-Kommentare zu Problemen. Wir automatisch
sammle diese Kommentare, um den Thread kurz zu halten.

Die unten aufgeführten Personen haben dieses Problem positiv bewertet, indem sie einen +1-Kommentar hinterlassen haben:

@lukad

Ich lese gerade diese sehr interessante Diskussion durch und frage mich, ob eine einfache Lösung diese Probleme lösen könnte. Ich denke spontan über eine Option im Dockerfile nach, um beim Erstellen von Snapshots nur bestimmte interne Verzeichnisse / Dateien ausschließen / ignorieren zu können. Wie schwer kann das sein?

dh

.ssh . AUSSCHLIESSEN

Ich denke, es würde für alle folgenden Schritte gelten. Wenn Sie es also hinter FROM platzieren, können Sie Ihre Schlüssel so oft hinzufügen, wie Sie möchten, und wie gewohnt bauen und müssen sich keine Sorgen machen, dass Schlüssel versehentlich in Ihrem Bild landen (zugegeben Sie müssen sie möglicherweise bei jedem Schritt hinzufügen, der sie erfordert, aber Sie müssen sich keine Sorgen machen, dass sie in einem Bild enden)

Der Vorschlag von einwandfrei , und der Docker-Daemon protokolliert den id_rsa-Schlüssel nur, wenn er sich im Debug-Modus befindet.

Eine noch niedlichere Möglichkeit, Ihren Schlüssel während des Builds freizugeben, ist:

# Dockerfile
ARG SSH_KEY
RUN eval `ssh-agent -s` > /dev/null \
    && echo "$SSH_KEY" | ssh-add - \
    && git clone [email protected]:private/repository.git

docker build -t my_tag --build-arg SSH_KEY="$(< ~/.ssh/id_rsa)" .

Ha, obwohl es in der Tat nur da sitzt, wenn Sie sich docker inspect my_tag ansehen.

Und wenn Sie ein Passwort für den Schlüssel id_rsa haben, könnten Sie ein schlechter Mensch sein und Folgendes tun:

# Dockerfile
ARG SSH_KEY
ARG SSH_PASS
RUN eval `ssh-agent -s` > /dev/null \
    && echo "echo $SSH_PASS" > /tmp/echo_ps && chmod 700 /tmp/echo_ps \
    && echo "$SSH_KEY" | SSH_ASKPASS=/tmp/echo_ps DISPLAY= ssh-add - \
    && git clone [email protected]:private/repository.git
    && rm /tmp/echo_ps

docker build -t my_tag --build-arg SSH_KEY="$(< ~/.ssh/id_rsa)" --build-arg SSH_PASS=<bad_idea> .

Es ist natürlich schwer zu begründen, dass dies auch nur im Entferntesten eine gute Idee ist, aber wir sind alle Menschen, nehme ich an.

Zugegeben, der Hauptgrund dafür scheint zu sein, dass Leute während eines Builds "Bundle-Installation" oder "Go Get" gegen private Repositorys durchführen.

Ich würde sagen, dass Sie einfach Ihre Abhängigkeiten verkaufen und das gesamte Projekt HINZUFÜGEN. Aber manchmal müssen Dinge jetzt erledigt werden.

@SvenDowideit @thaJeztah Gibt es eine Lösung für dieses Problem? Ich habe versucht, dem Thread zu folgen, aber zwischen dem Schließen und Öffnen anderer Threads und vielen Meinungen habe ich keine Ahnung, was das Docker-Team wann tun wird.

Das Beste, aber muss umgesetzt werden?

Docker-Build verwendet ssh-agent innerhalb des Builds, um einen Proxy für das ssh Ihres Hosts zu erstellen und dann Ihre Schlüssel zu verwenden, ohne sie kennen zu müssen!

Für alle, die gerade etwas über ssh-agent Proxying lernen: github zur Rettung

Die ursprüngliche Idee von @phemmer .

@yordis Ich glaube nicht, dass es eine "tolle" Lösung in dem Thread gibt, die noch frei verfügbar ist.

Dieser Kommentar von docker/docker-py#980 scheint darauf hinzuweisen, dass der Daemon diese Schlüssel verwendet, wenn Sie Ihre ssh-Schlüssel in das Schlüsselverzeichnis Ihres Root-Benutzers auf Ihrem Hostsystem kopieren. Allerdings bin ich diesbezüglich ein absoluter Anfänger, damit es vielleicht jemand anders klären kann.


Ok, aber nicht das Beste

Übergabe des Schlüssels mit den Build-Argumenten von Docker 1.8.
Vorbehalte .

Definitiv eine schlechte Idee

Viele Leute haben hier auch empfohlen, den Schlüssel vorübergehend zum Build-Kontext hinzuzufügen und ihn dann schnell zu entfernen. Klingt wirklich gefährlich, denn wenn sich der Schlüssel in einen der Commits einschleicht, kann jeder, der den Container verwendet, auf diesen Schlüssel zugreifen, indem er einen bestimmten Commit auscheckt.


Warum ist das noch nirgendwo hingekommen?

Es braucht einen Designvorschlag, dieses Thema ist _cah_- _geplaudert_ und Ideen sind im Moment nur vage. Die tatsächlichen Implementierungsdetails gehen in einem Dunst von "Was wäre, wenn wir x gemacht hätten" und +1 verloren. Um sich zu organisieren und mit dieser dringend benötigten Funktion fortzufahren, sollten diejenigen, die mögliche Lösungen haben, eine . . .

Designvorschlag

und verweisen Sie dann auf dieses Problem.

Ich habe Neuigkeiten zu diesem Thema.

Auf der DockerCon in der vergangenen Woche wurden wir ermutigt, unsere schwierigsten Fragen im Docker-Pavillon "Ask the Experts" zu stellen. Also ging ich hin und führte ein kurzes Gespräch mit einem intelligenten und freundlichen Ingenieur mit dem ermutigenden Titel Solutions Architect. Ich habe ihm eine kurze Zusammenfassung dieses Problems gegeben, die ich hoffe, dass ich sie richtig vermittelt habe, weil er mir versichert hat, dass dies mit _nur_ docker-compose getan werden kann! Die Details seines Vorschlags betrafen einen mehrstufigen Build – möglicherweise um die Abhängigkeiten in einem anderen Kontext als den endgültigen App-Build zu akkumulieren – und schienen die Verwendung von Datenmengen zum Zeitpunkt des Builds zu beinhalten.

Leider habe ich keine Erfahrung mit docker-compose, daher konnte ich nicht alle Details verfolgen, aber er versicherte mir, dass er mit einer Lösung antworten würde, wenn ich ihn mit dem genauen Problem anschreiben würde. Also habe ich eine E-Mail geschrieben , von der ich hoffe, dass sie

Ich bin mir sicher, dass er viel beschäftigt ist, daher würde ich nichts unmittelbar erwarten, aber ich finde das ermutigend, insofern er das Problem verstanden hat und bereit ist, es nur mit dem Docker-nativen Toolset anzugehen.

@benton Ich verwende die folgende Konfiguration von docker-compose.yaml, um die in diesem Thema beschriebenen Dinge zu tun:

version: '2'
services:
  serviceName:
     volumes:
      - "${SSH_AUTH_SOCK}:/tmp/ssh-agent"
    environment:
      SSH_AUTH_SOCK: /tmp/ssh-agent

Stellen Sie sicher, dass ssh-agent auf dem Hostcomputer gestartet wurde und den Schlüssel kennt (Sie können ihn mit dem Befehl ssh-add -L überprüfen).

Bitte beachten Sie, dass Sie möglicherweise hinzufügen müssen

Host *
  StrictHostKeyChecking no

in die .ssh/config.

Hallo @WoZ! Danke für deine Antwort, sieht einfach aus, also werde ich es versuchen :)

Ich habe jedoch eine Frage, wie können Sie dies mit automatisierten Builds im Docker-Hub verwenden? Soweit ich das jetzt habe, gibt es dort keine Möglichkeit, eine Compose-Datei zu verwenden :(

@garcianavalon funktioniert gut, aber nur für run , nicht für build . Arbeitet auch noch nicht mit Docker für Mac, obwohl es anscheinend auf der Todo-Liste steht.

Bearbeiten: https://github.com/docker/for-mac/issues/410

Wir haben uns 2 weitere Workarounds für unsere speziellen Anforderungen ausgedacht:

1) Richten Sie unseren eigenen Paketspiegel für npm, pypi usw. hinter unserem VPN ein, auf diese Weise benötigen wir kein SSH.

2) Auf dem gesamten Host-Computer haben wir bereits Zugriff auf private Repos, also klonen / laden wir das private Paket lokal auf den Host-Computer herunter, führen seine Paketinstallation aus, um es herunterzuladen, verwenden dann -v, um das Volume dem Docker zuzuordnen, und bauen dann Docker.

Wir verwenden derzeit Option 2).

Was docker run angeht, scheint

Es kann immer noch eine gute Idee sein, die Datei known_hosts vom Host zu KOPIEREN, anstatt sie im Container zu erstellen (weniger sicher), da ssh-agent keine bekannten Hosts weiterleitet.

Das grundlegende Problem beim Ziehen privater Abhängigkeiten während eines Docker-Ausführungsschritts besteht jedoch darin, den Docker-Build-Cache zu umgehen, was in Bezug auf die Build-Zeit sehr wichtig sein kann.

Ein Ansatz, um diese Einschränkung zu umgehen, besteht darin, Ihre Build-Abhängigkeitsdeklarationen md5/zu datieren (zB package.json ), das Ergebnis in ein Image zu übertragen und dasselbe Image wiederzuverwenden, wenn sich die Datei nicht geändert hat. Die Verwendung des Hashs im Bildnamen ermöglicht das Zwischenspeichern mehrerer Zustände. Es müsste auch mit dem vorinstallierten Image-Digest kombiniert werden.

Dies sollte robuster sein als die Lösung von @aidanhs für Build-Server, obwohl ich sie noch im Maßstab testen muss.

Dies sollte robuster sein als die Lösung von @aidanhs für Build-Server, obwohl ich sie noch im Maßstab testen muss.

Meine spezielle Lösung hat seit 1.9.0 nicht funktioniert - es stellte sich heraus, dass die in 1.8.0 eingeführte Funktion, auf die ich mich verlassen hatte, nicht beabsichtigt war und wurde daher entfernt.

Obwohl das Prinzip meiner Lösung gut bleibt (es erfordert nur, dass Sie einen DNS-Server außerhalb Ihres Computers haben, den a) Ihr Computer verwendet und b) Sie in der Lage sind, Einträge an geeigneten Orten hinzuzufügen), kann ich nicht wirklich sagen, dass ich begeistert bin empfehle es nicht weiter.

Danke für die zusätzlichen Infos @aidanhs!

Einige Updates zu meiner vorgeschlagenen Lösung: Hashes müssen nicht wirklich kombiniert werden, da der Hash des Basisimages direkt nach dem Hinzufügen der Deklarationsdatei für Abhängigkeiten einfach verwendet werden kann. Außerdem ist es besser, die Datei "known_host" einfach als Volume zu mounten, da ssh-agent ohnehin nur zur Laufzeit verwendet werden kann - und sicherer, da es eine Liste aller Hosts enthält, mit denen Sie sich verbinden.

Ich habe die Komplettlösung für node/npm implementiert und ist hier mit ausführlicher Dokumentation und Beispielen zu finden: https://github.com/iheartradio/docker-node

Natürlich können die Prinzipien auf andere Frameworks erweitert werden.

Das gleiche Problem hier, wie baut man etwas, wo dieses Etwas SSH-Anmeldeinformationen erfordert, um eine Reihe von Projekten zur Build-Zeit in einem Docker-Container zu überprüfen und zu erstellen, ohne Anmeldeinformationen in das Image oder ein Basisimage zu schreiben.

Wir umgehen dies, indem wir einen zweistufigen Build-Prozess haben. Es wird ein "Build"-Image erstellt, das die Quellen-/Schlüssel-/Build-Abhängigkeiten enthält. Sobald das erstellt wurde, wird es ausgeführt, um die Build-Ergebnisse in eine Tar-Datei zu extrahieren, die später zu einem "Deploy"-Image hinzugefügt wird. Das Build-Image wird dann entfernt und alles, was veröffentlicht wird, ist das "Deploy"-Image. Dies hat einen schönen Nebeneffekt, dass die Behälter-/Schichtgrößen klein gehalten werden.

@binarytemple-bet365 siehe https://github.com/iheartradio/docker-node für ein End-to-End-Beispiel, das genau das tut. Ich verwende mehr als zwei Schritte, da ich einen SSH-Dienstcontainer verwende, Vorinstallation (Basisimage bis vor der Installation privater Abhängigkeiten), Installation (Containerstatus nach Laufzeitinstallation privater Abhängigkeiten) und Nachinstallation (fügt Befehle hinzu, die Sie nach der Installation hatten privater Abhängigkeiten), um die Geschwindigkeit und die Trennung von Belangen zu optimieren.

Schauen Sie sich Rocker an , es ist eine saubere Lösung.

@Sodki Ich habe deinen Rat Rocker ist eine saubere und durchdachte Lösung. Umso mehr ist es schade, dass das Docker-Team dieses Projekt nicht einfach unter seine Fittiche nimmt und docker build . Danke schön.

Immer noch kein besserer Weg? :(

Hat jemand dieses neue Squash-Ding ausprobiert? https://github.com/docker/docker/pull/22641 Könnte die native Docker-Lösung sein, nach der wir suchen. Werde es jetzt ausprobieren und berichten, wie es gelaufen ist.

Nach 2+ Jahren ist dies noch nicht behoben 😞 Bitte das Docker-Team etwas dagegen unternehmen

Sieht so aus, als ob die neue Option --squash in 1.13 für mich funktioniert:
http://g.recordit.co/oSuMulfelK.gif

Ich baue es mit: docker build -t report-server --squash --build-arg SSH_KEY="$(cat ~/.ssh/github_private_key)" .

Wenn ich also docker history oder docker inspect mache, wird der Schlüssel nicht angezeigt.

Mein Dockerfile sieht so aus:

FROM node:6.9.2-alpine

ARG SSH_KEY

RUN apk add --update git openssh-client && rm -rf /tmp/* /var/cache/apk/* &&\
  mkdir -p /root/.ssh && chmod 0700 /root/.ssh && \
  ssh-keyscan github.com > /root/.ssh/known_hosts

RUN echo "$SSH_KEY" > /root/.ssh/id_rsa &&\
  chmod 0600 /root/.ssh/id_rsa

COPY package.json .

RUN npm install
RUN rm -f /root/.ssh/id_rsa

# Bundle app source
COPY . .

EXPOSE 3000

CMD ["npm","start"]

@kienpham2000 , Ihr Screenshot sieht so aus, als ob er noch die Schlüssel enthält - könnten Sie bitte die Ausgabe von docker history mit dem --no-trunc Flag überprüfen und hier berichten, ob die privaten Schlüssel im Docker angezeigt werden oder nicht? Geschichte?

@ryanschwartz du hast recht, das --no-trunc zeigt das ganze verdammte Ding, das fliegt nicht.

@kienpham2000
Eine andere Sache, die sie in Version 1.13 eingeführt haben, ist:

Geheimnisse bauen
• aktiviert Build-Time-Secrets mit dem —build-secret-Flag
• erstellt tmpfs während des Builds und enthüllt Geheimnisse für die
Build-Container, die während des Builds verwendet werden.
https://github.com/docker/docker/pull/28079

Vielleicht könnte das funktionieren?

Build-Geheimnisse haben es nicht in 1.13 geschafft, werden es aber hoffentlich in 1.14 tun.

Am 15. Dezember 2016 um 9:45 Uhr schrieb "Alex" [email protected] :

@kienpham2000 https://github.com/kienpham2000
Eine andere Sache, die sie in Version 1.13 eingeführt haben, ist:

Geheimnisse bauen
• aktiviert Build-Time-Secrets mit dem —build-secret-Flag
• erstellt tmpfs während des Builds und enthüllt Geheimnisse für die
Build-Container, die während des Builds verwendet werden.
• #28079 https://github.com/docker/docker/pull/28079

Vielleicht könnte das funktionieren?


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/6396#issuecomment-267393020 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAdcPDxrctBP2TlCtXen-Y_uY8Y8B09Sks5rIXy2gaJpZM4CD4SM
.

Also ein Jahr später: Nein, das ist eine schlechte Idee. Das solltest du nicht tun. Es gibt verschiedene andere Lösungen. Github kann beispielsweise Zugriffstoken bereitstellen. Sie können sie mit geringerem Risiko in Konfigurationsdateien/Umgebungsvariablen verwenden, da Sie festlegen können, welche Aktionen für jedes Token zulässig sind.

Die Lösung besteht darin, eine SSH-Weiterleitung zu implementieren. Wie zum Beispiel Vagrant.

Kann mir jemand erklären warum es so kompliziert ist das umzusetzen?

@omarabid - antworten Sie auf Ihren ursprünglichen Vorschlag, Umgebungsvariablen zu verwenden, um private Schlüssel zur Verwendung in der Dockerfile zu übergeben? Keine Frage, das ist eine schlechte Sicherheitspraxis.

Was Ihren Vorschlag betrifft, Zugriffstoken zu verwenden, werden sie in einer Schicht gespeichert und können genauso gefährlich herumliegen wie ein SSH-Schlüssel. Selbst wenn es nur Lesezugriff hat, möchten die meisten Leute nicht, dass andere nur Lesezugriff auf ihre Repositorys haben. Außerdem müsste eine häufige Sperrung/Rotation/Verteilung erfolgen; Dies ist für jeden Entwickler usw. etwas einfacher zu handhaben als mit "Master"-Zugriffstoken.

Die vor ein paar Kommentaren erwähnte Build-Secrets-Lösung scheint ein Schritt in die richtige Richtung zu sein, aber die Möglichkeit, einen SSH-Agenten zu verwenden, ist am besten. Vielleicht könnte man einen SSH-Agenten in Kombination mit Build-Geheimnissen verwenden, ich bin mir nicht sicher.

Für Entwickler/CI-Systeme ist es selbstverständlich, während git/build-Operationen einen SSH-Agenten zu verwenden. Dies ist viel sicherer als ein privater Klartext-Schlüssel ohne Passwort, der massenhaft auf einer Vielzahl von Systemen widerrufen/ersetzt werden muss. Außerdem besteht bei SSH-Agenten keine Möglichkeit, dass die privaten Schlüsseldaten in ein Image übernommen werden. Schlimmstenfalls wird eine Umgebungsvariable/SSH_AUTH_SOCK-Reste im Image zurückbleiben.

Ich habe diese neueste Problemumgehung erhalten, ohne den Inhalt des geheimen Schlüssels anzuzeigen oder ein zusätzliches Docker-Tool von Drittanbietern zu verwenden (hoffentlich wird der geheime Tresor während der erstellten PR bald zusammengeführt).

Ich verwende die AWS-Cli, um den gemeinsam genutzten privaten Schlüssel von S3 in das aktuelle Repository des Hosts herunterzuladen. Dieser Schlüssel wird im Ruhezustand mit KMS verschlüsselt. Sobald der Schlüssel heruntergeladen wurde, kopiert Dockerfile diesen Schlüssel einfach während des Build-Prozesses und entfernt ihn danach, der Inhalt wird nicht bei docker inspect oder docker history --no-trunc angezeigt

Laden Sie zuerst den privaten Github-Schlüssel von S3 auf den Host-Rechner herunter:

# build.sh
s3_key="s3://my-company/shared-github-private-key"
aws configure set s3.signature_version s3v4
aws s3 cp $s3_key id_rsa --region us-west-2 && chmod 0600 id_rsa

docker build -t app_name .

Dockerfile sieht so aus:

FROM node:6.9.2-alpine

ENV id_rsa /root/.ssh/id_rsa
ENV app_dir /usr/src/app

RUN mkdir -p $app_dir
RUN apk add --update git openssh-client && rm -rf /tmp/* /var/cache/apk/* && mkdir -p /root/.ssh && ssh-keyscan github.com > /root/.ssh/known_hosts

WORKDIR $app_dir

COPY package.json .
COPY id_rsa $id_rsa
RUN npm install && npm install -g gulp && rm -rf $id_rsa

COPY . $app_dir
RUN rm -rf $app_dir/id_rsa

CMD ["start"]

ENTRYPOINT ["npm"]

@kienpham2000 , warum würde diese Lösung den Schlüssel nicht in der Bildebene behalten? Die Aktionen zum Kopieren und Entfernen des Schlüssels werden in getrennten Befehlen ausgeführt, daher gibt es eine Ebene, die den Schlüssel enthalten sollte.
Unser Team hat Ihre Lösung bis gestern verwendet, aber wir haben eine verbesserte Lösung gefunden:

  • Wir generieren eine Pre-Sign-URL, um mit aws s3 cli auf den Schlüssel zuzugreifen, und begrenzen den Zugriff für ca. 5 Minuten. Wir speichern diese Pre-Sign-URL in einer Datei im Repo-Verzeichnis und fügen sie dann in Dockerfile dem Bild hinzu.
  • In dockerfile haben wir einen RUN-Befehl, der all diese Schritte ausführt: Verwenden Sie die Pre-Sing-URL, um den ssh-Schlüssel zu erhalten, führen Sie npm install aus und entfernen Sie den ssh-Schlüssel.
    Wenn Sie dies in einem einzigen Befehl tun, wird der ssh-Schlüssel in keiner Schicht gespeichert, sondern die Pre-Sign-URL wird gespeichert, und dies ist kein Problem, da die URL nach 5 Minuten nicht mehr gültig ist.

Das Build-Skript sieht so aus:

# build.sh
aws s3 presign s3://my_bucket/my_key --expires-in 300 > ./pre_sign_url
docker build -t my-service .

Dockerfile sieht so aus:

FROM node

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    ssh -o StrictHostKeyChecking=no [email protected] || true && \
    npm install --production && \
    rm ./my_key && \
    rm -rf ~/.ssh/*

ENTRYPOINT ["npm", "run"]

CMD ["start"]

@diegocsandrim danke für den Hinweis, ich mag deine Lösung sehr, ich werde unsere Sachen hier aktualisieren. Danke für das Teilen!

Ich bin ein bisschen neu in dem Thread, aber im Grunde scheint es, als ob die Leute versuchen, ein Problem zu lösen, das besser durch PKI gelöst wird. Nicht jeder versucht unbedingt, das gleiche Problem zu retten, bei dem PKI die bessere Lösung wäre, aber genügend Referenzen scheinen darauf hinzuweisen, dass dies etwas sein könnte, das in Betracht gezogen werden sollte.

Es scheint ärgerlich, aber grundsätzlich möglich zu

  • Erstellen Sie eine lokale Zertifizierungsstelle
  • einen Prozess zum Generieren eines Zertifikats haben
  • einen Prozess zur Ausstellung des Zertifikats haben
  • einen Prozess zum Widerrufen des Zertifikats haben
  • ssh-Daemons verwenden PKI

Und wenn die Leute das für machbar halten, dann bitte unbedingt erstellen und als Open Source verwenden, schließlich muss die Arbeit einmal gut gemacht werden. Ich habe keine Ahnung, ob der Build von Roumen Petrov sicher ist und habe keinen Quellcode notiert (habe den Tar nicht überprüft), also habe ich keine Ahnung, wie sicher er ist.

https://security.stackexchange.com/questions/30396/how-to-setup-openssh-to-use-x509-pki-for-authentication

https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html

@mehmetcodes : Eine PKI zu haben, löst das Problem nicht wirklich. Damit die PKI-basierte SSH-Authentifizierung funktioniert, müssen Sie weiterhin den privaten Schlüssel in das Image laden.

Wenn Sie nicht Ihre lokale Zertifizierungsstelle sehr kurzlebige Zertifikate ausstellen lassen (zB weniger als eine Stunde), und Sie das Zertifikat sofort nach einem erfolgreichen Build widerrufen, ist dies unsicher.

Wenn Sie es schaffen, einen kurzlebigen Zertifikatsprozess zu erstellen, unterscheidet sich das nicht wesentlich von der Verwendung eines neuen SSH-Schlüssels, den Sie sofort nach Abschluss eines Builds widerrufen.

Oh, es ist noch ärgerlicher als das, aber ich muss etwas auf der Spur sein oder warum sollte es in freier Wildbahn existieren?

https://blog.cloudflare.com/red-october-cloudflares-open-source-implementation-of-the-two-man-rule/
https://blog.cloudflare.com/how-to-build-your-own-public-key-infrastructure/

Ich weiß nicht, ein temporärer SSH-Schlüssel ist wahrscheinlich für die meisten Anwendungsfälle viel besser, aber jeder Rückgriff hat etwas Beunruhigendes, einschließlich des von mir vorgeschlagenen, insbesondere in diesem Zusammenhang.

Normalerweise würden Sie stattdessen einfach ein Volume mit dem Schlüssel mounten, aber das hilft nicht, den Docker für die Mac / Moby-Lösung zu benötigen.

wer zum f.. ist moby?

@weiße Farbe
Image of Moby

Unter MacOS bin ich so weit gekommen:

bash-3.2$ docker run -t -i -v "$SSH_AUTH_SOCK:/tmp/ssh_auth_sock" -e "SSH_AUTH_SOCK=/tmp/ssh_auth_sock" python:3.6 ssh-add -l
docker: Error response from daemon: Mounts denied:
The path /var/folders/yb/880w03m501z89p0bx7nsxt580000gn/T//ssh-DcwJrLqQ0Vu1/agent.10466
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.
.

/var/ ist ein Alias, mit dem Docker zu kämpfen scheint. Aber wenn ich dem $SSH_AUTH_SOCK-Pfad /private $ voranstelle (dh den aufgelösten Alias-Pfad), dann kann Docker die Datei lesen, aber ich bekomme:

bash-3.2$ docker run -t -i -v "/private$SSH_AUTH_SOCK:/tmp/ssh_auth_sock" -e "SSH_AUTH_SOCK=/tmp/ssh_auth_sock" python:3.6 ssh-add -l
Could not open a connection to your authentication agent.

An dieser Stelle frage ich mich, wie schlimm es ist, einfach…

docker run -v ~/.ssh:/root/.ssh python:3.6 bash

?

docker build  --build-arg ssh_prv_key="$(cat ~/.ssh/id_rsa_no_pass)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)" --squash .

Und dann in der Docker-Datei:

ARG ssh_prv_key
ARG ssh_pub_key

# Authorize SSH Host
RUN mkdir -p /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan github.com > /root/.ssh/known_hosts

# Add the keys and set permissions
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub

Und vergiss nicht zu erwähnen

RUN rm -f /root/.ssh/id_rsa /root/.ssh/id_rsa.pub

als letzter Schritt.

Der Haken dabei ist, dass Ihr privater Schlüssel nicht passwortgeschützt sein sollte.

Das Problem mit dem vorherigen Kommentar ist, dass die Schlüssel in den Ebenen landen ... rm wird nicht aus einer vorherigen Ebene gelöscht, da jede Zeile in einer Docker-Datei eine Ebene ist.

Löst docker secret dieses Problem nicht?
WDYT @thaJeztah

docker secret ist (noch) nicht während des Builds verfügbar und nur in Services verfügbar (also noch nicht für docker run )

Wenn Sie mehrstufige Builds verwenden, könnte so etwas jedoch funktionieren (auf meinem Telefon tippen, also lassen Sie mich eine Zusammenfassung verlinken, die ich vor einiger Zeit erstellt habe); https://gist.github.com/thaJeztah/836c4220ec024cf6dd48ffa850f07770

Ich beschäftige mich nicht mehr so ​​mit Docker, aber wie kann es sein, dass dieses Problem so lange besteht. Ich versuche nicht, anzurufen, sondern zu verstehen, was der Aufwand für die Behebung dieses Problems ist, denn damals, als ich damit zu tun hatte, schien es ein wirklich häufiges Problem für jedes Unternehmen zu sein, das private Pakete wie ruby gems von a . abzieht privates Repo.

Kümmert sich das Moby um dieses Problem? Warum es so schwer sein muss für etwas, das keine so große Sache zu sein scheint, denke ich.

Ist schon fast 3 Jahre her 😢

@yordis Docker Builder war ein oder zwei Jahre lang eingefroren. Das Docker-Team gab an, dass Builder gut genug ist und dass sie ihre Bemühungen anderswo konzentrieren. Aber das ist weg und seitdem gab es zwei Änderungen am Builder. Squash- und Mustli-Bühnenaufbauten. Bauzeitgeheimnisse könnten also auf dem Weg sein.

Für die Laufzeitweiterleitung von ssh-agent würde ich https://github.com/uber-common/docker-ssh-agent-forward empfehlen

Warum es so schwer sein muss für etwas, das keine so große Sache zu sein scheint, denke ich.

@yordis liest die Top-Beschreibung dieses Problems, die Implementierung ist buildkit Projekt für zukünftige Verbesserungen des Builders gestartet wurde; https://github.com/moby/buildkit

@thaJeztah Ich wünschte, ich könnte die erforderlichen Fähigkeiten haben, aber ich habe nicht.

@villlem kennst du eine Roadmap vom Docker-Team?

Wöchentliche Berichte für den Bauherrn finden Sie hier; https://github.com/moby/moby/tree/master/reports/builder build time secrets ist immer noch im neuesten Bericht aufgeführt, könnte aber Hilfe gebrauchen

Wir verwenden die Lösung von @diegocsandrim , jedoch mit einem Zwischenschritt zur Verschlüsselung, um zu vermeiden, dass in S3 ein unverschlüsselter SSH-Schlüssel hinterlassen wird.

Dieser zusätzliche Schritt bedeutet, dass der Schlüssel nicht aus dem Docker-Image wiederhergestellt werden kann (die URL zum Herunterladen läuft nach fünf Minuten ab) und nicht von AWS wiederhergestellt werden kann (da er mit einem rotierenden Passwort verschlüsselt ist, das nur dem Docker-Image bekannt ist). .

In build.sh:

BUCKET_NAME=my_bucket
KEY_FILE=my_unencrypted_key
openssl rand -base64 -out passfile 64
openssl enc -aes-256-cbc -salt -in $KEY_FILE -kfile passfile | aws s3 cp - s3://$BUCKET_NAME/$(hostname).enc_key
aws s3 presign s3://$BUCKET_NAME/$(hostname).enc_key --expires-in 300 > ./pre_sign_url
docker build -t my_service

Und im Dockerfile:

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - | openssl enc -aes-256-cbc -d -kfile passfile > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    mkdir /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan github.com > /root/.ssh/known_hosts && \
    [commands that require SSH access to Github] && \
    rm ./my_key && \
    rm ./passfile && \
    rm -rf /root/.ssh/

Wenn Sie docker run , sollten Sie Ihre .ssh mit --mount type=bind,source="${HOME}/.ssh/",target="/root/.ssh/",readonly mounten. Das Readonly ist die Magie, es maskiert die normalen Berechtigungen und ssh sieht im Grunde 0600 Berechtigungen, mit denen es zufrieden ist. Sie können auch mit -u root:$(id -u $USER) , damit der Root-Benutzer im Container alle Dateien schreibt, die er mit derselben Gruppe wie Ihr Benutzer erstellt .

Endlich.

Ich glaube, dieses Problem kann jetzt mit nur docker build gelöst werden, indem mehrstufige Builds verwendet werden .
Einfach COPY oder ADD den SSH-Schlüssel oder ein anderes Geheimnis, wo immer Sie es brauchen, und verwenden Sie es in RUN Anweisungen, wie Sie möchten.

Verwenden Sie dann eine zweite FROM Anweisung, um ein neues Dateisystem zu starten, und COPY --from=builder , um eine Teilmenge von Verzeichnissen zu importieren, die das Geheimnis nicht enthalten .

(Ich habe das noch nicht wirklich ausprobiert, aber wenn die Funktion wie beschrieben funktioniert...)

@benton mehrstufige Builds funktionieren wie beschrieben, wir verwenden sie. Es ist bei weitem die beste Option für viele verschiedene Probleme, einschließlich dieses.

Ich habe die folgende Technik überprüft:

  1. Übergeben Sie den _Speicherort eines privaten Schlüssels_ als Build-Argument, z. B. GITHUB_SSH_KEY , an die erste Phase eines mehrstufigen Builds
  2. Verwenden Sie ADD oder COPY , um den Schlüssel dorthin zu schreiben, wo er für die Authentifizierung benötigt wird. Beachten Sie, dass, wenn der Schlüsselspeicherort ein lokaler Dateisystempfad (und keine URL) ist, er _nicht_ in der .dockerignore Datei enthalten sein darf, da sonst die COPY Direktive nicht funktioniert. Dies hat Auswirkungen auf das endgültige Bild, wie Sie in Schritt 4 sehen werden ...
  3. Verwenden Sie den Schlüssel nach Bedarf. Im folgenden Beispiel wird der Schlüssel verwendet, um sich bei GitHub zu authentifizieren. Dies funktioniert auch für Rubys bundler und private Gem-Repositorys. Je nachdem, wie viel von der Codebasis Sie an dieser Stelle einschließen müssen, können Sie den Schlüssel als Nebeneffekt der Verwendung von COPY . oder ADD . erneut hinzufügen.
  4. ENTFERNEN SIE DEN SCHLÜSSEL, WENN ERFORDERLICH . Wenn der Schlüsselspeicherort ein lokaler Dateisystempfad (und keine URL) ist, wurde er wahrscheinlich zusammen mit der Codebasis hinzugefügt, als Sie ADD . oder COPY . in das endgültige Laufzeit-Image kopiert werden, daher möchten Sie wahrscheinlich auch eine RUN rm -vf ${GITHUB_SSH_KEY} Anweisung einfügen, sobald Sie mit der Verwendung des Schlüssels fertig sind.
  5. Sobald Ihre App vollständig in WORKDIR , starten Sie die zweite Build-Phase mit einer neuen FROM Anweisung, die Ihr gewünschtes Laufzeit-Image angibt. Installieren Sie alle erforderlichen Laufzeitabhängigkeiten und dann COPY --from=builder gegen die WORKDIR aus der ersten Phase.

Hier ist ein Beispiel Dockerfile , das die obige Technik demonstriert. Die Angabe eines GITHUB_SSH_KEY Build-Arguments testet die GitHub-Authentifizierung beim Erstellen, aber die Schlüsseldaten werden _nicht_ in das endgültige Laufzeit-Image aufgenommen. GITHUB_SSH_KEY kann ein Dateisystempfad (innerhalb des Docker-Build-Verzeichnisses) oder eine URL sein, die die Schlüsseldaten bereitstellt, aber der Schlüssel selbst darf in diesem Beispiel nicht verschlüsselt werden.

########################################################################
# BUILD STAGE 1 - Start with the same image that will be used at runtime
FROM ubuntu:latest as builder

# ssh is used to test GitHub access
RUN apt-get update && apt-get -y install ssh

# The GITHUB_SSH_KEY Build Argument must be a path or URL
# If it's a path, it MUST be in the docker build dir, and NOT in .dockerignore!
ARG GITHUB_SSH_KEY=/path/to/.ssh/key

  # Set up root user SSH access for GitHub
ADD ${GITHUB_SSH_KEY} /root/.ssh/id_rsa

# Add the full application codebase dir, minus the .dockerignore contents...
# WARNING! - if the GITHUB_SSH_KEY is a file and not a URL, it will be added!
COPY . /app
WORKDIR /app

# Build app dependencies that require SSH access here (bundle install, etc.)
# Test SSH access (this returns false even when successful, but prints results)
RUN ssh -o StrictHostKeyChecking=no -vT [email protected] 2>&1 | grep -i auth

# Finally, remove the $GITHUB_SSH_KEY if it was a file, so it's not in /app!
# It can also be removed from /root/.ssh/id_rsa, but you're probably not going
# to COPY that directory into the runtime image.
RUN rm -vf ${GITHUB_SSH_KEY} /root/.ssh/id*

########################################################################
# BUILD STAGE 2 - copy the compiled app dir into a fresh runtime image
FROM ubuntu:latest as runtime
COPY --from=builder /app /app

Es _könnte_ sicherer sein, die Schlüsseldaten selbst im GITHUB_SSH_KEY Build-Argument zu übergeben, anstatt den _Standort_ der Schlüsseldaten. Dies würde ein versehentliches Einfügen der Schlüsseldaten verhindern, wenn sie in einer lokalen Datei gespeichert und dann mit COPY . hinzugefügt werden. Dies würde jedoch die Verwendung von echo und einer Shell-Umleitung erfordern, um die Daten in das Dateisystem zu schreiben, was möglicherweise nicht in allen Basisimages funktioniert. Verwenden Sie die Methode, die für Ihren Satz von Basisbildern am sichersten und am besten durchführbar ist.

@jbiel Ein weiteres Jahr, und die Lösung, die ich gefunden habe, besteht darin, so etwas wie Vault zu verwenden.

Hier ist ein Link mit 2 Methoden (Squash und Zwischencontainer, die zuvor von @benton beschrieben wurden)

Ich füge nur eine Anmerkung hinzu, um zu sagen, dass keiner der aktuellen Ansätze funktioniert, wenn Sie eine Passphrase für den von Ihnen verwendeten ssh-Schlüssel haben, da der Agent Sie jedes Mal zur Eingabe der Passphrase auffordert, wenn Sie die Aktion ausführen, für die der Zugriff erforderlich ist. Ich denke, es gibt keinen Weg, dies zu umgehen, ohne den Schlüsselsatz zu umgehen (was aus einer Reihe von Gründen unerwünscht ist).

Lösen.
Bash-Skript erstellen (~/bin/docker-compose oder ähnliches):

#!/bin/bash

trap 'kill $(jobs -p)' EXIT
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &

/usr/bin/docker-compose $@

Und in Dockerfile mit socat:

...
ENV SSH_AUTH_SOCK /tmp/auth.sock
...
  && apk add --no-cache socat openssh \
  && /bin/sh -c "socat -v UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:172.22.1.11:56789 &> /dev/null &" \
  && bundle install \
...
or any other ssh commands will works

Führen Sie dann docker-compose build

@benton warum verwendest du RUN rm -vf ${GITHUB_SSH_KEY} /root/.ssh/id* ? Sollte es nicht einfach RUN rm -vf /root/.ssh/id* ? Oder vielleicht habe ich die Absicht hier falsch verstanden.

@benton Und es ist auch nicht sicher:

RUN ssh -o StrictHostKeyChecking=no -vT [email protected] 2>&1

Sie müssen den Fingerabdruck überprüfen

Ich habe dieses Problem auf diese Weise gelöst

ARGS USERNAME
ARGS PASSWORD
RUN git config --global url."https://${USERNAME}:${PASSWORD}@github.com".insteadOf "ssh://[email protected]"

dann bauen mit

docker build --build-arg USERNAME=use --build-arg PASSWORD=pwd. -t service

Aber zuerst muss Ihr privater Git-Server username:password Klon-Repo unterstützen.

@zeayes RUN-Befehl im Containerverlauf gespeichert. So ist Ihr Passwort für andere sichtbar.

Richtig; Wenn Sie --build-arg / ARG , werden diese Werte im Build-Verlauf angezeigt. Es _ist_ möglich, diese Technik zu verwenden, wenn Sie mehrstufige Builds verwenden _und_ dem Host vertrauen, auf dem die Images erstellt werden (dh kein nicht vertrauenswürdiger Benutzer hat Zugriff auf die lokale Build-Historie), _und_ Zwischenbuild-Phasen nicht an eine Registry gepusht werden.

Im folgenden Beispiel werden beispielsweise USERNAME und PASSWORD nur in der Historie der ersten Phase ("builder") vorkommen, aber nicht in der Historie der letzten Phase;

FROM something AS builder
ARG USERNAME
ARG PASSWORD
RUN something that uses $USERNAME and $PASSWORD

FROM something AS finalstage
COPY --from= builder /the/build-artefacts /usr/bin/something

Wenn nur das endgültige Image (erzeugt von "finalstage") in eine Registry gepusht wird, dann sind USERNAME und PASSWORD nicht in diesem Image enthalten.

_Allerdings_ werden diese Variablen im lokalen Build-Cache-Verlauf immer noch vorhanden sein (und im Klartext auf der Festplatte gespeichert).

Der Builder der nächsten Generation (mit BuildKit ) wird mehr Funktionen haben, auch im Zusammenhang mit der Weitergabe von Build-Time-Geheimnissen; es ist in Docker 18.06 als experimentelle Funktion verfügbar, wird aber in einer zukünftigen Version aus dem Experimental herauskommen und weitere Funktionen werden hinzugefügt (ich müsste prüfen, ob Geheimnisse/Anmeldeinformationen in der aktuellen Version bereits möglich sind)

@kinnalru @thaJeztah thx, ich verwende mehrstufige Builds, aber das Passwort kann in der Historie des Cache-Containers eingesehen werden, thx!

@zeayes Oh! Ich sehe, dass ich einen Kopier-/Einfügefehler gemacht habe; letzte Stufe darf nicht FROM builder .. . Hier ist ein vollständiges Beispiel; https://gist.github.com/thaJeztah/af1c1e3da76d7ad6ce2abab891506e50

Dieser Kommentar von @kinnalru ist der richtige Weg, dies zu tun https://github.com/moby/moby/issues/6396#issuecomment -348103398

Bei dieser Methode verarbeitet Docker niemals Ihre privaten Schlüssel. Und es funktioniert auch heute, ohne dass neue Funktionen hinzugefügt werden.

Ich habe eine Weile gebraucht, um es herauszufinden, daher ist hier eine klarere und verbesserte Erklärung. Ich habe den @kinnalru- Code geändert, um --network=host und localhost , sodass Sie Ihre IP-Adresse nicht kennen müssen. ( Hauptsache hier )

Dies ist docker_with_host_ssh.sh , es umschließt Docker und leitet SSH_AUTH_SOCK an einen Port auf localhost weiter:

#!/usr/bin/env bash

# ensure the processes get killed when we're done
trap 'kill $(jobs -p)' EXIT

# create a connection from port 56789 to the unix socket SSH_AUTH_SOCK (which is used by ssh-agent)
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &
# Run docker
# Pass it all the command line args ($@)
# set the network to "host" so docker can talk to localhost
docker $@ --network='host'

Im Dockerfile verbinden wir uns über localhost mit dem Hosts ssh-agent:

FROM python:3-stretch

COPY . /app
WORKDIR /app

RUN mkdir -p /tmp

# install socat and ssh to talk to the host ssh-agent
RUN  apt-get update && apt-get install git socat openssh-client \
  # create variable called SSH_AUTH_SOCK, ssh will use this automatically
  && export SSH_AUTH_SOCK=/tmp/auth.sock \
  # make SSH_AUTH_SOCK useful by connecting it to hosts ssh-agent over localhost:56789
  && /bin/sh -c "socat UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:localhost:56789 &" \
  # stuff I needed my ssh keys for
  && mkdir -p ~/.ssh \
  && ssh-keyscan gitlab.com > ~/.ssh/known_hosts \
  && pip install -r requirements.txt

Dann können Sie Ihr Image erstellen, indem Sie das Skript aufrufen:

$ docker_with_host_ssh.sh build -f ../docker/Dockerfile .

@cowlicks Vielleicht interessiert Sie dieser Pull-Request, der Unterstützung für docker build --ssh hinzufügt, um den SSH-Agenten während des Builds weiterzuleiten; https://github.com/docker/cli/pull/1419. Die Dockerfile-Syntax ist noch nicht in den offiziellen Spezifikationen enthalten, aber Sie können eine syntax=.. Direktive in Ihrem Dockerfile verwenden, um ein Frontend zu verwenden, das sie unterstützt (siehe Beispiel/Anleitung im Pull-Request).

Dieser Pull-Request wird Teil der kommenden Version 18.09 sein.

Es sieht so aus, als ob dies jetzt in der Version 18.09 verfügbar ist. Da dieser Thread vor den Release Notes und dem Medium Post auftaucht, werde ich hier Cross-Postings machen.

Versionshinweise:
https://docs.docker.com/develop/develop-images/build_enhancements/#using -ssh-to-access-private-data-in-builds

Mittlerer Beitrag:
https://medium.com/@tonistiigi/build -secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066

Sehr aufregend.

Ich denke, wir können das schließen, weil wir jetzt docker build --ssh

Zugehöriges Compose-Problem hier: docker/compose#6865. Compose Funktionalität zu verwenden und SSH Mittel Buchse auf Behälter belichten merkte Landung zu sein in der nächsten Release - Kandidaten, 1.25.0-RC3 ( Veröffentlichungen ).

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen