webentwicklung-frage-antwort-db.com.de

Fügen Sie die Host-SSH-Schlüssel in Docker Machine mit Docker Compose ein

Ich verwende Docker unter Mac OS X mit Docker Machine (mit der Standard-Boot2docker-Maschine) und benutze Docker-Compose, um meine Entwicklungsumgebung einzurichten.

Nehmen wir an, einer der Container heißt "stack". Jetzt möchte ich anrufen:

docker-composer run stack ssh [email protected]

Mein öffentlicher Schlüssel (der zu stackoverflow.com hinzugefügt wurde und der zur Authentifizierung verwendet wird) befindet sich auf dem Host-Computer. Ich möchte, dass dieser Schlüssel für den Docker Machine-Container verfügbar ist, sodass ich mich mit diesem Schlüssel aus dem Container heraus gegen stackoverflow authentifizieren kann. Vorzugsweise, ohne meinen Schlüssel physisch auf Docker Machine zu kopieren.

Gibt es eine Möglichkeit, dies zu tun? Wenn mein Schlüssel passwortgeschützt ist, gibt es eine Möglichkeit, ihn einmal zu entsperren, so dass ich nach jeder Injektion das Passwort nicht manuell eingeben muss?

15
Ruslan

Sie können dies zu Ihrer Docker-compose.yml hinzufügen (vorausgesetzt, Ihr Benutzer in container ist root):

volumes:
    - ~/.ssh:/root/.ssh

Sie können auch nach weiterentwickelter Lösung mit ssh agent suchen (ich habe es selbst nicht versucht)

32
Anton Serdyuk

Docker hat eine Funktion namens Geheimnisse, die hier hilfreich sein kann. Um es zu benutzen, könnte man den folgenden Code zu docker-compose.yml hinzufügen:

---
version: '3.1' # Note the minimum file version for this feature to work
services:
  stack:
    ...
    secrets:
      - Host_ssh_key

secrets:
  Host_ssh_key:
    file: ~/.ssh/id_rsa

Dann kann auf die neue geheime Datei in Dockerfile wie folgt zugegriffen werden:

RUN mkdir ~/.ssh && ln -s /run/secrets/Host_ssh_key ~/.ssh/id_rsa

Geheime Dateien werden nicht in den Container kopiert:

Wenn Sie einem neu erstellten oder laufenden Dienst Zugriff auf ein Geheimnis gewähren, wird das entschlüsselte Geheimnis in einem In-Memory-Dateisystem in den Container eingebunden

Für weitere Details lesen Sie bitte:

10
Anton Styagun

Sie können den SSH-Agenten weiterleiten:

something:
    container_name: something
    volumes:
        - $SSH_AUTH_SOCK:/ssh-agent # Forward local machine SSH key to docker
    environment:
        SSH_AUTH_SOCK: /ssh-agent
5
Aistis

Wenn Sie OS X und verschlüsselte Schlüssel verwenden, wird dies PITA sein. Hier sind die Schritte Ich habe das herausgefunden.

Unkomplizierter Ansatz

Man könnte meinen, dass es kein Problem gibt. Mounten Sie einfach Ihren SSH-Ordner:

...
volumes:
  - ~/.ssh:/root/.ssh:ro
...

Das sollte funktionieren, richtig?

Benutzerproblem

Als Nächstes werden wir feststellen, dass wir die falsche Benutzer-ID verwenden. Gut, wir schreiben ein Skript zum Kopieren und Ändern des Besitzers von SSH-Schlüsseln. Wir setzen den ssh-Benutzer auch in config, damit der ssh-Server weiß, wer sich verbindet.

...
volumes:
  - ~/.ssh:/root/.ssh-keys:ro
command: sh -c ‘./.ssh-keys.sh && ...’
environment:
  SSH_USER: $USER
...

# ssh-keys.sh
mkdir -p ~/.ssh
cp -r /root/.ssh-keys/* ~/.ssh/
chown -R $(id -u):$(id -g) ~/.ssh

cat <<EOF >> ~/.ssh/config
  User $SSH_USER
EOF

SSH-Schlüssel-Passphrasenproblem

In unserem Unternehmen schützen wir SSH-Schlüssel mit einer Passphrase. Im Docker funktioniert das nicht, da es nicht praktikabel ist, jedes Mal, wenn wir einen Container starten, eine Passphrase einzugeben. Wir könnten eine Passphrase entfernen (siehe Beispiel unten), es besteht jedoch ein Sicherheitsrisiko.

openssl rsa -in id_rsa -out id_rsa2
# enter passphrase
# replace passphrase-encrypted key with plaintext key:
mv id_rsa2 id_rsa

SSH-Agentenlösung

Möglicherweise haben Sie festgestellt, dass Sie vor Ort nicht jedes Mal eine Passphrase eingeben müssen, wenn Sie SSH-Zugriff benötigen. Warum ist das so? Dafür gibt es einen SSH-Agenten. Der SSH-Agent ist im Grunde ein Server, der auf eine spezielle Datei, einen Unix-Socket, namens "ssh auth sock", wartet. Sie können den Ort auf Ihrem System sehen:

echo $SSH_AUTH_SOCK
# /run/user/1000/keyring-AvTfL3/ssh

Der SSH-Client kommuniziert über diese Datei mit dem SSH-Agenten, sodass Sie die Passphrase nur einmal eingeben. Sobald es unverschlüsselt ist, speichert der SSH-Agent ihn im Speicher und sendet ihn auf Anfrage an den SSH-Client. Können wir das in Docker verwenden? Mounten Sie einfach diese spezielle Datei und geben Sie eine entsprechende Umgebungsvariable an:

environment:
  SSH_AUTH_SOCK: $SSH_AUTH_SOCK
  ...
volumes:
  - $SSH_AUTH_SOCK:$SSH_AUTH_SOCK

In diesem Fall brauchen wir nicht einmal Schlüssel zu kopieren ... Um die Verfügbarkeit der Schlüssel zu bestätigen, können Sie das Dienstprogramm ssh-add verwenden:

if [ -z "$SSH_AUTH_SOCK" ]; then
  echo "No ssh agent detected"
else
  echo $SSH_AUTH_SOCK
  ssh-add -l
fi

Das Problem der Unix-Socket-Mount-Unterstützung in Docker für Mac

Unglücklicherweise für Benutzer von OS X hat Docker für Mac eine Reihe von Nachteilen, darunter Unix-Sockets zwischen Mac und Linux. Es gibt ein offenes Problem in D4M Github . Ab Februar 2019 ist es noch geöffnet.

Ist das eine Sackgasse? Nein, es gibt eine harte Workaround.

Weiterleitungslösung für SSH-Agenten

Glücklicherweise ist diese Ausgabe nicht neu. Lange vor dem Docker gab es eine Möglichkeit, lokale SSH-Schlüssel innerhalb einer Remote-SSH-Sitzung zu verwenden. Dies wird als ssh agent forwarding bezeichnet. Die Idee ist einfach: Sie stellen über ssh eine Verbindung zu einem Remote-Server her, und Sie können dort alle Remote-Server verwenden, um Ihre Schlüssel gemeinsam zu nutzen.

Mit Docker für Mac können Sie einen intelligenten Trick verwenden: Den ssh-Agenten über die TCP ssh-Verbindung für die virtuelle Docker-Maschine freigeben und diese Datei von der virtuellen Maschine in einen anderen Container einhängen, in dem diese SSH-Verbindung benötigt wird. Hier ist ein Bild, um die Lösung zu demonstrieren:

SSH forwarding

Zuerst erstellen wir eine SSH-Sitzung für den SSH-Server in einem Container in einem Linux VM über einen TCP -Port. Wir verwenden hier eine echte ssh auth Socke.

Als nächstes leitet der SSH-Server unsere SSH-Schlüssel an den SSH-Agenten in diesem Container weiter. Der SSH-Agent verfügt über einen Unix-Socket, der einen an die Linux-VM angehängten Ort verwendet. D.h. Unix-Socket funktioniert unter Linux. Eine nicht funktionierende Unix-Socket-Datei in Mac hat keine Auswirkungen.

Danach erstellen wir unseren nützlichen Container mit einem SSH-Client. Wir teilen die Unix-Socket-Datei, die von unserer lokalen SSH-Sitzung verwendet wird.

Es gibt eine Reihe von Skripts, die diesen Vorgang vereinfachen: https://github.com/avsm/docker-ssh-agent-forward

Fazit

SSH in Docker zum Laufen zu bringen, war einfacher. Aber es kann gemacht werden. Und es wird wahrscheinlich in der Zukunft verbessert. Zumindest die Docker-Entwickler kennen dieses Problem. Und sogar gelöst für Dockerfiles mit Build Time Geheimnissen . Und es gibt einen Vorschlag , wie Unix-Domain-Sockets unterstützt werden.

1
Vanuan