miércoles, 27 de mayo de 2009

Soporte remoto con VNC y uso de túneles SSH

En una de mis visitas a Otime en Segovia me enseñaron una variante de soporte remoto que no conocía y sencillamente me encantó. He usado VNC desde hace muchos años pero tiene un problema importante cuando quieres ofrecer soporte a clientes y es cómo acceder a ordenadores que están en una red local detrás de un router/firewall. La solución consistiría en cambiar la configuración del router para que redireccionara los puertos a las máquinas locales pero creo que estaréis conmigo cuando pienso que no es una solución factible.

Pues bien, en Otime me enseñaron el uso del VNC inverso. Lo conocía con SSH pero no caí en que fuera posible hacerlo con VNC. La idea es que en lugar de iniciar tú la conexión al ordenador del cliente sea el cliente el que inicie la conexión contigo y luego tomes el control de su ordenador. Esto es mucho más factible pues sólo es necesario modificar las reglas del firewall en un sitio, en tu oficina. Además tiene otro punto muy favorable y es que es gratis. Hay varias soluciones de helpdesk en el mercado pero de esta forma, aunque algo más compleja, te lo haces tú mismo.

Las formas de hacer este VNC inverso son distintas dependiendo del cliente que utilices. Yo voy a explicar el uso de Ultra VNC y su addon Single Click. Ultra VNC te ofrece un .zip a modo de distribución para que lo personalices con los logos, los mensajes en tu idioma,... y mediante su página web te generas un .exe ya configurado como el que se ve en la imagen siguiente.


Las instrucciones están detalladas en http://www.uvnc.com/addons/singleclick.html por lo que no merece la pena que las repita pero únicamente decir que es sencillísimo. Este Single Click representa al programa que tiene que ejecutar el cliente. En cuanto a Sinergics lo que tenemos es un script que arranca winvnc indicando que escuche en un determinado puerto (el mismo que se pone en la configuración del Single Click).
> vncviewer -listen 8888

Por lo tanto, a modo resumen:
- Llama el cliente indicando que tiene un problema y requieres controlar su ordenador.
- Arrancas el VNC en modo escucha.
- Le indicas que se descargue de la página web el ejecutable y que lo abra.
- Cuando lo ha abierto tendrás el control de su máquina.
- Justo antes de dejar de tener el control de su máquina le cierras el cliente de VNC por si las moscas.

Un esquema gráfico muy sencillo de cómo quedaría la cosa:



Hasta aquí todo bien pero... muchas veces me encuentro que estoy en la universidad, donde me conecto a través de una VPN y mi máquina no es accesible desde el exterior por políticas de seguridad. La única forma de ver acceder a máquina es desde otra máquina a la que sí que se tiene acceso desde fuera, pero únicamente vía SSH ¿Eingg? Pues sí, esto me ha pasado.

La solución a la que he llegado, por lo menos la única que se me ocurrió fue la siguiente... Tengo un servidor privado alojado en Internet con control total sobre él. Lo que decidí hacer fue crear un túnel SSH desde un puerto, por ejemplo 8989 de forma que cuando alguien se conecte a este puerto se redirija los datos a mi máquina pasando a través del ordenador de la universidad que está visible a través de SSH. La orden es algo así:
ssh -L IP_PUBLICA_DE_MI_SERVIDOR_PRIVADO:8989:IP_DE_MI_MAQUINA:PUERTO_ESCUCHA_VPN
usuariomaquinauniversidad@ipuniversidad

Como ni yo mismo entiendo este párrafo después de escribirlo voy a pegar otro diagrama para que quede algo más claro.



Lo que he hecho es configurar el SingleClick con la IP y puerto del servidor que tengo contratado y entonces cuando el cliente se conecta a dicho puerto el túnel se conecta con mi máquina local pasando a través del servidor de la universidad que es el que hace de túnel.


ACTUALIZACION
Indagando un poco más he encontrado otra solución más sencilla para el caso en el que no te encuentras en la oficina y que es en mi opinión más práctica . Consiste en utilizar un túnel SSH inverso.

El funcionamiento de un túnel SSH es más o menos el siguiente. Desde una máquina A quieres acceder a una máquina C, pero A no ve a C. Sin embargo A ve a una máquina B que esta a su vez ve a la máquina C. A haría un túnel utilizando a B de forma que mapea un puerto local de la máquina A con un puerto de la máquina C. Si A hace un telnet por ejemplo a dicho puerto local el túnel SSH configurado lo que hace es enviarlo a la máquina B que a su vez lo envía a la máquina C. B hace las veces de mensajero.

Pues bien, el túnel SSH inverso hace algo parecido. En el caso del túnel normal lo que haces es permitir a A que se conecte con C. En el túnel inverso lo que haces es preparar a A para que pueda recibir datos de C enviando dichos datos a través de B (que es pública). Con el ejemplo de la VPN quedará más claro. Me voy de viaje y estoy en las oficinas de un cliente. En este entorno no puedo tocar el router de la oficina y mi máquina no es visible desde fuera. Necesito conectarme con un cliente con el VPN inverso (luego el cliente tiene que iniciar la conexión conmigo). Lo que hago es crear un túnel inverso desde mi máquina al servidor privado que tengo contratado y que es público. Este túnel lo que hará es mapear un puerto de dicho servidor remoto de forma que cuando alguien se conecte a dicho puerto reenvíe los paquetes a mi máquina. Realmente que esta máquina me envíe datos no se puede hacer sin túnel porque mi máquina no es visible desde fuera pero al iniciar yo la conexión mediante el túnel inverso ya pasaría a ser visible.

La sintaxis del ssh inverso, que se ejecutaría desde mi máquina local, es la siguiente.
ssh -R IP_MAQUINA_PUBLICA:8989:localhost:8888 usuariomaquinapublica@IP_MAQUINA_PUBLICA

Lo que indica es que cuando alguien acceda al puerto 8989 de la máquina remota el túnel reenvíe dicho dato a mi puerto 8888 que es donde tendría escuchando el UltraVNC con el -listen 8888.

Otra cosa a tener en cuenta es que hay que modificar la configuración del sshd tal y como indica la página man. Por defecto la máquina remota sólo escucharía este puerto mediante la loopback interface.
By default, the listening socket on the server will be bound to
the loopback interface only. This may be overriden by specifying
a bind_address. An empty bind_address, or the address '*', indi-
cates that the remote socket should listen on all interfaces.
Specifying a remote bind_address will only succeed if the
server's GatewayPorts option is enabled (see sshd_config(5)).

Espero que os haya servido de ayuda este post.

No hay comentarios:

Publicar un comentario