SSH + VNC = acceso seguro a equipos remotos
El otro día al tratar de acceder a un equipo remoto por VNC me encontré con esta pantalla:
Ya me había pasado antes y… ¡no recordaba cómo había resuelto este pequeño problema!
Por eso publico este post, para un futuro en el que le tenga que echar mano o por si puede ser de tu interés.
Tengo que acceder a un equipo que está en una red local detrás de un router de vodafone al que se le ha abierto un puerto público y mapeado hacia la ip del equipo local y un puerto local, para poder acceder mediante ssh.
Pasos a seguir:
-
Se crea un tunel ssh para preparar el servidor de escritorio remoto. (Usando terminal o programa windows/android tipo putty)
ssh usuario@zzz.suroot.com -p 2200
Nos pide la contraseña del usuario «usuario» y ya tenemos acceso por terminal.
Con esto accedemos a una ip (en este caso dinámica que tiene un servicio gratuito de ddns) mediante el usuario «usuario» y un puerto, el 2200. Previamente se ha instalado en la máquina a acceder el servidor ssh, se ha abierto y redireccionado el puerto del router el 2200 al 22 (ssh) del ordenador, mediante un mapeo/redireccionamiento hacia la ip asignada al ordenador. El puerto 2200 que se abre podría ser cualquier otro de los no asignados a servicios utilizados. No se utiliza el 22 hacia el «exterior» para evitar los continuos ataques a este puerto.
zzz.suroot.com se puede sustituir por la propia ip dinámica asignada en ese momento y que debemos conocer o nos han de facilitar. Si la ip es estática o si se cuenta además con dominio propio y capacidad para gestionarlo, sin duda todo será más evidente.
2. Se instala un servidor VNC (escritorio remoto).
Una vez tenemos acceso por terminal, toca preparar el ordenador de destino, instalando un servidor de vnc.
sudo apt-get update
sudo apt install tightvncserver
Para ello el usuario tiene que tener permisos para utilizar el comando sudo que le eleva los privilegios y permisos
3. Asignamos un gestor (entorno) de escritorio (y de ventanas) a la sesión remota que se iniciará cuando creemos una sesión de acceso por VNC.
Realmente el servidor de VNC conectará al servidor X del sistema GNU/Linux remoto (el servidor gráfico). Si conectáramos nuestro cliente VNC al servidor en este momento, veríamos la pantalla gráfica de las X (imagen de cabecera del artículo) sin más opciones de gestión o elementos. NOTA: Aclaración sobre servidor gráfico, entorno gráfico y gestor de ventanas.
Pues bien, para cargar o asociar un gestor de ventanas a la sesión remota, primero miramos qué gestor o gestores están instalados en el sistema mediante este comando:
env | grep -i "session"
Podría ser que según qué sabor de GNU/Linux estemos utilizando este comando no diera el resultado previsto. Googleando encontramos alternativas, por ejemplo aquí dan varias.
Al redactar estas líneas estoy probando en un Debian con Gnome en el que el comando anterior no da el resultado deseado. Pruebo otro:
ls /usr/bin/*session*
Con el resultado (entre otros):
/usr/bin/dbus-run-session
/usr/bin/gnome-session
/usr/bin/mate-session
También pudiera ocurrir que nos interesara instalar en el ordenador remoto otros gestor de escritorios diferentes. Para simplificar se utilizará el gestor por defecto que además lleva asociado por defento un gestor de ventanas.
Ahora viene el meollo del asunto: Editar el siguiente archivo.
nano ~/.vnc/xstartup
xstartup es un archivo situado en un directorio oculto (por eso lleva un punto inicial) llamado .vnc que se encuentra en la home del usuario (por eso se utiliza la ruta ~ que es lo mismo que /home/usuario.
Sería aconsejable hacer una copia del fichero antes de su edición. En ocasiones como en esta versión de Debian el fichero está vacío.
Debería quedarnos algo parecido a lo siguiente (ojo con esto que en cada distro puede variar y de hecho varía):
/#!/bin/bash
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec /etc/X11/xinit/xinitrc
gnome-session &
4. Arrancamos el servidor de VNC.
vncserver :1 -geometry 1920x1080
Se puede hacer con más o menos parámetros y de manera manual o automática en el arranque. La forma más sencilla es manual y con unos parámetros mínimos:
:1 –> indica que el puerto al que se debe conectar es el 5901 (si abrimos con :2 será el 5902. Se puede tener una o varias sesiones abiertas de esta manera)
-geometry –> es importante para hacer coincidir la resolución del escritorio remoto que abramos con la resolución de nuestro equipò.
Si por alguna razón quermos eliminar la sesión (para terminarla desde el equipo remoto, para modificar alguna línea del archivo xstartup y volver a recargar la sesión) haremos lo siguiente
vncserver -kill :1
siendo :1 la sesión que habíamos abierto.
NOTA: La primera vez que arrancamos una sesión del servidor vnc nos pedirá una contraseña de acceso y si éste será sólo para visualizar el escritorio remoto o para interactuar con él.
Para pasar al siguiente paso debemos tener al menos una sesión corriendo y tener claro el puerto que se ha abierto. Una consideración: el puerto abierto en el equipo para el acceso «gráfico» remoto es el 5901, típico de una sesión de VNC. Pero nuestro cortafuegos/router sólo tiene abierto el puerto 2200 (redireccionado al 22 local del equipo) necesario para hacer un túnel ssh. ¿Cómo lo hacemos entonces?
5. Creación de un túnel ssh con redirección de puertos para «canalizar» de forma segura y privada nuestro tráfico de datos entre el cliente VNC de nuestro equipo y el servidor VNC del remoto.
ssh -L 5901:127.0.0.1:5901 usuario@zzz.suroot.com -p 2200
Previamente pudimos cerrar el túnel ssh que nos permitió configurar vía terminal todos los pasos descritos con anterioridad o no. El caso es que también podríamos haber utilizado este comando en el paso 1 y crear un túnel con la redirección de puertos, ya que sin más parámetros también crea la sesión remota con terminal que necesitamos en los puntos anteriores.
Lo que tenemos claro a estas alturas es que la segunda parte del comando nos conecta con el usuario «usuario» a una ip/dominio/ddns que nos da acceso al ordenador remoto.
Y la primera parte es fácil ya que el puerto a la izquierda de la ip 127.0.0.1 (localhost) es el puerto de mi ordenador local que quiero redireccionar A TRAVÉS DEL TÚNEL SSH hacia el puerto que está escrito a la derecha que corresponde con el ordenador remoto. Es decir, conecto el 5901 local con el 5901 remoto. Es evidente que si he creado en remoto una sesión VNC por el puerto 5901, el puerto de la derecha debe ser éste, pudiendo ser el puerto local de libre elección. Por ejemplo: 5555:127.0.0.1:5901
6. Conexión mediante un cliente VNC al ordenador remoto:
Una vez creado el túnel con redirección de puertos tan sólo nos queda utilizar un cliente VNC en nuestro equipo, por ejemplo vinagre.
Introduciremos en la casilla de dirección del server VNC o bien 127.0.0.1:5901 o bien localhost:5901.
Tan sencillo como que esta petición entrará por el túnel en el puerto 5901 y alcanzará el 5901 del servidor vnc en el ordenador remoto.
Aviso: Hay que dar un tiempo para que sobre el servidor X se cargue el gestor de escritorio, dependiendo de la calidad y velocidad de la conexión.
NOTA: El cliente VNC puede decirnos que estamos ante una conexión insegura al no estar cifrada. Es correcto, el cliente no cifra absolutamente nada y nos da información correcta. Lo que no sabe el cliente es que hacemos pasar todos los datos a través del túnel ENCRIPTADO creado por el mágico ssh.
AÑADIDO: Caso de Ubuntu 17.04 utilizando Xfce como gestor de escritorio. Archivo ~/.vnc/xtartup
#!/bin/sh
export XKL_XMODMAP_DISABLE=1
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
xfce4-panel &
xfsettingsd &
xfwm4 &
pcmanfm &
xfce4-terminal &
xfdesktop &
O sencillamente con startxfce4 sin lanzar individualmente cada componente.
#!/bin/sh
export XKL_XMODMAP_DISABLE=1
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &