Je peux utiliser le fichier de configuration ssh pour permettre le transfert des clés ssh ajoutées à ssh-agent. Comment puis-je faire de même avec les clés gpg?
Je peux utiliser le fichier de configuration ssh pour permettre le transfert des clés ssh ajoutées à ssh-agent. Comment puis-je faire de même avec les clés gpg?
Réponses:
EDIT: Cette réponse est obsolète maintenant qu'un support approprié a été implémenté dans OpenSSH, voir la réponse de Brian Minton.
SSH est uniquement capable de transmettre des connexions TCP dans le tunnel.
Vous pouvez, cependant, utiliser un programme comme socat
pour relayer la socket unix sur TCP, avec quelque chose comme ça (vous aurez besoin de socat à la fois sur le client et les hôtes du serveur):
# 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) &
Testez si cela fonctionne avec gpg-connect-agent
. Assurez-vous que GPG_AGENT_INFO n'est pas défini sur l'hôte distant, afin qu'il retombe dans le $HOME/.gnupg/S.gpg-agent
socket.
Avec un peu de chance, tout ce dont vous avez besoin est un moyen d'exécuter tout cela automatiquement!
localhost
maintenant.
gpg-connect-agent
: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC
. La télécommande socat
meurt alors. Le local socat
meurt et prononce socat[24692] E connect(3, AF=1 "", 2): Invalid argument
. Cette page me fait croire que cela ne fonctionnera jamais, car l'agent ne stocke pas la clé (juste la phrase secrète). Est-ce que cela a été confirmé par quelqu'un?
Le nouveau transfert de socket de domaine Unix d'OpenSSH peut le faire directement à partir de la version 6.7.
Vous devriez pouvoir faire quelque chose comme:
ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9
Dans les nouvelles versions des distributions GnuPG ou Linux, les chemins des sockets peuvent changer. Ceux-ci peuvent être trouvés via
$ gpgconf --list-dirs agent-extra-socket
et
$ gpgconf --list-dirs agent-socket
Ajoutez ensuite ces chemins à votre configuration SSH:
Host remote
RemoteForward <remote socket> <local socket>
Solution rapide pour copier les clés publiques:
scp .gnupg/pubring.kbx remote:~/.gnupg/
Sur la machine distante, activez l'agent GPG:
echo use-agent >> ~/.gnupg/gpg.conf
Sur la machine distante, modifiez également la configuration du serveur SSH et ajoutez ce paramètre (/ etc / ssh / sshd_config):
StreamLocalBindUnlink yes
Redémarrez le serveur SSH, reconnectez-vous à la machine distante - alors cela devrait fonctionner.
systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
soit nécessaire pour empêcher systemd de lancer un socket volant l'agent gpg distant. Selon bugs.debian.org/850982, c'est le comportement prévu.
J'ai dû faire de même, et j'ai basé mon script sur la solution de b0fh, avec quelques petites modifications: il intercepte les sorties et tue les processus d'arrière-plan, et il utilise les options "fork" et "reuseaddr" pour socat, ce qui vous évite boucle (et rend le socat d'arrière-plan proprement tuable).
Le tout se configure en une seule fois, donc cela se rapproche probablement d'une configuration automatisée.
Notez que sur l'hôte distant, vous aurez besoin de:
GPG_AGENT_INFO
variable. Je préremplit le mien avec ~/.gnupg/S.gpg-agent:1:1
- le premier est un PID pour l'agent gpg (je le simule comme "init", qui est toujours en cours d'exécution), le second est le numéro de version du protocole de l'agent. Cela devrait correspondre à celui qui s'exécute sur votre ordinateur local.
#!/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'
Je crois qu'il existe également une solution qui implique une seule invocation de commande SSH (se reconnecter de l'hôte distant à l'hôte local) -o LocalCommand
, mais je n'arrivais pas à comprendre comment le supprimer facilement à la sortie.
Selon GnuPG Wiki , vous devez transmettre le socket distant au socket S.gpg-agent.extra
local S.gpg-agent
. De plus, vous devez activer StreamLocalBindUnlink
sur le serveur.
Gardez à l'esprit que vous avez également besoin de la partie publique de votre clé disponible sur GnuPG distant .
Utilisez gpgconf --list-dir agent-socket
respectivement gpgconf --list-dir agent-extra-socket
sur la télécommande pour obtenir les chemins réels.
Configuration ajoutée sur la télécommande /etc/sshd_config
:
StreamLocalBindUnlink yes
Importez votre clé publique à distance:
gpg --export <your-key> >/tmp/public
scp /tmp/public <remote-host>:/tmp/public
ssh <remote-host> gpg --import /tmp/public
Commande pour se connecter via SSH avec le transfert d'agent gpg activé: (chemins pour mon Debian)
ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
Comme alternative à la modification /etc/ssh/sshd_config
avec StreamLocalBindUnlink yes
, vous pouvez empêcher la création des fichiers socket qui doivent être remplacés:
systemctl --global mask --now \
gpg-agent.service \
gpg-agent.socket \
gpg-agent-ssh.socket \
gpg-agent-extra.socket \
gpg-agent-browser.socket
Notez que cela affecte tous les utilisateurs de l'hôte.
Bonus: Comment tester le transfert d'agent GPG fonctionne:
ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
${remote_sock}
est indiqué dans la sortie détaillée de sshls -l ${remote_sock}
gpg --list-secret-keys
debug1
messages de ssh montrant le trafic transféréSi cela ne fonctionne pas (comme cela ne l'a pas été pour moi), vous pouvez tracer le socket auquel GPG accède:
strace -econnect gpg --list-secret-keys
Exemple de sortie:
connect(5, {sa_family=AF_UNIX, sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0
Dans mon cas, le chemin d'accès était parfaitement adapté ${remote_sock}
, mais ce socket n'a pas été créé sshd
lorsque je me suis connecté, malgré l'ajout StreamLocalBindUnlink yes
à mon /etc/ssh/sshd_config
. J'ai été créé par systemd lors de la connexion.
(Notez que j'étais trop lâche pour redémarrer sshd, car je n'ai pas d'accès physique à l'hôte pour le moment. service reload sshd
N'était clairement pas suffisant ...)
Testé sur Ubuntu 16.04