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 socatretransmitir 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-agentsocket.
¡Ahora con suerte todo lo que necesita es una forma de ejecutar todo esto automáticamente!
localhostahora.
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 socatluego muere. El local socatmuere 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.socketes 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_INFOvariable 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.extralocal S.gpg-agent. Además, debe habilitar StreamLocalBindUnlinken 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-socketrespectivamente gpgconf --list-dir agent-extra-socketen 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_configcon 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
debug1mensajes 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 sshdcuando inicié sesión, a pesar de agregar StreamLocalBindUnlink yesa 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 sshdClaramente no era suficiente ...)
Probado en Ubuntu 16.04