Wie kann ich einen gpg-Schlüssel per ssh-agent weiterleiten?
29
Ich kann die ssh-Konfigurationsdatei verwenden, um die Weiterleitung der zu ssh-agent hinzugefügten ssh-Schlüssel zu ermöglichen. Wie kann ich dasselbe mit GPG-Schlüsseln machen?
Beide Antworten schlagen vor, socat auszuführen, um den GPG-Agent-Unix-Socket auf einem TCP-Port verfügbar zu machen. Im Gegensatz zu Unix-Sockets haben TCP-Ports bei der Zugriffssteuerung jedoch nicht dieselbe Ebene. Insbesondere kann jetzt jeder Benutzer auf demselben Host eine Verbindung zu Ihrem GPG-Agenten herstellen. Dies ist wahrscheinlich in Ordnung, wenn Sie einen Einzelbenutzer-Laptop haben. Wenn sich jedoch auch andere Benutzer bei demselben System anmelden können (dem System, auf dem der GPG-Agent ausgeführt wird), können sie auch auf Ihren GPG-Agenten zugreifen, was ein erhebliches Sicherheitsproblem darstellt. Es ist wahrscheinlich die beste Möglichkeit, dies zu beheben, wenn Sie socat mithilfe des EXEC-Adresstyps direkt SSH starten lassen.
BEARBEITEN: Diese Antwort ist veraltet, da die entsprechende Unterstützung in OpenSSH implementiert wurde (siehe Brian Mintons Antwort).
SSH kann nur TCP-Verbindungen innerhalb des Tunnels weiterleiten.
Sie können jedoch ein Programm verwenden, socatum den Unix-Socket über TCP weiterzuleiten (Sie benötigen socat sowohl auf dem Client- als auch auf dem Server-Host):
# Get the path of gpg-agent socket:
GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)
# Forward some local tcp socket to the agent
(while true; do
socat TCP-LISTEN:12345,bind=127.0.0.1 UNIX-CONNECT:$GPG_SOCK;
done) &
# Connect to the remote host via ssh, forwarding the TCP port
ssh -R12345:localhost:12345 host.example.com
# (On the remote host)
(while true; do
socat UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early TCP4:localhost:12345;
done) &
Testen Sie, ob es mit funktioniert gpg-connect-agent. Stellen Sie sicher, dass GPG_AGENT_INFO auf dem Remote-Host undefiniert ist, damit es auf den $HOME/.gnupg/S.gpg-agentSocket zurückfällt .
Jetzt brauchen Sie hoffentlich nur noch eine Möglichkeit, dies alles automatisch auszuführen!
Nun, die SSH-Agent-Schlüssel werden automatisch weitergeleitet, wenn die Weiterleitung in der Konfigurationsdatei festgelegt ist. Ich werde das ausprobieren.
Txwikinger
Sie haben Recht, ssh-agent verwendet auch einen Unix-Socket, hat aber spezielle Unterstützung dafür (hier ein bisschen müde :) Trotzdem sollte die Lösung immer noch funktionieren.
Freitag,
1
Für diese Lösung wäre mein gpg-Agent über Port 12345 öffentlich zugänglich, wenn ich mich nicht hinter einer Firewall / NAT befände. Dies sollte bitte in der Antwort erwähnt werden.
Jonas Schäfer
Ich vermute, deine letzte Bearbeitung hat das Problem behoben, Jonas? es ist erst localhostjetzt verbindlich .
1.
Dies nicht für mich mit folgendem Argument vom Remote - Hosts gpg-connect-agent: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC. Die Fernbedienung socatstirbt dann. Die lokale socatstirbt und spricht socat[24692] E connect(3, AF=1 "", 2): Invalid argument. Diese Seite lässt mich glauben, dass dies niemals funktionieren wird, da der Agent den Schlüssel (nur die Passphrase) nicht speichert. Wurde bestätigt, dass dies von irgendjemandem funktioniert?
1.
17
Das neue Unix Domain Socket Forwarding von OpenSSH kann dies direkt ab Version 6.7.
Ich habe ein erforderliches kritisches Detail gefunden: Auf dem Remote-Computer (ohne privaten Schlüssel) muss der öffentliche Schlüssel der signierenden Identität vorhanden sein. Lokale GPG-Version 2.1.15 OS X, Remote 2.1.11 Linux.
phs
4
In neuen Versionen von GnuPG- oder Linux-Distributionen können sich die Pfade der Sockets ändern. Diese können über ermittelt werden
$ gpgconf --list-dirs agent-extra-socket
und
$ gpgconf --list-dirs agent-socket
Fügen Sie dann diese Pfade zu Ihrer SSH-Konfiguration hinzu:
Falls der entfernte Host eine aktuelle Version von Debian ausführt, scheint systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socketes erforderlich zu sein, zu laufen, um zu verhindern, dass systemd einen Socket startet, der den entfernten gpg-Agenten stiehlt. Laut bugs.debian.org/850982 ist dies das beabsichtigte Verhalten.
Sampi
3
Ich musste das Gleiche tun und basierte mein Skript auf der Lösung von b0fh mit ein paar kleinen Änderungen: Es fängt Exits ab und bricht Hintergrundprozesse ab und verwendet die Optionen "fork" und "reuseaddr", um socat zu verwenden, was Ihnen das erspart Schleife (und macht den Hintergrund socat sauber tötbar).
Das Ganze lässt sich in einem Rutsch einrichten, sodass es wahrscheinlich einem automatisierten Setup näher kommt.
Beachten Sie, dass Sie auf dem Remote-Host Folgendes benötigen:
Die Schlüsselringe, die Sie zum Signieren / En / Entschlüsseln von Inhalten verwenden möchten.
Je nach Version von gpg auf der Fernbedienung eine gefälschte GPG_AGENT_INFOVariable. Ich fülle meine mit vor ~/.gnupg/S.gpg-agent:1:1- die erste 1 ist eine PID für den gpg-Agenten (ich täusche sie als "init" vor, was immer läuft), die zweite ist die Versionsnummer des Agentenprotokolls. Dies sollte mit dem übereinstimmen, der auf Ihrem lokalen Computer ausgeführt wird.
#!/bin/bash -e
FORWARD_PORT=${1:-12345}
trap '[ -z "$LOCAL_SOCAT" ] || kill -TERM $LOCAL_SOCAT' EXIT
GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)
if [ -z "$GPG_SOCK" ] ; then
echo "No GPG agent configured - this won't work out." >&2
exit 1
fi
socat TCP-LISTEN:$FORWARD_PORT,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:$GPG_SOCK &
LOCAL_SOCAT=$!
ssh -R $FORWARD_PORT:127.0.0.1:$FORWARD_PORT socat 'UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early,fork,reuseaddr TCP4:localhost:$FORWARD_PORT'
Ich glaube, es gibt auch eine Lösung, die nur einen SSH-Befehlsaufruf (Rückverbindung vom Remote-Host zum lokalen Host) umfasst -o LocalCommand, aber ich konnte nicht genau herausfinden, wie man das beim Beenden bequem beendet.
Vermissen Sie nicht ein Argument 'user @ host' vor socat im letzten Befehl? Trotzdem schlägt dies auch nach dem Beheben des Problems fehl, wenn "socat [6788] E connect (3, AF = 2 127.0.0.1:0, 16): Verbindung abgelehnt" lokal angezeigt wird, wenn gpg-connect-agent aus der Ferne versucht wird.
David Faure
1
Laut GnuPG-Wiki müssen Sie den Remote-Socket S.gpg-agent.extraan den lokalen Socket weiterleiten S.gpg-agent. Darüber hinaus müssen Sie StreamLocalBindUnlinkauf dem Server aktivieren .
Denken Sie daran, dass Sie auch den öffentlichen Teil Ihres Schlüssels benötigen, der auf GnuPG verfügbar ist .
Verwenden Sie gpgconf --list-dir agent-socketjeweils gpgconf --list-dir agent-extra-socketauf der Fernbedienung, um die tatsächlichen Pfade abzurufen.
Zusammenfassung
Zusätzliche Konfiguration auf der Fernbedienung /etc/sshd_config:
StreamLocalBindUnlink yes
Importieren Sie Ihren öffentlichen Schlüssel auf Remote:
@brian minton: Es funktioniert bei mir nicht, wenn nicht an die extra Buchse weitergeleitet wird.
Doak
0
Alternativ zum Ändern /etc/ssh/sshd_configmit StreamLocalBindUnlink yeskönnen Sie auch die Erstellung der Socket-Dateien verhindern, die ersetzt werden müssen:
In meinem Fall stimmte der Pfad, auf den zugegriffen wurde, perfekt überein ${remote_sock}, aber dieser Socket wurde nicht erstellt, sshdals ich mich anmeldete, obwohl ich StreamLocalBindUnlink yesmeinen hinzugefügt habe /etc/ssh/sshd_config. Ich wurde von systemd bei der Anmeldung erstellt.
(Beachten Sie, dass ich zu feige war, um sshd neu zu starten , da ich momentan keinen physischen Zugriff auf den Host habe. Offensichtlich service reload sshdwar das nicht ausreichend ...)
Antworten:
BEARBEITEN: Diese Antwort ist veraltet, da die entsprechende Unterstützung in OpenSSH implementiert wurde (siehe Brian Mintons Antwort).
SSH kann nur TCP-Verbindungen innerhalb des Tunnels weiterleiten.
Sie können jedoch ein Programm verwenden,
socat
um den Unix-Socket über TCP weiterzuleiten (Sie benötigen socat sowohl auf dem Client- als auch auf dem Server-Host):Testen Sie, ob es mit funktioniert
gpg-connect-agent
. Stellen Sie sicher, dass GPG_AGENT_INFO auf dem Remote-Host undefiniert ist, damit es auf den$HOME/.gnupg/S.gpg-agent
Socket zurückfällt .Jetzt brauchen Sie hoffentlich nur noch eine Möglichkeit, dies alles automatisch auszuführen!
quelle
localhost
jetzt verbindlich .gpg-connect-agent
:can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC
. Die Fernbedienungsocat
stirbt dann. Die lokalesocat
stirbt und sprichtsocat[24692] E connect(3, AF=1 "", 2): Invalid argument
. Diese Seite lässt mich glauben, dass dies niemals funktionieren wird, da der Agent den Schlüssel (nur die Passphrase) nicht speichert. Wurde bestätigt, dass dies von irgendjemandem funktioniert?Das neue Unix Domain Socket Forwarding von OpenSSH kann dies direkt ab Version 6.7.
Sie sollten in der Lage sein, etwas wie:
quelle
In neuen Versionen von GnuPG- oder Linux-Distributionen können sich die Pfade der Sockets ändern. Diese können über ermittelt werden
und
Fügen Sie dann diese Pfade zu Ihrer SSH-Konfiguration hinzu:
Schnelle Lösung zum Kopieren der öffentlichen Schlüssel:
Aktivieren Sie auf dem Remotecomputer den GPG-Agenten:
Ändern Sie auf dem Remotecomputer auch die SSH-Serverkonfiguration und fügen Sie diesen Parameter hinzu (/ etc / ssh / sshd_config):
Starten Sie den SSH-Server neu, stellen Sie die Verbindung zum Remotecomputer wieder her - dann sollte es funktionieren.
quelle
systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
es erforderlich zu sein, zu laufen, um zu verhindern, dass systemd einen Socket startet, der den entfernten gpg-Agenten stiehlt. Laut bugs.debian.org/850982 ist dies das beabsichtigte Verhalten.Ich musste das Gleiche tun und basierte mein Skript auf der Lösung von b0fh mit ein paar kleinen Änderungen: Es fängt Exits ab und bricht Hintergrundprozesse ab und verwendet die Optionen "fork" und "reuseaddr", um socat zu verwenden, was Ihnen das erspart Schleife (und macht den Hintergrund socat sauber tötbar).
Das Ganze lässt sich in einem Rutsch einrichten, sodass es wahrscheinlich einem automatisierten Setup näher kommt.
Beachten Sie, dass Sie auf dem Remote-Host Folgendes benötigen:
GPG_AGENT_INFO
Variable. Ich fülle meine mit vor~/.gnupg/S.gpg-agent:1:1
- die erste 1 ist eine PID für den gpg-Agenten (ich täusche sie als "init" vor, was immer läuft), die zweite ist die Versionsnummer des Agentenprotokolls. Dies sollte mit dem übereinstimmen, der auf Ihrem lokalen Computer ausgeführt wird.Ich glaube, es gibt auch eine Lösung, die nur einen SSH-Befehlsaufruf (Rückverbindung vom Remote-Host zum lokalen Host) umfasst
-o LocalCommand
, aber ich konnte nicht genau herausfinden, wie man das beim Beenden bequem beendet.quelle
Laut GnuPG-Wiki müssen Sie den Remote-Socket
S.gpg-agent.extra
an den lokalen Socket weiterleitenS.gpg-agent
. Darüber hinaus müssen SieStreamLocalBindUnlink
auf dem Server aktivieren .Denken Sie daran, dass Sie auch den öffentlichen Teil Ihres Schlüssels benötigen, der auf GnuPG verfügbar ist .
Verwenden Sie
gpgconf --list-dir agent-socket
jeweilsgpgconf --list-dir agent-extra-socket
auf der Fernbedienung, um die tatsächlichen Pfade abzurufen.Zusammenfassung
Zusätzliche Konfiguration auf der Fernbedienung
/etc/sshd_config
:Importieren Sie Ihren öffentlichen Schlüssel auf Remote:
Befehl zum Verbinden über SSH mit aktivierter Weiterleitung von gpg-Agenten: (Pfade für mein Debian)
quelle
Alternativ zum Ändern
/etc/ssh/sshd_config
mitStreamLocalBindUnlink yes
können Sie auch die Erstellung der Socket-Dateien verhindern, die ersetzt werden müssen:Beachten Sie, dass dies alle Benutzer auf dem Host betrifft .
Bonus: So testen Sie die Weiterleitung von GPG-Agenten:
ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
${remote_sock}
dies in der ausführlichen Ausgabe von ssh angezeigt wirdls -l ${remote_sock}
gpg --list-secret-keys
debug1
Nachrichten von ssh sehen, die den weitergeleiteten Verkehr anzeigenWenn das nicht funktioniert (wie bei mir nicht), können Sie nachverfolgen, auf welchen Socket GPG zugreift:
Beispielausgabe:
In meinem Fall stimmte der Pfad, auf den zugegriffen wurde, perfekt überein
${remote_sock}
, aber dieser Socket wurde nicht erstellt,sshd
als ich mich anmeldete, obwohl ichStreamLocalBindUnlink yes
meinen hinzugefügt habe/etc/ssh/sshd_config
. Ich wurde von systemd bei der Anmeldung erstellt.(Beachten Sie, dass ich zu feige war, um sshd neu zu starten , da ich momentan keinen physischen Zugriff auf den Host habe. Offensichtlich
service reload sshd
war das nicht ausreichend ...)Getestet unter Ubuntu 16.04
quelle