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?
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)
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:
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
Wenn Sie OS X und verschlüsselte Schlüssel verwenden, wird dies PITA sein. Hier sind die Schritte Ich habe das herausgefunden.
Man könnte meinen, dass es kein Problem gibt. Mounten Sie einfach Ihren SSH-Ordner:
...
volumes:
- ~/.ssh:/root/.ssh:ro
...
Das sollte funktionieren, richtig?
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
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
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
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.
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:
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
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.