miércoles, 23 de marzo de 2011

Túneles con SSH

Qué tal?

Quiero comentar sobre una de las herramientas más poderosas que me he encontrado en mis años de administración de sistemas GNU/Linux. Los túneles SSH.

SSH por sí misma es una excelente herramienta (seguridad, ligereza) para poder administrar equipos de forma remota. Virtualmente no hay equipo *NIX que no tenga un servicio de SSH instalado para administrarlo. Pero adicionalmente SSH tiene una serie de facilidades que le dan una flexibilidad tremenda para resolver otros tipos de problemas no necesariamente relativos a administración de equipos per se. Una de esas facilidades son los túneles.

Imaginemos la situación en la cual tenemos que acceder a un puerto de un equipo, para los efectos de un ejemplo digamos que es VNC, que está en una red remota y no hay acceso directo hacia el puerto porque hay un firewall que está filtrando el acceso. Sin embargo tenemos acceso (en la misma red del equipo objetivo de nuestro experimento) a un servidor con un servicio de SSH que si tiene acceso a dicho puerto del equipo que nos quita el sueño. En ese caso, el problema está resuelto. Primero explicaré lo que haremos para luego explicar la lógica de la solución.

Creamos la sesión de ssh agregando un túnel local (hay 3 tipos de túneles SSH, básicamente) que abra un puerto en nuestro equipo indicándole al servidor SSH intermedio que conecte con el servidor destino al puerto de VNC:

ssh -nNT -L 5900:servidorvnc:5900 usuario@servidorssh

Ahora vienen las explicaciones:

-nNT
lo utilizo para no crear una sesión de terminal sino solamente el tunel que necesito.

-L 5900:servidorvnc:5900 indica que es un túnel local (es decir, abre el puerto donde se van a esperar conexiones en el equipo local). La especificación del túnel tiene 2 partes, la primera (5900) es el puerto donde se van a esperar las conexiones en el lado que escucha (como es un túnel local, eso implica en nuestro equipo). La siguiente parte (servidorvpn:5900) indica hacia donde se van a pasar las conexiones del lado del servidor ssh (en este caso que es un túnel local) cuando un cliente se conecte en nuestro puerto 5900. Es importante hacer notar que la resolución del nombre/ip se dará del lado del servidor ssh por ser éste un túnel local.

A continuación la información para autenticar contra el servidor ssh.

Ahora cómo nos conectamos al servicio de VNC del equipo remoto que nos interesa? Utilizamos un cliente VNC para conectarnos a localhost. Nuestro cliente ssh es el encargado de abrir el puerto 5900 en el equipo local. Cuando un cliente se conecte a dicho puerto, el tráfico será enviado por el túnel SSH (lo cual implica que va encriptado) y será enviado a su vez desde el servidor SSH hacia el equipo servidorvnc y hacia su puerto 5900. Y con eso habremos logrado conectarnos con el equipo que nos interesa.

Importante: Los números de los puertos indicados en el túnel no necesariamente tienen que ser iguales. Solo recuerden que un puerto se abre bien en el cliente (si es local) o en el servidor SSH (remoto) y que en el otro lado de la conexión SSH se hará la resolución de nombre/ip.

Como dije en un principio, hay 3 tipos de túneles:
- Locales (como el que acabamos de ver en nuestro ejemplo)
- Remotos (puerto que se abre para escuchar conexiones en el servidor SSH y conexión que se establece a un equipo desde nuestro equipo por el cliente SSH)
- Dinámicos Este tipo de túnel abre un puerto en nuestro equipo que funciona como un proxy socks. Este tipo de proxies puede ser utilizado, entre otras, para poder navegar con un browser evitando filtrados de un firewall. El tráfico estaría saliendo desde el servidor SSH al que nos conectamos.

Para mayor información, mirar el man page de ssh.

Espero que haya sido instructiva la explicación y que disfruten haciendo túneles a medida de sus necesidades.