Posso usare il file di configurazione di ssh per abilitare l'inoltro di chiavi ssh aggiunte a ssh-agent. Come posso fare lo stesso con le chiavi gpg?
Posso usare il file di configurazione di ssh per abilitare l'inoltro di chiavi ssh aggiunte a ssh-agent. Come posso fare lo stesso con le chiavi gpg?
Risposte:
EDIT: questa risposta è obsoleta ora che il supporto adeguato è stato implementato in OpenSSH, vedi la risposta di Brian Minton.
SSH è in grado di inoltrare solo connessioni tcp all'interno del tunnel.
Tuttavia, è possibile utilizzare un programma simile socat
per inoltrare il socket unix su TCP, con qualcosa del genere (sarà necessario socat sia sul client che sugli host del server):
# 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) &
Verifica se funziona gpg-connect-agent
. Assicurarsi che GPG_AGENT_INFO non sia definito sull'host remoto, in modo che ricada sul $HOME/.gnupg/S.gpg-agent
socket.
Spero che tutto ciò di cui hai bisogno sia un modo per eseguire tutto questo automaticamente!
localhost
ora.
gpg-connect-agent
: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC
. Il telecomando socat
quindi muore. Il locale socat
muore e pronuncia socat[24692] E connect(3, AF=1 "", 2): Invalid argument
. Questa pagina mi porta a credere che questo non funzionerà mai, perché l'agente non memorizza la chiave (solo la passphrase). È stato confermato che funziona da qualcuno?
Il nuovo Inoltro socket di dominio Unix di OpenSSH può farlo direttamente a partire dalla versione 6.7.
Dovresti essere in grado di qualcosa come:
ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9
Nelle nuove versioni di GnuPG o distribuzioni Linux i percorsi dei socket possono cambiare. Questi possono essere trovati tramite
$ gpgconf --list-dirs agent-extra-socket
e
$ gpgconf --list-dirs agent-socket
Quindi aggiungi questi percorsi alla tua configurazione SSH:
Host remote
RemoteForward <remote socket> <local socket>
Soluzione rapida per la copia delle chiavi pubbliche:
scp .gnupg/pubring.kbx remote:~/.gnupg/
Sul computer remoto, attiva l'agente GPG:
echo use-agent >> ~/.gnupg/gpg.conf
Sul computer remoto, modificare anche la configurazione del server SSH e aggiungere questo parametro (/ etc / ssh / sshd_config):
StreamLocalBindUnlink yes
Riavvia il server SSH, riconnettiti al computer remoto, quindi dovrebbe funzionare.
systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
sia necessaria per impedire a systemd di lanciare un socket rubando gpg-agent remoto. Secondo bugs.debian.org/850982 questo è il comportamento previsto.
Ho dovuto fare lo stesso, e ho basato il mio script sulla soluzione di b0fh, con alcune minuscole modifiche: intercetta le uscite e uccide i processi in background e utilizza le opzioni "fork" e "reuseaddr" per socat, il che consente di risparmiare loop (e rende lo sfondo socat perfettamente in grado di uccidere).
Il tutto imposta tutto in una volta, quindi probabilmente si avvicina a una configurazione automatizzata.
Nota che sull'host remoto avrai bisogno di:
GPG_AGENT_INFO
variabile . Compilare il mio con ~/.gnupg/S.gpg-agent:1:1
- il primo 1 è un PID per l'agente gpg (lo falso come "init", che è sempre in esecuzione), il secondo è il numero di versione del protocollo dell'agente. Questo dovrebbe corrispondere a quello in esecuzione sul tuo computer locale.
#!/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'
Credo che ci sia anche una soluzione che prevede solo una chiamata al comando SSH (ricollegamento dall'host remoto a quello locale) utilizzando -o LocalCommand
, ma non sono riuscito a capire come ucciderlo comodamente all'uscita.
Secondo GnuPG Wiki , devi inoltrare la presa remota S.gpg-agent.extra
alla presa locale S.gpg-agent
. Inoltre è necessario abilitare StreamLocalBindUnlink
sul server.
Tieni presente che hai anche bisogno della parte pubblica della tua chiave disponibile su GnuPG remoto .
Utilizzare gpgconf --list-dir agent-socket
rispettivamente gpgconf --list-dir agent-extra-socket
sul telecomando per ottenere i percorsi effettivi.
Configurazione aggiunta sul telecomando /etc/sshd_config
:
StreamLocalBindUnlink yes
Importa la tua chiave pubblica sul telecomando:
gpg --export <your-key> >/tmp/public
scp /tmp/public <remote-host>:/tmp/public
ssh <remote-host> gpg --import /tmp/public
Comando per connettersi tramite SSH con l'inoltro dell'agente gpg abilitato: (percorsi per il mio Debian)
ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
In alternativa alla modifica /etc/ssh/sshd_config
conStreamLocalBindUnlink yes
, puoi invece impedire la creazione dei file socket che devono essere sostituiti:
systemctl --global mask --now \
gpg-agent.service \
gpg-agent.socket \
gpg-agent-ssh.socket \
gpg-agent-extra.socket \
gpg-agent-browser.socket
Si noti che questo influisce tutti gli utenti sull'host.
Bonus: come testare l'inoltro dell'agente GPG funziona:
ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
${remote_sock}
sia mostrato nell'output dettagliato di sshls -l ${remote_sock}
gpg --list-secret-keys
debug1
messaggi di ssh che mostrano il traffico inoltratoSe ciò non funziona (come non ha funzionato per me) puoi tracciare quale socket GPG sta accedendo:
strace -econnect gpg --list-secret-keys
Uscita campione:
connect(5, {sa_family=AF_UNIX, sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0
Nel mio caso il percorso a cui si accede corrispondeva perfettamente ${remote_sock}
, ma quel socket non è stato creato da sshd
quando ho effettuato l'accesso, nonostante sia stato aggiunto StreamLocalBindUnlink yes
al mio/etc/ssh/sshd_config
. Sono stato creato da systemd al momento del login.
(Nota che ero troppo codardo per riavviare sshd, dato che al momento non ho accesso fisico all'host. service reload sshd
Chiaramente non era sufficiente ...)
Testato su Ubuntu 16.04