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?


3
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.
Matthijs Kooijman

Eine weitere Präsentation der openssh 6.7+ -Lösung finden Sie unter 2015.rmll.info/IMG/pdf/an-advanced-introduction-to-gnupg.pdf
phs

Das war nützlich für mich.
PHS

Antworten:


16

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.

Sie sollten in der Lage sein, etwas wie:

ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9

@DrewR. Freut mich das zu hören.
Brian Minton

2
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:

Host remote
  RemoteForward <remote socket> <local socket>

Schnelle Lösung zum Kopieren der öffentlichen Schlüssel:

scp .gnupg/pubring.kbx remote:~/.gnupg/

Aktivieren Sie auf dem Remotecomputer den GPG-Agenten:

echo use-agent >> ~/.gnupg/gpg.conf

Ändern Sie auf dem Remotecomputer auch die SSH-Serverkonfiguration und fügen Sie diesen Parameter hinzu (/ etc / ssh / sshd_config):

StreamLocalBindUnlink yes

Starten Sie den SSH-Server neu, stellen Sie die Verbindung zum Remotecomputer wieder her - dann sollte es funktionieren.


Ein ausführlicheres Tutorial mit Hinweisen zur Fehlerbehebung finden Sie hier: mlohr.com/gpg-agent-forwarding
MaLo

1
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:

  1. Die Schlüsselringe, die Sie zum Signieren / En / Entschlüsseln von Inhalten verwenden möchten.
  2. 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

  1. Zusätzliche Konfiguration auf der Fernbedienung /etc/sshd_config:

    StreamLocalBindUnlink yes
    
  2. Importieren Sie Ihren öffentlichen Schlüssel auf Remote:

    gpg --export <your-key> >/tmp/public
    scp /tmp/public <remote-host>:/tmp/public
    ssh <remote-host> gpg --import /tmp/public
    
  3. Befehl zum Verbinden über SSH mit aktivierter Weiterleitung von gpg-Agenten: (Pfade für mein Debian)

    ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
    

@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:

systemctl --global mask --now \
  gpg-agent.service \
  gpg-agent.socket \
  gpg-agent-ssh.socket \
  gpg-agent-extra.socket \
  gpg-agent-browser.socket

Beachten Sie, dass dies alle Benutzer auf dem Host betrifft .

Bonus: So testen Sie die Weiterleitung von GPG-Agenten:

  • Lokal: ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
  • Überprüfen Sie, ob ${remote_sock}dies in der ausführlichen Ausgabe von ssh angezeigt wird
  • Fernbedienung: ls -l ${remote_sock}
  • Fernbedienung: gpg --list-secret-keys
    • Sie sollten viele debug1Nachrichten von ssh sehen, die den weitergeleiteten Verkehr anzeigen

Wenn das nicht funktioniert (wie bei mir nicht), können Sie nachverfolgen, auf welchen Socket GPG zugreift:

strace -econnect gpg --list-secret-keys

Beispielausgabe:

connect(5, {sa_family=AF_UNIX, sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0

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 ...)

Getestet unter Ubuntu 16.04

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.