Puedo usar el archivo de configuración ssh para habilitar el reenvío de claves ssh agregadas a ssh-agent. ¿Cómo puedo hacer lo mismo con las claves gpg?
Puedo usar el archivo de configuración ssh para habilitar el reenvío de claves ssh agregadas a ssh-agent. ¿Cómo puedo hacer lo mismo con las claves gpg?
Respuestas:
EDITAR: Esta respuesta es obsoleta ahora que se ha implementado el soporte adecuado en OpenSSH, vea la respuesta de Brian Minton.
SSH solo es capaz de reenviar conexiones TCP dentro del túnel.
Sin embargo, puede usar un programa como socat
retransmitir el socket de Unix a través de TCP, con algo así (necesitará socat tanto en el cliente como en los hosts del servidor):
# 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) &
Prueba si funciona gpg-connect-agent
. Asegúrese de que GPG_AGENT_INFO no esté definido en el host remoto, de modo que vuelva al $HOME/.gnupg/S.gpg-agent
socket.
¡Ahora con suerte todo lo que necesita es una forma de ejecutar todo esto automáticamente!
localhost
ahora.
gpg-connect-agent
: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC
. El control remoto socat
luego muere. El local socat
muere y pronuncia socat[24692] E connect(3, AF=1 "", 2): Invalid argument
. Esta página me lleva a creer que esto nunca funcionará, porque el agente no almacena la clave (solo la frase de contraseña). ¿Alguien ha confirmado que esto funciona?
El nuevo reenvío de socket de dominio Unix de OpenSSH puede hacer esto directamente a partir de la versión 6.7.
Deberías poder hacer algo como:
ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9
En las nuevas versiones de distribuciones GnuPG o Linux, las rutas de los sockets pueden cambiar. Estos se pueden encontrar a través de
$ gpgconf --list-dirs agent-extra-socket
y
$ gpgconf --list-dirs agent-socket
Luego agregue estas rutas a su configuración SSH:
Host remote
RemoteForward <remote socket> <local socket>
Solución rápida para copiar las claves públicas:
scp .gnupg/pubring.kbx remote:~/.gnupg/
En la máquina remota, active el agente GPG:
echo use-agent >> ~/.gnupg/gpg.conf
En la máquina remota, también modifique la configuración del servidor SSH y agregue este parámetro (/ etc / ssh / sshd_config):
StreamLocalBindUnlink yes
Reinicie el servidor SSH, vuelva a conectarse a la máquina remota, entonces debería funcionar.
systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
es necesario para evitar que systemd lance un socket que robe el agente gpg remoto. Según bugs.debian.org/850982, este es el comportamiento previsto.
Tuve que hacer lo mismo, y basé mi script en la solución de b0fh, con algunas pequeñas modificaciones: atrapa las salidas y elimina los procesos en segundo plano, y utiliza las opciones "fork" y "reuseaddr" para socat, lo que le ahorra loop (y hace que el fondo socat sea fácilmente eliminable).
Todo esto configura todos los reenvíos de una sola vez, por lo que probablemente se acerque a una configuración automatizada.
Tenga en cuenta que en el host remoto, necesitará:
GPG_AGENT_INFO
variable falsa . Prefiero el mío con ~/.gnupg/S.gpg-agent:1:1
: el primer 1 es un PID para el agente gpg (lo simulo como "init", que siempre se está ejecutando), el segundo es el número de versión del protocolo del agente. Esto debería coincidir con el que se ejecuta en su máquina 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'
Creo que también hay una solución que involucra solo una invocación de comando SSH (conexión desde el host remoto al local) usando -o LocalCommand
, pero no pude averiguar cómo matar eso convenientemente al salir.
De acuerdo con GnuPG Wiki , debe reenviar el socket remoto al socket S.gpg-agent.extra
local S.gpg-agent
. Además, debe habilitar StreamLocalBindUnlink
en el servidor.
Tenga en cuenta que también necesita la parte pública de su clave disponible en GnuPG remoto .
Use gpgconf --list-dir agent-socket
respectivamente gpgconf --list-dir agent-extra-socket
en el control remoto para obtener las rutas reales.
Configuración agregada en remoto /etc/sshd_config
:
StreamLocalBindUnlink yes
Importe su clave pública en el control remoto:
gpg --export <your-key> >/tmp/public
scp /tmp/public <remote-host>:/tmp/public
ssh <remote-host> gpg --import /tmp/public
Comando para conectarse a través de SSH con reenvío de agente gpg habilitado: (rutas para mi Debian)
ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
Como alternativa a la modificación /etc/ssh/sshd_config
con StreamLocalBindUnlink yes
, en su lugar puede impedir la creación de los archivos de socket que necesitan ser reemplazados:
systemctl --global mask --now \
gpg-agent.service \
gpg-agent.socket \
gpg-agent-ssh.socket \
gpg-agent-extra.socket \
gpg-agent-browser.socket
Tenga en cuenta que esto afecta a todos los usuarios en el host.
Bonificación: cómo probar el reenvío de agentes GPG está funcionando:
ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
${remote_sock}
se muestra en la salida detallada de sshls -l ${remote_sock}
gpg --list-secret-keys
debug1
mensajes de ssh que muestran el tráfico reenviadoSi eso no funciona (como no lo hizo para mí), puede rastrear a qué socket GPG está accediendo:
strace -econnect gpg --list-secret-keys
Salida de muestra:
connect(5, {sa_family=AF_UNIX, sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0
En mi caso, la ruta a la que se accedía coincidía perfectamente ${remote_sock}
, pero ese socket no fue creado sshd
cuando inicié sesión, a pesar de agregar StreamLocalBindUnlink yes
a mi /etc/ssh/sshd_config
. Fui creado por systemd al iniciar sesión.
(Tenga en cuenta que era demasiado cobarde para reiniciar sshd, ya que no tengo acceso físico al host en este momento. service reload sshd
Claramente no era suficiente ...)
Probado en Ubuntu 16.04