Túneles ssh

Hace algunos meses escribí un artículo sobre ssh a fondo, en el que hablaba entre otras cosas sobre los túneles ssh. La cuestión es que por las circunstancias, esto de los túneles, no lo he utilizado de forma habitual, al menos hasta ahora. Y digo al menos hasta ahora, porque durante las próximas semanas, haré un uso intensivo de ellos, y como no podía ser de otra forma, me he hecho un sencillo script que me permita levantar varios túneles, y un segundo script que me permite cerrarlos, cuando he dejado de utilizarlos

Así, en este artículo, voy a tratar mas a fondo el tema de los túneles ssh y en particular, estos dos scripts para realizar tus propios túneles, de forma cómodo y sencilla.

Túneles ssh

Túneles ssh

¿Que te parecería que en lugar de utilizar un puerto de tu máquina utilizaras el puerto de otra máquina? ¿Para que quiero esto?¿Te gustaría acceder a un servicio remoto como su fuera local?

¿No se te ocurre ninguna ningún caso? Pongamos que tienes una Raspberry en tu red local, donde tienes levantados varios servicios como puede ser un WordPress por el puerto 80 (con su correspondiente Apache o Nginx) o incluso un Grafana, en este caso por el puerto 3000, como es habitual.

Ahora tienes dos opciones, o bien, acceder a estos servicios utilizando la IP de la Rasbperry y su puerto, o bien, otra solución, sería hacer un túnel ssh, de forma que le digas a tu equipo cuando una aplicación se conecte al puerto 3000 de portátil, realmente se estará conectando al puerto 3000 de la Rasbperry. Sinceramente, esto es brutal.

Se trata de una sencilla y simple manera de solucionar el problema de las reglas de firewall, o simplemente, de tener todo lo que necesitas como si estuviera en tu ordenador.

Un servicio remoto como si fuera local

De esta manera convertir un servicio remoto en un servicio local, es tan sencillo, como hacer unir tu puerto local con el puerto remoto. Para ello, tan solo tienes que ejecutar la siguiente instrucción,

ssh lorenzo@192.168.1.48 -fNL 3001:localhost:3000

En este caso, he conectado el 3001 local, con el 3000 remoto. Mas que nada para que los dos tengamos claro cual es el remoto y cual es el local. Pero, ¿entiendes que los dos podrían ser el 3000? Está claro.

Una vez hecho esto, cuando desde mi Firefox, acceda a localhost:3001 realmente estaré accediendo a 192.168.1.48:3000, tan sencillo, fácil y útil, como lo que te acabo de mostrar.

Entendiendo la operativa

Llegados a este punto, seguro que te estarás preguntando, mas que nada porque no quieres buscarlo en la ayuda del comando ssh, que son las opciones que he puesto. ¿Que es ese -fNL? Vamos por partes,

  • f es para que ssh vaya a segundo plano nada mas ejecutarse la instrucción.
  • N indica que no se ejecuta ningún comando remoto, simplemente hace lo que queremos hacer, conectar un puerto local con uno remoto,
  • L es el encargado de especificar la conexión.

Esto también lo puedes escribir de la siguiente forma,

ssh lorenzo@192.168.1.48 -f -N -L 3001:localhost:3000

O también como

ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000

Pero en la última posición recuerda poner la L que es la que lleva el argumento.

Saliendo del túnel

Ahora ya tienes claro como levantar ese túnel, pero ¿que hacer cuando no lo necesites?¿Y si quieres cerrar el tunel? Pues simplemente tienes que matar el proceso. Tan sencillo como eso, matas el proceso y se cerró el túnel.

¿Y como mato el proceso?

Lo primero es buscar el PID del proceso. Para esto, con un ps -ef | grep ssh, podrás ver todos los procesos ssh que tienes corriendo en tu equipo. Otra opción para hacer lo mismo, es utilizar el comando pgrep -fa ssh.

El problema de este comando de estos comandos, tal y como los he puesto, es que te muestra todos los procesos ssh que están corriendo en el momento. Por que como te puedes imaginar, una vez abres el primer túnel, esto es un no parar. Actualmente tengo 4 túneles ssh… y no solo esto. También puedes tener otras sesiones ssh abiertas, y ciertamente puede ser una locura.

La solución sería buscar exactamente el mismo comando que ejecutaste para abrir el tunel, es decir,

pgrep -fa ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000

Ejecutando esto te devolverá algo como lo siguiente,

158833 ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000

Esto ya es muy parecido a lo que ando buscando. Así, para matar el proceso y cerrar el túnel, solo tienes que ejecutar el siguiente comando,

kill $(pgrep -f ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000)

Los scripts

Llegados a este punto, todo es mas sencillo, tan solo tienes que hacer un script para levantar tus puertos y otro para detenerlos. Así, por ejemplo, para el caso de que quieras un solo túnel, podría quedar como te muestro a continuación,

#!/bin/bash
PID=$(pgrep -f "ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000")
if [ -z $PID ]
then
    ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000
fi
PID=$(pgrep -f "ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000")
if [ -z $PID ]
then
    echo "No se ha establecido el túnel"
else
    echo "El túnel está levantado y funcionando"
fi

Mientras que el script para detener el túnel podría ser algo como,

#!/bin/bash
PID=$(pgrep -f "ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000")
if [ ! -z $PID ]
then
    kill $PID
fi
PID=$(pgrep -f "ssh lorenzo@192.168.1.48 -NfL 3001:localhost:3000")
if [ -z $PID ]
then
    echo "Se ha cerrado el túnel"
else
    echo "El túnel sigue levantado"
fi

Algunas observaciones

No hace falta que te diga, que lo mejor, para esto de los túneles ssh, es utilizar clave público privada, en lugar de usuario y contraseña, porque de lo contrario tendrás que retocar ligeramente los scripts anteriores.

Por otro lado, esto es carne de diálogo, ya se un cuadro de diálogo para el terminal utilizando dialog para crear diálogos para el terminal, del tutorial de diálogos para scripts o cualquiera de las otras herramientas que te propongo en este tutorial.

Por último, también podría ser realmente interesante hacer una extensión para GNOME Shell o una aplicación, muy sencilla que te permitiera gestionar todos estas conexiones, de forma que fuera una operativa mucho más dinánica.


Más información,

Imagen de portada en Florian van Duyn en Unsplash

Deja una respuesta

Tu dirección de correo electrónico no será publicada.