Supongamos que tienes la siguiente situación:
– Un ordenador (cliente) con acceso a internet, pero situado trás un router ó firewall que impide el acceso desde el exterior a dicho ordenador. Podría ser el ordenador de tu oficina, de un centro de trabajo ó una biblioteca. Desde este ordenador cliente puedes conectar via SSH con el ordenador de tu casa (servidor) pero no a la inversa.

¿Como acceder desde tu casa (servidor) al ordenador de tu oficina (cliente) para consultar los documentos que tienes allí guardados? La tuneladora de SSH es tu amiga.
Básicamente un tunel ssh lo que hace es enlazar un puerto en el ordenador servidor (tu casa) con el puerto a través del cual sale el ordenador cliente (trabajo), de la siguiente manera.ssh -o TCPKeepAlive=yes -R 6666:localhost:22 usuario-servidor@servidor
Esto abriría un tunel entre el puerto 6666 de tu casa y el puerto SSH (22) del cliente. Ahora para acceder de forma remota al ordenador cliente desde el servidor de tu casa bastaría con ssh usuario-cliente@localhost -p 6666
Esto funcionará hasta que el ordenador cliente se reinicie ó se corte la comunicación ssh con el servidor. Para restaurar el acceso desde el servidor al cliente es necesario volver a repetir el proceso para generar de nuevo el tunel de comunicación ó bien crear un script que se encargue de hacerlo al iniciarse la maquina cliente ó que desde crontab mantenga la conexión levantada.
Para hacer esto, previamente tenemos que haber configurado ssh para permitir que cliente se conecte al servidor sin solicitar contraseña mediante el uso de un archivo de clave.

Autentificación en SSH sin contraseña

Para que un cliente se conecte al servidor ssh sin necesidad de contraseña, el cliente debe generar un archivo con una clave que lo identifica y este archivo debe ser copiado al servidor.
En el ordenador cliente ejecutassh-keygen
#>Generating public/private rsa key pair.
#>Enter file in which to save the key (~/.ssh/id_rsa): mi-archivo-clave
#>Enter passphrase (empty for no passphrase): [vacio, pulsa ENTER]
#>Enter same passphrase again: [vacio, pulsa ENTER]
#>Your identification has been saved in mi-archivo-clave.
#>Your public key has been saved in mi-archivo-clave.pub.

Ahora copiamos el archivo .pub al servidor a través de ssh conscp ~/.ssh/mi-archivo-clave.pub usuario-servidor@servidor:~/.ssh/

Nos movemos al servidor y lo insertamos en el archivo de claves autorizadascd ~/.ssh
cat mi-archivo-clave.pub >> authorized_keys

Con esto hecho, el usuario-cliente ya no necesita contraseña para autentificarse en servidor como usuario-servidor, y bastaría hacer ssh usuario-servidor@servidor
servidor#>Bienvenido

Konqueror+fish y reverse ssh

Creación automática de tunel

Una vez podemos conectar el cliente con el servidor sin necesidad de contraseña la creación del tunel al iniciarse el sistema o a intervalos de tiempo mediante crontab no tiene más misterio que repetir la orden indicada arribassh -o TCPKeepAlive=yes -R 6666:localhost:22 usuario-servidor@servidor

Ahora bien, dando una vuelta por internet encontré ssh-reverse-tunnel. Básicamente es lo mismo: un script que se encarga de abrir el tunel y mantenerlo abierto, con algunas comodidades añadidas:

  • El script se ejecuta a intervalos (crontab) en el lado del cliente y el servidor, y restaura el tunel de forma automática cuando este desaparece.
  • Las opciones de la conexión se archivan en una fichero CONF identico para ambas maquinas (en cada lado, cliente-servidor, el script utiliza los parámetros que necesita de dicho fichero)
  • El script desde el lado cliente mira en cada conexión si existe algún “archivo de ordenes” en el servidor. De esta manera desde el servidor podemos facilmente detener la creación del tunel, restaurarlo si falla, crearlo si no existe ó incluso incorporar ordenes que serán ejecutadas en el cliente mediante bash.
  • ssh-reverse-tunnel permite crear conexiones VPN (red privada virtual) de manera que podamos acceder a la máquina cliente desde el servidor simplemente abriendo konqueror en (p.ejm) 192.168.1.20
    (teniendo instalado el protocolo fish:// creo que esta opción es redundante, basta con abrir Konqueror y abrir fish://usuario@localhost:6666/home/usuario/Desktop para acceder al escritorio remoto de forma gráfica)

Pasos para crear el tunel usando ssh-reverse-tunel

  • Descarga e instala en ambas máquinas el script (descargar, descomprimir y sudo make install)
  • Edita /etc/ssh-reverse-tunnel.conf en ambas máquinas y escribe los parámetros de la conexión (están bastante bien explicados en el propio archivo CONF), básicamente: SERVER_USER, SERVER_HOST, CLIENT_USER, CLIENT_HOST
  • En la máquina cliente ejecuta ssh-reverse-tunnel client para generar el tunel
  • Añade esta misma orden en crontab (el autor recomienda hacerlo cada minuto, me pareció excesivo y lo he puesto en 5 min) como:
    */5 * * * * /usr/bin/ssh-reverse-tunnel client

Si lo deseas en el lado del servidor puedes también ejecutar ssh-reverse-tunnel para que comprueba la creación del tunel y lo regenere en caso de “caerse”. Puedes añadir a crontab (como root)*/5 * * * * /usr/bin/ssh-reverse-tunnel server
Pero esto último no es necesario. Cuando se caiga puedes restauralas haciendoecho "" > /home/user-cliente/.ssh-reverse-tunnel.restart.CLIENT_HOST donde CLIENT_HOST es el valor que tuviera CLIENT_HOST en el archivo de configuración.
Cuando el cliente se vuelva a conectar “verá” la orden, restaurará el tunel y borrará esta orden.
Cuando quieras cerrar el tunel basta con echo "" > /home/user-client/.ssh-reverse-tunnel.dead.CLIENT_HOST
Si activaste la opción REMOTE_COMMANDS en el archivo de configuración, puedes escanear la red a la que está conectada el cliente y que te envie los resultados con echo "nmap -sP 10.0.0.1-20 > scan.txt ; scp scan.txt usuario-servidor@servidor:~/Desktop/" > /home/user-client/.ssh-reverse-tunnel.command.CLIENT_HOST

Facil, ¿no? :)