Utilizar SSH ForwardAgent con el cliente de ssh es algo muy útil ya que permite hacer uso de nuestras llaves ssh para autenticarnos desde entornos remotos. Pudiendo así clonar repositorios con git desde otros servidores usando la cuenta local o simplemente copiar con scp / rsync desde y entre servidores externos con nuestras llaves. Estos son los pasos para configurarlo.
El objetivo de esta pequeña guía es mostrar como activar ForwardAgent y además ssh-agent, para que se solicite la password de las llaves ssh solo una vez. Con posibilidad de que se solicite también gráficamente una vez arrancado el escritorio del sistema operativo. De esta manera la navegación ssh en entornos de varios servidores se hace mucho más productiva, rápida y flexible.
Activar ForwardAgent: Configuramos en /etc/ssh/ssh_config “ForwardAgent yes” para todos los Hosts o bien los que nos interesen.
Host * ForwardAgent yes # ForwardAgent no
Las llaves ssh deben estar cifradas siempre con una passphrase (que no contraseña), utilizar ssh-agent nos permite dejar en memoria nuestras credenciales tras autenticarnos y no volver a requerirla para ninguna conexión ssh. Es algo independiente del ForwardAgent visto anteriormente, pero suelen ir de la mano debido a que se complementan.
NOTA: En GNU/linux no se suelen dejar las credenciales en memoria, se suelen usar tokens u otros mecanismos sofisticados que permiten descifrar la información pero no obtener la passphrase / llaves / contraseñas.
NOTA: Una passphrase o “frase de contraseña” es una secuencia de palabras u otro texto usada para controlar acceso a un sistema de computadoras. Una frase de contraseña es similar a una contraseña en cuanto a su uso, pero es, generalmente, más larga para agregar seguridad. Las frases de contraseña son usadas para controlar el acceso y la operación de programas y sistemas criptográficos. Estas frases de contraseña son particularmente aplicables a sistemas que las usan como llave de cifrado.(Leer)
ssh-agent suele venir de serie como demonio o directamente configurado para que esté disponible desde cualquier terminal del sistema. Todo depende de cada distribución. Si esto no es así, siempre se puede hacer manualmente de varias maneras.
Veamos tres maneras de ejecutar ssh-agent, directamente en terminal, con un servicio de usuario systemd y desde el arranque del escritorio.
Terminal. En terminal, solo tiene validez sobre la sesión de terminal en la que nos encontremos.
eval `ssh-agent` ssh-add
Systemd.
Fichero: ~/.config/systemd/user/ssh-agent.service
[Unit] Description=SSH key agent [Service] Type=simple Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK [Install] WantedBy=default.target
Agregar la siguiente linea al fichero ~/.pam_environment
SSH_AUTH_SOCK DEFAULT="${XDG_RUNTIME_DIR}/ssh-agent.socket
systemctl --user enable ssh-agent.service systemctl --user start ssh-agent
Una vez dentro del sistema valdría con ejecutar el comando ssh-add, solo una vez.
Ejecutar ssh-agent al inicio del escritorio.
También puede incluirse al inicio del escritorio, por ejemplo dentro de .xinitrc.
#!/bin/sh # # ~/.xinitrc # # Executed by startx (run your window manager from here) if [ -d /etc/X11/xinit/xinitrc.d ]; then for f in /etc/X11/xinit/xinitrc.d/*; do [ -x "$f" ] && . "$f" done unset f fi if [ -s ~/.Xmodmap ]; then xmodmap ~/.Xmodmap fi # exec gnome-session # exec startkde # exec startxfce4 # ...or the Window Manager of your choice exec ssh-agent startlxde
Una vez dentro del escritorio valdría con ejecutar el comando ssh-add, solo una vez en cada arranque del sistema. Con la opción “-l” se pueden ver las llaves exportadas.
Aplicación gráfica que solicita credenciales de SSH.
Instalar x11-ssh-askpass u otra variante como openssh-askpass. Con estas herramientas, cuando se ejecute algún comando ssh desasociado de una terminal, como por ejemplo con el típico atajo Alt+ F2, se nos solicitarán las credenciales por entorno gráfico. Pudiendo así lanzar un comando a un servidor mediante ssh sin necesidad de usar una terminal. Si se quiere probar en consola se puede usar por ejemplo este comando.
ssh-add </dev/null &>/dev/null &
Cuando se tienen varias llaves, puede hacerse un script y colocarlo para que inicie en el arranque del escritorio o gestor de ventanas, algo similar a esto.
#!/bin/bash ssh-add $HOME/.ssh/id_rsa sleep 2 ssh-add $HOME/.ssh_trabajo/id_rsa
De esta manera cuando arranque el equipo se nos solicitarán la/s passphrase de cifrado de nuestras llaves ssh.
En vez de optar por utilizar llaves privadas sin passphrase para tareas programadas que utilizan, se puede configurar el demonio cron para que utilice ssh-agent. De esta manera se pueden tener las llaves de una manera segura.
La variable SSH_AUTH_SOCK contiene la ruta al socket que utiliza ssh-agent para comunicarse con otros procesos, como scp o ssh. Si se tiene ssh-agent activo se puede obtener el valor de la variable y obtener la ruta al socket en /tmp.
env | grep SSH SSH_AUTH_SOCK=/tmp/ssh-0EwY9zRoB252/agent.389 SSH_AGENT_PID=397
Esta variable no está disponible para cron ni para ningún otro proceso que no sea iniciado por nosotros directamente. Sabiendo eso cualquier tarea programada que use ssh, scp, sftp, etc necesitará introducir la passphrase y por lo tanto no podrá realizarse.
Una forma de solucionar esto es introducir la variable en las tareas cron cuando usamos ssh-agent. Para eso podemos valernos de sed e introducir en la primera linea del cron del usuario la variable. Luego valdría con ejecutar ese comando una vez introducidas las credenciales con sshd-add, ya sea en terminal o gráficamente.
En esta ruta se encuentra la configuración del cron del usuario: /var/spool/cron/USUARIO,
Agregar siempre en la primera fila del fichero cron del usuario la variable SSH_AUTH_SOCK. Todas las tareas que cron inicie tendrán la variable disponible y harán uso del socket si lo requieren para no solicitar la passphrase.
sed "1cSSH_AUTH_SOCK=$SSH_AUTH_SOCK" /var/spool/cron/USUARIO > /tmp/test && cat /tmp/test > /var/spool/cron/USUARIO
Así quedaría el script comentado anteriormente para arrancar al inicio del sistema ssh-agent.
#!/bin/bash ssh-add $HOME/.ssh/id_rsa && sed "1cSSH_AUTH_SOCK=$SSH_AUTH_SOCK" /var/spool/cron/USUARIO > /tmp/test && cat /tmp/test > /var/spool/cron/USUARIO sleep 2 ssh-add $HOME/.ssh_trabajo/id_rsa
Apunte de seguridad al usar ForwardAgent de SSH.
Si se comparten usuarios en entornos remotos con terceras personas usando SSH Forwarding hay que tener en cuenta lo siguiente. Cualquier otra persona con acceso a dicho usuario en el servidor puede buscar el fichero socket en /tmp y exportar la variable “SSH_AUTH_SOCK”. Esto significa que tiene los mismos privilegios que la llave privada usada en el origen para crear dicho socket. Veamos un ejemplo.
El administrador “A” tiene acceso a root en todo el datancenter. Necesita conectar a un servidor de X equipo de programación para mirar alguna cosa, usando un usuario no privilegiado como “usuario1”. Los programadores del equipo también tienen acceso a ese servidor mediante el mismo login “usuario1”. Cuando el administrador conecta a dicho servidor con el Forwarding activo en cliente se genera el socket, cualquiera de los programadores puede exportar la variable “SSH_AUTH_SOCK” y conectar con privilegios de root a todo el datacenter mientras el socket esté activo.
ForwardAgent de SSH en comandos sudo/su
Como ya sabemos, de usar ForwardAgent SSH con un usuario del sistema, al cambiar a otro usuario no privilegiado por medido de comandos “sudo” o “su”, no se tendrán permisos de lectura sobre el socket y este no podrá usarse desde el nuevo usuario. En el uso de estos comandos es importante establecer el traspaso de variables de manera explícita. En el caso de sudo por defecto no se exportan variables de entorno y se debe especificar en la linea de comandos o bien en el fichero “/etc/sudoers” para que las variables sean exportables. Se podría incluso configurar qué variables se quieren exportar.
Fichero /etc/sudoers
# Esta configuración exporta la variable para todos los usuarios.
Defaults env_keep+=SSH_AUTH_SOCK
Linea de comandos.
su # Si no especifica "-", las variables son exportadas sudo -sE # Exporta las variables de entorno y de usarse root (al no ser que se especifique "-u usuario"), este podrá usar el socket indicado en la variable SSH_AUTH_SOCK. su - # No se exportan las variables, aunque al ser root, siempre puede buscar el socket en /tmp y exportar la variable. sudo # No exporta las variables por lo que no podrá usarse el socket para utilizar ForwardAgent.